ActivityManagerService.java revision 9f49df933f01a32d04bdf92d53c943065aa8ddf7
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.Manifest; 32import android.app.AppOpsManager; 33import android.app.IActivityContainer; 34import android.app.IActivityContainerCallback; 35import android.appwidget.AppWidgetManager; 36import android.graphics.Rect; 37import android.os.BatteryStats; 38import android.service.voice.IVoiceInteractionSession; 39import android.util.ArrayMap; 40 41import com.android.internal.R; 42import com.android.internal.annotations.GuardedBy; 43import com.android.internal.app.IAppOpsService; 44import com.android.internal.app.IVoiceInteractor; 45import com.android.internal.app.ProcessMap; 46import com.android.internal.app.ProcessStats; 47import com.android.internal.content.PackageMonitor; 48import com.android.internal.os.BackgroundThread; 49import com.android.internal.os.BatteryStatsImpl; 50import com.android.internal.os.ProcessCpuTracker; 51import com.android.internal.os.TransferPipe; 52import com.android.internal.os.Zygote; 53import com.android.internal.util.FastPrintWriter; 54import com.android.internal.util.FastXmlSerializer; 55import com.android.internal.util.MemInfoReader; 56import com.android.internal.util.Preconditions; 57import com.android.server.AppOpsService; 58import com.android.server.AttributeCache; 59import com.android.server.IntentResolver; 60import com.android.server.LocalServices; 61import com.android.server.ServiceThread; 62import com.android.server.SystemService; 63import com.android.server.SystemServiceManager; 64import com.android.server.Watchdog; 65import com.android.server.am.ActivityStack.ActivityState; 66import com.android.server.firewall.IntentFirewall; 67import com.android.server.pm.UserManagerService; 68import com.android.server.wm.AppTransition; 69import com.android.server.wm.WindowManagerService; 70import com.google.android.collect.Lists; 71import com.google.android.collect.Maps; 72 73import libcore.io.IoUtils; 74 75import org.xmlpull.v1.XmlPullParser; 76import org.xmlpull.v1.XmlPullParserException; 77import org.xmlpull.v1.XmlSerializer; 78 79import android.app.Activity; 80import android.app.ActivityManager; 81import android.app.ActivityManager.RunningTaskInfo; 82import android.app.ActivityManager.StackInfo; 83import android.app.ActivityManagerInternal; 84import android.app.ActivityManagerNative; 85import android.app.ActivityOptions; 86import android.app.ActivityThread; 87import android.app.AlertDialog; 88import android.app.AppGlobals; 89import android.app.ApplicationErrorReport; 90import android.app.Dialog; 91import android.app.IActivityController; 92import android.app.IApplicationThread; 93import android.app.IInstrumentationWatcher; 94import android.app.INotificationManager; 95import android.app.IProcessObserver; 96import android.app.IServiceConnection; 97import android.app.IStopUserCallback; 98import android.app.IUiAutomationConnection; 99import android.app.IUserSwitchObserver; 100import android.app.Instrumentation; 101import android.app.Notification; 102import android.app.NotificationManager; 103import android.app.PendingIntent; 104import android.app.backup.IBackupManager; 105import android.content.ActivityNotFoundException; 106import android.content.BroadcastReceiver; 107import android.content.ClipData; 108import android.content.ComponentCallbacks2; 109import android.content.ComponentName; 110import android.content.ContentProvider; 111import android.content.ContentResolver; 112import android.content.Context; 113import android.content.DialogInterface; 114import android.content.IContentProvider; 115import android.content.IIntentReceiver; 116import android.content.IIntentSender; 117import android.content.Intent; 118import android.content.IntentFilter; 119import android.content.IntentSender; 120import android.content.pm.ActivityInfo; 121import android.content.pm.ApplicationInfo; 122import android.content.pm.ConfigurationInfo; 123import android.content.pm.IPackageDataObserver; 124import android.content.pm.IPackageManager; 125import android.content.pm.InstrumentationInfo; 126import android.content.pm.PackageInfo; 127import android.content.pm.PackageManager; 128import android.content.pm.ParceledListSlice; 129import android.content.pm.UserInfo; 130import android.content.pm.PackageManager.NameNotFoundException; 131import android.content.pm.PathPermission; 132import android.content.pm.ProviderInfo; 133import android.content.pm.ResolveInfo; 134import android.content.pm.ServiceInfo; 135import android.content.res.CompatibilityInfo; 136import android.content.res.Configuration; 137import android.graphics.Bitmap; 138import android.net.Proxy; 139import android.net.ProxyProperties; 140import android.net.Uri; 141import android.os.Binder; 142import android.os.Build; 143import android.os.Bundle; 144import android.os.Debug; 145import android.os.DropBoxManager; 146import android.os.Environment; 147import android.os.FactoryTest; 148import android.os.FileObserver; 149import android.os.FileUtils; 150import android.os.Handler; 151import android.os.IBinder; 152import android.os.IPermissionController; 153import android.os.IRemoteCallback; 154import android.os.IUserManager; 155import android.os.Looper; 156import android.os.Message; 157import android.os.Parcel; 158import android.os.ParcelFileDescriptor; 159import android.os.Process; 160import android.os.RemoteCallbackList; 161import android.os.RemoteException; 162import android.os.SELinux; 163import android.os.ServiceManager; 164import android.os.StrictMode; 165import android.os.SystemClock; 166import android.os.SystemProperties; 167import android.os.UpdateLock; 168import android.os.UserHandle; 169import android.provider.Settings; 170import android.text.format.DateUtils; 171import android.text.format.Time; 172import android.util.AtomicFile; 173import android.util.EventLog; 174import android.util.Log; 175import android.util.Pair; 176import android.util.PrintWriterPrinter; 177import android.util.Slog; 178import android.util.SparseArray; 179import android.util.TimeUtils; 180import android.util.Xml; 181import android.view.Gravity; 182import android.view.LayoutInflater; 183import android.view.View; 184import android.view.WindowManager; 185 186import java.io.BufferedInputStream; 187import java.io.BufferedOutputStream; 188import java.io.DataInputStream; 189import java.io.DataOutputStream; 190import java.io.File; 191import java.io.FileDescriptor; 192import java.io.FileInputStream; 193import java.io.FileNotFoundException; 194import java.io.FileOutputStream; 195import java.io.IOException; 196import java.io.InputStreamReader; 197import java.io.PrintWriter; 198import java.io.StringWriter; 199import java.lang.ref.WeakReference; 200import java.util.ArrayList; 201import java.util.Arrays; 202import java.util.Collections; 203import java.util.Comparator; 204import java.util.HashMap; 205import java.util.HashSet; 206import java.util.Iterator; 207import java.util.List; 208import java.util.Locale; 209import java.util.Map; 210import java.util.Set; 211import java.util.concurrent.atomic.AtomicBoolean; 212import java.util.concurrent.atomic.AtomicLong; 213 214public final class ActivityManagerService extends ActivityManagerNative 215 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 216 private static final String USER_DATA_DIR = "/data/user/"; 217 static final String TAG = "ActivityManager"; 218 static final String TAG_MU = "ActivityManagerServiceMU"; 219 static final boolean DEBUG = false; 220 static final boolean localLOGV = DEBUG; 221 static final boolean DEBUG_BACKUP = localLOGV || false; 222 static final boolean DEBUG_BROADCAST = localLOGV || false; 223 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 224 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 225 static final boolean DEBUG_CLEANUP = localLOGV || false; 226 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 227 static final boolean DEBUG_FOCUS = false; 228 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 229 static final boolean DEBUG_MU = localLOGV || false; 230 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 231 static final boolean DEBUG_LRU = localLOGV || false; 232 static final boolean DEBUG_PAUSE = localLOGV || false; 233 static final boolean DEBUG_POWER = localLOGV || false; 234 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 235 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 236 static final boolean DEBUG_PROCESSES = localLOGV || false; 237 static final boolean DEBUG_PROVIDER = localLOGV || false; 238 static final boolean DEBUG_RESULTS = localLOGV || false; 239 static final boolean DEBUG_SERVICE = localLOGV || false; 240 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 241 static final boolean DEBUG_STACK = localLOGV || false; 242 static final boolean DEBUG_SWITCH = localLOGV || false; 243 static final boolean DEBUG_TASKS = localLOGV || false; 244 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 245 static final boolean DEBUG_TRANSITION = localLOGV || false; 246 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 247 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 248 static final boolean DEBUG_VISBILITY = localLOGV || false; 249 static final boolean DEBUG_PSS = localLOGV || false; 250 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 251 static final boolean VALIDATE_TOKENS = false; 252 static final boolean SHOW_ACTIVITY_START_TIME = true; 253 254 // Control over CPU and battery monitoring. 255 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 256 static final boolean MONITOR_CPU_USAGE = true; 257 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 258 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 259 static final boolean MONITOR_THREAD_CPU_USAGE = false; 260 261 // The flags that are set for all calls we make to the package manager. 262 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 263 264 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 265 266 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 267 268 // Maximum number of recent tasks that we can remember. 269 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 270 271 // Amount of time after a call to stopAppSwitches() during which we will 272 // prevent further untrusted switches from happening. 273 static final long APP_SWITCH_DELAY_TIME = 5*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. 277 static final int PROC_START_TIMEOUT = 10*1000; 278 279 // How long we wait for a launched process to attach to the activity manager 280 // before we decide it's never going to come up for real, when the process was 281 // started with a wrapper for instrumentation (such as Valgrind) because it 282 // could take much longer than usual. 283 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 284 285 // How long to wait after going idle before forcing apps to GC. 286 static final int GC_TIMEOUT = 5*1000; 287 288 // The minimum amount of time between successive GC requests for a process. 289 static final int GC_MIN_INTERVAL = 60*1000; 290 291 // The minimum amount of time between successive PSS requests for a process. 292 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 293 294 // The minimum amount of time between successive PSS requests for a process 295 // when the request is due to the memory state being lowered. 296 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 297 298 // The rate at which we check for apps using excessive power -- 15 mins. 299 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 300 301 // The minimum sample duration we will allow before deciding we have 302 // enough data on wake locks to start killing things. 303 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 304 305 // The minimum sample duration we will allow before deciding we have 306 // enough data on CPU usage to start killing things. 307 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 308 309 // How long we allow a receiver to run before giving up on it. 310 static final int BROADCAST_FG_TIMEOUT = 10*1000; 311 static final int BROADCAST_BG_TIMEOUT = 60*1000; 312 313 // How long we wait until we timeout on key dispatching. 314 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 315 316 // How long we wait until we timeout on key dispatching during instrumentation. 317 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 318 319 // Amount of time we wait for observers to handle a user switch before 320 // giving up on them and unfreezing the screen. 321 static final int USER_SWITCH_TIMEOUT = 2*1000; 322 323 // Maximum number of users we allow to be running at a time. 324 static final int MAX_RUNNING_USERS = 3; 325 326 // How long to wait in getAssistContextExtras for the activity and foreground services 327 // to respond with the result. 328 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 329 330 // Maximum number of persisted Uri grants a package is allowed 331 static final int MAX_PERSISTED_URI_GRANTS = 128; 332 333 static final int MY_PID = Process.myPid(); 334 335 static final String[] EMPTY_STRING_ARRAY = new String[0]; 336 337 // How many bytes to write into the dropbox log before truncating 338 static final int DROPBOX_MAX_SIZE = 256 * 1024; 339 340 /** All system services */ 341 SystemServiceManager mSystemServiceManager; 342 343 /** Run all ActivityStacks through this */ 344 ActivityStackSupervisor mStackSupervisor; 345 346 public IntentFirewall mIntentFirewall; 347 348 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 349 // default actuion automatically. Important for devices without direct input 350 // devices. 351 private boolean mShowDialogs = true; 352 353 /** 354 * Description of a request to start a new activity, which has been held 355 * due to app switches being disabled. 356 */ 357 static class PendingActivityLaunch { 358 final ActivityRecord r; 359 final ActivityRecord sourceRecord; 360 final int startFlags; 361 final ActivityStack stack; 362 363 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 364 int _startFlags, ActivityStack _stack) { 365 r = _r; 366 sourceRecord = _sourceRecord; 367 startFlags = _startFlags; 368 stack = _stack; 369 } 370 } 371 372 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 373 = new ArrayList<PendingActivityLaunch>(); 374 375 BroadcastQueue mFgBroadcastQueue; 376 BroadcastQueue mBgBroadcastQueue; 377 // Convenient for easy iteration over the queues. Foreground is first 378 // so that dispatch of foreground broadcasts gets precedence. 379 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 380 381 BroadcastQueue broadcastQueueForIntent(Intent intent) { 382 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 383 if (DEBUG_BACKGROUND_BROADCAST) { 384 Slog.i(TAG, "Broadcast intent " + intent + " on " 385 + (isFg ? "foreground" : "background") 386 + " queue"); 387 } 388 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 389 } 390 391 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 392 for (BroadcastQueue queue : mBroadcastQueues) { 393 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 394 if (r != null) { 395 return r; 396 } 397 } 398 return null; 399 } 400 401 /** 402 * Activity we have told the window manager to have key focus. 403 */ 404 ActivityRecord mFocusedActivity = null; 405 406 /** 407 * List of intents that were used to start the most recent tasks. 408 */ 409 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 410 411 public class PendingAssistExtras extends Binder implements Runnable { 412 public final ActivityRecord activity; 413 public boolean haveResult = false; 414 public Bundle result = null; 415 public PendingAssistExtras(ActivityRecord _activity) { 416 activity = _activity; 417 } 418 @Override 419 public void run() { 420 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 421 synchronized (this) { 422 haveResult = true; 423 notifyAll(); 424 } 425 } 426 } 427 428 final ArrayList<PendingAssistExtras> mPendingAssistExtras 429 = new ArrayList<PendingAssistExtras>(); 430 431 /** 432 * Process management. 433 */ 434 final ProcessList mProcessList = new ProcessList(); 435 436 /** 437 * All of the applications we currently have running organized by name. 438 * The keys are strings of the application package name (as 439 * returned by the package manager), and the keys are ApplicationRecord 440 * objects. 441 */ 442 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 443 444 /** 445 * Tracking long-term execution of processes to look for abuse and other 446 * bad app behavior. 447 */ 448 final ProcessStatsService mProcessStats; 449 450 /** 451 * The currently running isolated processes. 452 */ 453 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 454 455 /** 456 * Counter for assigning isolated process uids, to avoid frequently reusing the 457 * same ones. 458 */ 459 int mNextIsolatedProcessUid = 0; 460 461 /** 462 * The currently running heavy-weight process, if any. 463 */ 464 ProcessRecord mHeavyWeightProcess = null; 465 466 /** 467 * The last time that various processes have crashed. 468 */ 469 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 470 471 /** 472 * Information about a process that is currently marked as bad. 473 */ 474 static final class BadProcessInfo { 475 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 476 this.time = time; 477 this.shortMsg = shortMsg; 478 this.longMsg = longMsg; 479 this.stack = stack; 480 } 481 482 final long time; 483 final String shortMsg; 484 final String longMsg; 485 final String stack; 486 } 487 488 /** 489 * Set of applications that we consider to be bad, and will reject 490 * incoming broadcasts from (which the user has no control over). 491 * Processes are added to this set when they have crashed twice within 492 * a minimum amount of time; they are removed from it when they are 493 * later restarted (hopefully due to some user action). The value is the 494 * time it was added to the list. 495 */ 496 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 497 498 /** 499 * All of the processes we currently have running organized by pid. 500 * The keys are the pid running the application. 501 * 502 * <p>NOTE: This object is protected by its own lock, NOT the global 503 * activity manager lock! 504 */ 505 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 506 507 /** 508 * All of the processes that have been forced to be foreground. The key 509 * is the pid of the caller who requested it (we hold a death 510 * link on it). 511 */ 512 abstract class ForegroundToken implements IBinder.DeathRecipient { 513 int pid; 514 IBinder token; 515 } 516 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 517 518 /** 519 * List of records for processes that someone had tried to start before the 520 * system was ready. We don't start them at that point, but ensure they 521 * are started by the time booting is complete. 522 */ 523 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 524 525 /** 526 * List of persistent applications that are in the process 527 * of being started. 528 */ 529 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 530 531 /** 532 * Processes that are being forcibly torn down. 533 */ 534 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 535 536 /** 537 * List of running applications, sorted by recent usage. 538 * The first entry in the list is the least recently used. 539 */ 540 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 541 542 /** 543 * Where in mLruProcesses that the processes hosting activities start. 544 */ 545 int mLruProcessActivityStart = 0; 546 547 /** 548 * Where in mLruProcesses that the processes hosting services start. 549 * This is after (lower index) than mLruProcessesActivityStart. 550 */ 551 int mLruProcessServiceStart = 0; 552 553 /** 554 * List of processes that should gc as soon as things are idle. 555 */ 556 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 557 558 /** 559 * Processes we want to collect PSS data from. 560 */ 561 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 562 563 /** 564 * Last time we requested PSS data of all processes. 565 */ 566 long mLastFullPssTime = SystemClock.uptimeMillis(); 567 568 /** 569 * This is the process holding what we currently consider to be 570 * the "home" activity. 571 */ 572 ProcessRecord mHomeProcess; 573 574 /** 575 * This is the process holding the activity the user last visited that 576 * is in a different process from the one they are currently in. 577 */ 578 ProcessRecord mPreviousProcess; 579 580 /** 581 * The time at which the previous process was last visible. 582 */ 583 long mPreviousProcessVisibleTime; 584 585 /** 586 * Which uses have been started, so are allowed to run code. 587 */ 588 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 589 590 /** 591 * LRU list of history of current users. Most recently current is at the end. 592 */ 593 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 594 595 /** 596 * Constant array of the users that are currently started. 597 */ 598 int[] mStartedUserArray = new int[] { 0 }; 599 600 /** 601 * Registered observers of the user switching mechanics. 602 */ 603 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 604 = new RemoteCallbackList<IUserSwitchObserver>(); 605 606 /** 607 * Currently active user switch. 608 */ 609 Object mCurUserSwitchCallback; 610 611 /** 612 * Packages that the user has asked to have run in screen size 613 * compatibility mode instead of filling the screen. 614 */ 615 final CompatModePackages mCompatModePackages; 616 617 /** 618 * Set of IntentSenderRecord objects that are currently active. 619 */ 620 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 621 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 622 623 /** 624 * Fingerprints (hashCode()) of stack traces that we've 625 * already logged DropBox entries for. Guarded by itself. If 626 * something (rogue user app) forces this over 627 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 628 */ 629 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 630 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 631 632 /** 633 * Strict Mode background batched logging state. 634 * 635 * The string buffer is guarded by itself, and its lock is also 636 * used to determine if another batched write is already 637 * in-flight. 638 */ 639 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 640 641 /** 642 * Keeps track of all IIntentReceivers that have been registered for 643 * broadcasts. Hash keys are the receiver IBinder, hash value is 644 * a ReceiverList. 645 */ 646 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 647 new HashMap<IBinder, ReceiverList>(); 648 649 /** 650 * Resolver for broadcast intents to registered receivers. 651 * Holds BroadcastFilter (subclass of IntentFilter). 652 */ 653 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 654 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 655 @Override 656 protected boolean allowFilterResult( 657 BroadcastFilter filter, List<BroadcastFilter> dest) { 658 IBinder target = filter.receiverList.receiver.asBinder(); 659 for (int i=dest.size()-1; i>=0; i--) { 660 if (dest.get(i).receiverList.receiver.asBinder() == target) { 661 return false; 662 } 663 } 664 return true; 665 } 666 667 @Override 668 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 669 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 670 || userId == filter.owningUserId) { 671 return super.newResult(filter, match, userId); 672 } 673 return null; 674 } 675 676 @Override 677 protected BroadcastFilter[] newArray(int size) { 678 return new BroadcastFilter[size]; 679 } 680 681 @Override 682 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 683 return packageName.equals(filter.packageName); 684 } 685 }; 686 687 /** 688 * State of all active sticky broadcasts per user. Keys are the action of the 689 * sticky Intent, values are an ArrayList of all broadcasted intents with 690 * that action (which should usually be one). The SparseArray is keyed 691 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 692 * for stickies that are sent to all users. 693 */ 694 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 695 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 696 697 final ActiveServices mServices; 698 699 /** 700 * Backup/restore process management 701 */ 702 String mBackupAppName = null; 703 BackupRecord mBackupTarget = null; 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 private boolean mSleeping = false; 883 884 /** 885 * Set while we are running a voice interaction. This overrides 886 * sleeping while it is active. 887 */ 888 private boolean mRunningVoice = false; 889 890 /** 891 * State of external calls telling us if the device is asleep. 892 */ 893 private boolean mWentToSleep = false; 894 895 /** 896 * State of external call telling us if the lock screen is shown. 897 */ 898 private boolean mLockScreenShown = false; 899 900 /** 901 * Set if we are shutting down the system, similar to sleeping. 902 */ 903 boolean mShuttingDown = false; 904 905 /** 906 * Current sequence id for oom_adj computation traversal. 907 */ 908 int mAdjSeq = 0; 909 910 /** 911 * Current sequence id for process LRU updating. 912 */ 913 int mLruSeq = 0; 914 915 /** 916 * Keep track of the non-cached/empty process we last found, to help 917 * determine how to distribute cached/empty processes next time. 918 */ 919 int mNumNonCachedProcs = 0; 920 921 /** 922 * Keep track of the number of cached hidden procs, to balance oom adj 923 * distribution between those and empty procs. 924 */ 925 int mNumCachedHiddenProcs = 0; 926 927 /** 928 * Keep track of the number of service processes we last found, to 929 * determine on the next iteration which should be B services. 930 */ 931 int mNumServiceProcs = 0; 932 int mNewNumAServiceProcs = 0; 933 int mNewNumServiceProcs = 0; 934 935 /** 936 * Allow the current computed overall memory level of the system to go down? 937 * This is set to false when we are killing processes for reasons other than 938 * memory management, so that the now smaller process list will not be taken as 939 * an indication that memory is tighter. 940 */ 941 boolean mAllowLowerMemLevel = false; 942 943 /** 944 * The last computed memory level, for holding when we are in a state that 945 * processes are going away for other reasons. 946 */ 947 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 948 949 /** 950 * The last total number of process we have, to determine if changes actually look 951 * like a shrinking number of process due to lower RAM. 952 */ 953 int mLastNumProcesses; 954 955 /** 956 * The uptime of the last time we performed idle maintenance. 957 */ 958 long mLastIdleTime = SystemClock.uptimeMillis(); 959 960 /** 961 * Total time spent with RAM that has been added in the past since the last idle time. 962 */ 963 long mLowRamTimeSinceLastIdle = 0; 964 965 /** 966 * If RAM is currently low, when that horrible situation started. 967 */ 968 long mLowRamStartTime = 0; 969 970 /** 971 * For reporting to battery stats the current top application. 972 */ 973 private String mCurResumedPackage = null; 974 private int mCurResumedUid = -1; 975 976 /** 977 * For reporting to battery stats the apps currently running foreground 978 * service. The ProcessMap is package/uid tuples; each of these contain 979 * an array of the currently foreground processes. 980 */ 981 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 982 = new ProcessMap<ArrayList<ProcessRecord>>(); 983 984 /** 985 * This is set if we had to do a delayed dexopt of an app before launching 986 * it, to increasing the ANR timeouts in that case. 987 */ 988 boolean mDidDexOpt; 989 990 /** 991 * Set if the systemServer made a call to enterSafeMode. 992 */ 993 boolean mSafeMode; 994 995 String mDebugApp = null; 996 boolean mWaitForDebugger = false; 997 boolean mDebugTransient = false; 998 String mOrigDebugApp = null; 999 boolean mOrigWaitForDebugger = false; 1000 boolean mAlwaysFinishActivities = false; 1001 IActivityController mController = null; 1002 String mProfileApp = null; 1003 ProcessRecord mProfileProc = null; 1004 String mProfileFile; 1005 ParcelFileDescriptor mProfileFd; 1006 int mProfileType = 0; 1007 boolean mAutoStopProfiler = false; 1008 String mOpenGlTraceApp = null; 1009 1010 static class ProcessChangeItem { 1011 static final int CHANGE_ACTIVITIES = 1<<0; 1012 static final int CHANGE_PROCESS_STATE = 1<<1; 1013 int changes; 1014 int uid; 1015 int pid; 1016 int processState; 1017 boolean foregroundActivities; 1018 } 1019 1020 final RemoteCallbackList<IProcessObserver> mProcessObservers 1021 = new RemoteCallbackList<IProcessObserver>(); 1022 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1023 1024 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1025 = new ArrayList<ProcessChangeItem>(); 1026 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1027 = new ArrayList<ProcessChangeItem>(); 1028 1029 /** 1030 * Runtime CPU use collection thread. This object's lock is used to 1031 * protect all related state. 1032 */ 1033 final Thread mProcessCpuThread; 1034 1035 /** 1036 * Used to collect process stats when showing not responding dialog. 1037 * Protected by mProcessCpuThread. 1038 */ 1039 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1040 MONITOR_THREAD_CPU_USAGE); 1041 final AtomicLong mLastCpuTime = new AtomicLong(0); 1042 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1043 1044 long mLastWriteTime = 0; 1045 1046 /** 1047 * Used to retain an update lock when the foreground activity is in 1048 * immersive mode. 1049 */ 1050 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1051 1052 /** 1053 * Set to true after the system has finished booting. 1054 */ 1055 boolean mBooted = false; 1056 1057 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1058 int mProcessLimitOverride = -1; 1059 1060 WindowManagerService mWindowManager; 1061 1062 final ActivityThread mSystemThread; 1063 1064 int mCurrentUserId = 0; 1065 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1066 private UserManagerService mUserManager; 1067 1068 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1069 final ProcessRecord mApp; 1070 final int mPid; 1071 final IApplicationThread mAppThread; 1072 1073 AppDeathRecipient(ProcessRecord app, int pid, 1074 IApplicationThread thread) { 1075 if (localLOGV) Slog.v( 1076 TAG, "New death recipient " + this 1077 + " for thread " + thread.asBinder()); 1078 mApp = app; 1079 mPid = pid; 1080 mAppThread = thread; 1081 } 1082 1083 @Override 1084 public void binderDied() { 1085 if (localLOGV) Slog.v( 1086 TAG, "Death received in " + this 1087 + " for thread " + mAppThread.asBinder()); 1088 synchronized(ActivityManagerService.this) { 1089 appDiedLocked(mApp, mPid, mAppThread); 1090 } 1091 } 1092 } 1093 1094 static final int SHOW_ERROR_MSG = 1; 1095 static final int SHOW_NOT_RESPONDING_MSG = 2; 1096 static final int SHOW_FACTORY_ERROR_MSG = 3; 1097 static final int UPDATE_CONFIGURATION_MSG = 4; 1098 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1099 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1100 static final int SERVICE_TIMEOUT_MSG = 12; 1101 static final int UPDATE_TIME_ZONE = 13; 1102 static final int SHOW_UID_ERROR_MSG = 14; 1103 static final int IM_FEELING_LUCKY_MSG = 15; 1104 static final int PROC_START_TIMEOUT_MSG = 20; 1105 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1106 static final int KILL_APPLICATION_MSG = 22; 1107 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1108 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1109 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1110 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1111 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1112 static final int CLEAR_DNS_CACHE_MSG = 28; 1113 static final int UPDATE_HTTP_PROXY_MSG = 29; 1114 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1115 static final int DISPATCH_PROCESSES_CHANGED = 31; 1116 static final int DISPATCH_PROCESS_DIED = 32; 1117 static final int REPORT_MEM_USAGE_MSG = 33; 1118 static final int REPORT_USER_SWITCH_MSG = 34; 1119 static final int CONTINUE_USER_SWITCH_MSG = 35; 1120 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1121 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1122 static final int PERSIST_URI_GRANTS_MSG = 38; 1123 static final int REQUEST_ALL_PSS_MSG = 39; 1124 static final int START_PROFILES_MSG = 40; 1125 static final int UPDATE_TIME = 41; 1126 static final int SYSTEM_USER_START_MSG = 42; 1127 static final int SYSTEM_USER_CURRENT_MSG = 43; 1128 1129 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1130 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1131 static final int FIRST_COMPAT_MODE_MSG = 300; 1132 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1133 1134 AlertDialog mUidAlert; 1135 CompatModeDialog mCompatModeDialog; 1136 long mLastMemUsageReportTime = 0; 1137 1138 /** 1139 * Flag whether the current user is a "monkey", i.e. whether 1140 * the UI is driven by a UI automation tool. 1141 */ 1142 private boolean mUserIsMonkey; 1143 1144 final ServiceThread mHandlerThread; 1145 final MainHandler mHandler; 1146 1147 final class MainHandler extends Handler { 1148 public MainHandler(Looper looper) { 1149 super(looper, null, true); 1150 } 1151 1152 @Override 1153 public void handleMessage(Message msg) { 1154 switch (msg.what) { 1155 case SHOW_ERROR_MSG: { 1156 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1157 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1158 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1159 synchronized (ActivityManagerService.this) { 1160 ProcessRecord proc = (ProcessRecord)data.get("app"); 1161 AppErrorResult res = (AppErrorResult) data.get("result"); 1162 if (proc != null && proc.crashDialog != null) { 1163 Slog.e(TAG, "App already has crash dialog: " + proc); 1164 if (res != null) { 1165 res.set(0); 1166 } 1167 return; 1168 } 1169 if (!showBackground && UserHandle.getAppId(proc.uid) 1170 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1171 && proc.pid != MY_PID) { 1172 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1173 if (res != null) { 1174 res.set(0); 1175 } 1176 return; 1177 } 1178 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1179 Dialog d = new AppErrorDialog(mContext, 1180 ActivityManagerService.this, res, proc); 1181 d.show(); 1182 proc.crashDialog = d; 1183 } else { 1184 // The device is asleep, so just pretend that the user 1185 // saw a crash dialog and hit "force quit". 1186 if (res != null) { 1187 res.set(0); 1188 } 1189 } 1190 } 1191 1192 ensureBootCompleted(); 1193 } break; 1194 case SHOW_NOT_RESPONDING_MSG: { 1195 synchronized (ActivityManagerService.this) { 1196 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1197 ProcessRecord proc = (ProcessRecord)data.get("app"); 1198 if (proc != null && proc.anrDialog != null) { 1199 Slog.e(TAG, "App already has anr dialog: " + proc); 1200 return; 1201 } 1202 1203 Intent intent = new Intent("android.intent.action.ANR"); 1204 if (!mProcessesReady) { 1205 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1206 | Intent.FLAG_RECEIVER_FOREGROUND); 1207 } 1208 broadcastIntentLocked(null, null, intent, 1209 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1210 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1211 1212 if (mShowDialogs) { 1213 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1214 mContext, proc, (ActivityRecord)data.get("activity"), 1215 msg.arg1 != 0); 1216 d.show(); 1217 proc.anrDialog = d; 1218 } else { 1219 // Just kill the app if there is no dialog to be shown. 1220 killAppAtUsersRequest(proc, null); 1221 } 1222 } 1223 1224 ensureBootCompleted(); 1225 } break; 1226 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1227 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1228 synchronized (ActivityManagerService.this) { 1229 ProcessRecord proc = (ProcessRecord) data.get("app"); 1230 if (proc == null) { 1231 Slog.e(TAG, "App not found when showing strict mode dialog."); 1232 break; 1233 } 1234 if (proc.crashDialog != null) { 1235 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1236 return; 1237 } 1238 AppErrorResult res = (AppErrorResult) data.get("result"); 1239 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1240 Dialog d = new StrictModeViolationDialog(mContext, 1241 ActivityManagerService.this, res, proc); 1242 d.show(); 1243 proc.crashDialog = d; 1244 } else { 1245 // The device is asleep, so just pretend that the user 1246 // saw a crash dialog and hit "force quit". 1247 res.set(0); 1248 } 1249 } 1250 ensureBootCompleted(); 1251 } break; 1252 case SHOW_FACTORY_ERROR_MSG: { 1253 Dialog d = new FactoryErrorDialog( 1254 mContext, msg.getData().getCharSequence("msg")); 1255 d.show(); 1256 ensureBootCompleted(); 1257 } break; 1258 case UPDATE_CONFIGURATION_MSG: { 1259 final ContentResolver resolver = mContext.getContentResolver(); 1260 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1261 } break; 1262 case GC_BACKGROUND_PROCESSES_MSG: { 1263 synchronized (ActivityManagerService.this) { 1264 performAppGcsIfAppropriateLocked(); 1265 } 1266 } break; 1267 case WAIT_FOR_DEBUGGER_MSG: { 1268 synchronized (ActivityManagerService.this) { 1269 ProcessRecord app = (ProcessRecord)msg.obj; 1270 if (msg.arg1 != 0) { 1271 if (!app.waitedForDebugger) { 1272 Dialog d = new AppWaitingForDebuggerDialog( 1273 ActivityManagerService.this, 1274 mContext, app); 1275 app.waitDialog = d; 1276 app.waitedForDebugger = true; 1277 d.show(); 1278 } 1279 } else { 1280 if (app.waitDialog != null) { 1281 app.waitDialog.dismiss(); 1282 app.waitDialog = null; 1283 } 1284 } 1285 } 1286 } break; 1287 case SERVICE_TIMEOUT_MSG: { 1288 if (mDidDexOpt) { 1289 mDidDexOpt = false; 1290 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1291 nmsg.obj = msg.obj; 1292 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1293 return; 1294 } 1295 mServices.serviceTimeout((ProcessRecord)msg.obj); 1296 } break; 1297 case UPDATE_TIME_ZONE: { 1298 synchronized (ActivityManagerService.this) { 1299 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1300 ProcessRecord r = mLruProcesses.get(i); 1301 if (r.thread != null) { 1302 try { 1303 r.thread.updateTimeZone(); 1304 } catch (RemoteException ex) { 1305 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1306 } 1307 } 1308 } 1309 } 1310 } break; 1311 case CLEAR_DNS_CACHE_MSG: { 1312 synchronized (ActivityManagerService.this) { 1313 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1314 ProcessRecord r = mLruProcesses.get(i); 1315 if (r.thread != null) { 1316 try { 1317 r.thread.clearDnsCache(); 1318 } catch (RemoteException ex) { 1319 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1320 } 1321 } 1322 } 1323 } 1324 } break; 1325 case UPDATE_HTTP_PROXY_MSG: { 1326 ProxyProperties proxy = (ProxyProperties)msg.obj; 1327 String host = ""; 1328 String port = ""; 1329 String exclList = ""; 1330 String pacFileUrl = null; 1331 if (proxy != null) { 1332 host = proxy.getHost(); 1333 port = Integer.toString(proxy.getPort()); 1334 exclList = proxy.getExclusionList(); 1335 pacFileUrl = proxy.getPacFileUrl(); 1336 } 1337 synchronized (ActivityManagerService.this) { 1338 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1339 ProcessRecord r = mLruProcesses.get(i); 1340 if (r.thread != null) { 1341 try { 1342 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1343 } catch (RemoteException ex) { 1344 Slog.w(TAG, "Failed to update http proxy for: " + 1345 r.info.processName); 1346 } 1347 } 1348 } 1349 } 1350 } break; 1351 case SHOW_UID_ERROR_MSG: { 1352 String title = "System UIDs Inconsistent"; 1353 String text = "UIDs on the system are inconsistent, you need to wipe your" 1354 + " data partition or your device will be unstable."; 1355 Log.e(TAG, title + ": " + text); 1356 if (mShowDialogs) { 1357 // XXX This is a temporary dialog, no need to localize. 1358 AlertDialog d = new BaseErrorDialog(mContext); 1359 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1360 d.setCancelable(false); 1361 d.setTitle(title); 1362 d.setMessage(text); 1363 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1364 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1365 mUidAlert = d; 1366 d.show(); 1367 } 1368 } break; 1369 case IM_FEELING_LUCKY_MSG: { 1370 if (mUidAlert != null) { 1371 mUidAlert.dismiss(); 1372 mUidAlert = null; 1373 } 1374 } break; 1375 case PROC_START_TIMEOUT_MSG: { 1376 if (mDidDexOpt) { 1377 mDidDexOpt = false; 1378 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1379 nmsg.obj = msg.obj; 1380 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1381 return; 1382 } 1383 ProcessRecord app = (ProcessRecord)msg.obj; 1384 synchronized (ActivityManagerService.this) { 1385 processStartTimedOutLocked(app); 1386 } 1387 } break; 1388 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1389 synchronized (ActivityManagerService.this) { 1390 doPendingActivityLaunchesLocked(true); 1391 } 1392 } break; 1393 case KILL_APPLICATION_MSG: { 1394 synchronized (ActivityManagerService.this) { 1395 int appid = msg.arg1; 1396 boolean restart = (msg.arg2 == 1); 1397 Bundle bundle = (Bundle)msg.obj; 1398 String pkg = bundle.getString("pkg"); 1399 String reason = bundle.getString("reason"); 1400 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1401 false, UserHandle.USER_ALL, reason); 1402 } 1403 } break; 1404 case FINALIZE_PENDING_INTENT_MSG: { 1405 ((PendingIntentRecord)msg.obj).completeFinalize(); 1406 } break; 1407 case POST_HEAVY_NOTIFICATION_MSG: { 1408 INotificationManager inm = NotificationManager.getService(); 1409 if (inm == null) { 1410 return; 1411 } 1412 1413 ActivityRecord root = (ActivityRecord)msg.obj; 1414 ProcessRecord process = root.app; 1415 if (process == null) { 1416 return; 1417 } 1418 1419 try { 1420 Context context = mContext.createPackageContext(process.info.packageName, 0); 1421 String text = mContext.getString(R.string.heavy_weight_notification, 1422 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1423 Notification notification = new Notification(); 1424 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1425 notification.when = 0; 1426 notification.flags = Notification.FLAG_ONGOING_EVENT; 1427 notification.tickerText = text; 1428 notification.defaults = 0; // please be quiet 1429 notification.sound = null; 1430 notification.vibrate = null; 1431 notification.setLatestEventInfo(context, text, 1432 mContext.getText(R.string.heavy_weight_notification_detail), 1433 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1434 PendingIntent.FLAG_CANCEL_CURRENT, null, 1435 new UserHandle(root.userId))); 1436 1437 try { 1438 int[] outId = new int[1]; 1439 inm.enqueueNotificationWithTag("android", "android", null, 1440 R.string.heavy_weight_notification, 1441 notification, outId, root.userId); 1442 } catch (RuntimeException e) { 1443 Slog.w(ActivityManagerService.TAG, 1444 "Error showing notification for heavy-weight app", e); 1445 } catch (RemoteException e) { 1446 } 1447 } catch (NameNotFoundException e) { 1448 Slog.w(TAG, "Unable to create context for heavy notification", e); 1449 } 1450 } break; 1451 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1452 INotificationManager inm = NotificationManager.getService(); 1453 if (inm == null) { 1454 return; 1455 } 1456 try { 1457 inm.cancelNotificationWithTag("android", null, 1458 R.string.heavy_weight_notification, msg.arg1); 1459 } catch (RuntimeException e) { 1460 Slog.w(ActivityManagerService.TAG, 1461 "Error canceling notification for service", e); 1462 } catch (RemoteException e) { 1463 } 1464 } break; 1465 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1466 synchronized (ActivityManagerService.this) { 1467 checkExcessivePowerUsageLocked(true); 1468 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1469 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1470 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1471 } 1472 } break; 1473 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1474 synchronized (ActivityManagerService.this) { 1475 ActivityRecord ar = (ActivityRecord)msg.obj; 1476 if (mCompatModeDialog != null) { 1477 if (mCompatModeDialog.mAppInfo.packageName.equals( 1478 ar.info.applicationInfo.packageName)) { 1479 return; 1480 } 1481 mCompatModeDialog.dismiss(); 1482 mCompatModeDialog = null; 1483 } 1484 if (ar != null && false) { 1485 if (mCompatModePackages.getPackageAskCompatModeLocked( 1486 ar.packageName)) { 1487 int mode = mCompatModePackages.computeCompatModeLocked( 1488 ar.info.applicationInfo); 1489 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1490 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1491 mCompatModeDialog = new CompatModeDialog( 1492 ActivityManagerService.this, mContext, 1493 ar.info.applicationInfo); 1494 mCompatModeDialog.show(); 1495 } 1496 } 1497 } 1498 } 1499 break; 1500 } 1501 case DISPATCH_PROCESSES_CHANGED: { 1502 dispatchProcessesChanged(); 1503 break; 1504 } 1505 case DISPATCH_PROCESS_DIED: { 1506 final int pid = msg.arg1; 1507 final int uid = msg.arg2; 1508 dispatchProcessDied(pid, uid); 1509 break; 1510 } 1511 case REPORT_MEM_USAGE_MSG: { 1512 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1513 Thread thread = new Thread() { 1514 @Override public void run() { 1515 final SparseArray<ProcessMemInfo> infoMap 1516 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1517 for (int i=0, N=memInfos.size(); i<N; i++) { 1518 ProcessMemInfo mi = memInfos.get(i); 1519 infoMap.put(mi.pid, mi); 1520 } 1521 updateCpuStatsNow(); 1522 synchronized (mProcessCpuThread) { 1523 final int N = mProcessCpuTracker.countStats(); 1524 for (int i=0; i<N; i++) { 1525 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1526 if (st.vsize > 0) { 1527 long pss = Debug.getPss(st.pid, null); 1528 if (pss > 0) { 1529 if (infoMap.indexOfKey(st.pid) < 0) { 1530 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1531 ProcessList.NATIVE_ADJ, -1, "native", null); 1532 mi.pss = pss; 1533 memInfos.add(mi); 1534 } 1535 } 1536 } 1537 } 1538 } 1539 1540 long totalPss = 0; 1541 for (int i=0, N=memInfos.size(); i<N; i++) { 1542 ProcessMemInfo mi = memInfos.get(i); 1543 if (mi.pss == 0) { 1544 mi.pss = Debug.getPss(mi.pid, null); 1545 } 1546 totalPss += mi.pss; 1547 } 1548 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1549 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1550 if (lhs.oomAdj != rhs.oomAdj) { 1551 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1552 } 1553 if (lhs.pss != rhs.pss) { 1554 return lhs.pss < rhs.pss ? 1 : -1; 1555 } 1556 return 0; 1557 } 1558 }); 1559 1560 StringBuilder tag = new StringBuilder(128); 1561 StringBuilder stack = new StringBuilder(128); 1562 tag.append("Low on memory -- "); 1563 appendMemBucket(tag, totalPss, "total", false); 1564 appendMemBucket(stack, totalPss, "total", true); 1565 1566 StringBuilder logBuilder = new StringBuilder(1024); 1567 logBuilder.append("Low on memory:\n"); 1568 1569 boolean firstLine = true; 1570 int lastOomAdj = Integer.MIN_VALUE; 1571 for (int i=0, N=memInfos.size(); i<N; i++) { 1572 ProcessMemInfo mi = memInfos.get(i); 1573 1574 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1575 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1576 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1577 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1578 if (lastOomAdj != mi.oomAdj) { 1579 lastOomAdj = mi.oomAdj; 1580 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1581 tag.append(" / "); 1582 } 1583 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1584 if (firstLine) { 1585 stack.append(":"); 1586 firstLine = false; 1587 } 1588 stack.append("\n\t at "); 1589 } else { 1590 stack.append("$"); 1591 } 1592 } else { 1593 tag.append(" "); 1594 stack.append("$"); 1595 } 1596 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1597 appendMemBucket(tag, mi.pss, mi.name, false); 1598 } 1599 appendMemBucket(stack, mi.pss, mi.name, true); 1600 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1601 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1602 stack.append("("); 1603 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1604 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1605 stack.append(DUMP_MEM_OOM_LABEL[k]); 1606 stack.append(":"); 1607 stack.append(DUMP_MEM_OOM_ADJ[k]); 1608 } 1609 } 1610 stack.append(")"); 1611 } 1612 } 1613 1614 logBuilder.append(" "); 1615 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1616 logBuilder.append(' '); 1617 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1618 logBuilder.append(' '); 1619 ProcessList.appendRamKb(logBuilder, mi.pss); 1620 logBuilder.append(" kB: "); 1621 logBuilder.append(mi.name); 1622 logBuilder.append(" ("); 1623 logBuilder.append(mi.pid); 1624 logBuilder.append(") "); 1625 logBuilder.append(mi.adjType); 1626 logBuilder.append('\n'); 1627 if (mi.adjReason != null) { 1628 logBuilder.append(" "); 1629 logBuilder.append(mi.adjReason); 1630 logBuilder.append('\n'); 1631 } 1632 } 1633 1634 logBuilder.append(" "); 1635 ProcessList.appendRamKb(logBuilder, totalPss); 1636 logBuilder.append(" kB: TOTAL\n"); 1637 1638 long[] infos = new long[Debug.MEMINFO_COUNT]; 1639 Debug.getMemInfo(infos); 1640 logBuilder.append(" MemInfo: "); 1641 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1642 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1643 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1644 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1645 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1646 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1647 logBuilder.append(" ZRAM: "); 1648 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1649 logBuilder.append(" kB RAM, "); 1650 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1651 logBuilder.append(" kB swap total, "); 1652 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1653 logBuilder.append(" kB swap free\n"); 1654 } 1655 Slog.i(TAG, logBuilder.toString()); 1656 1657 StringBuilder dropBuilder = new StringBuilder(1024); 1658 /* 1659 StringWriter oomSw = new StringWriter(); 1660 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1661 StringWriter catSw = new StringWriter(); 1662 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1663 String[] emptyArgs = new String[] { }; 1664 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1665 oomPw.flush(); 1666 String oomString = oomSw.toString(); 1667 */ 1668 dropBuilder.append(stack); 1669 dropBuilder.append('\n'); 1670 dropBuilder.append('\n'); 1671 dropBuilder.append(logBuilder); 1672 dropBuilder.append('\n'); 1673 /* 1674 dropBuilder.append(oomString); 1675 dropBuilder.append('\n'); 1676 */ 1677 StringWriter catSw = new StringWriter(); 1678 synchronized (ActivityManagerService.this) { 1679 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1680 String[] emptyArgs = new String[] { }; 1681 catPw.println(); 1682 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1683 catPw.println(); 1684 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1685 false, false, null); 1686 catPw.println(); 1687 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1688 catPw.flush(); 1689 } 1690 dropBuilder.append(catSw.toString()); 1691 addErrorToDropBox("lowmem", null, "system_server", null, 1692 null, tag.toString(), dropBuilder.toString(), null, null); 1693 //Slog.i(TAG, "Sent to dropbox:"); 1694 //Slog.i(TAG, dropBuilder.toString()); 1695 synchronized (ActivityManagerService.this) { 1696 long now = SystemClock.uptimeMillis(); 1697 if (mLastMemUsageReportTime < now) { 1698 mLastMemUsageReportTime = now; 1699 } 1700 } 1701 } 1702 }; 1703 thread.start(); 1704 break; 1705 } 1706 case REPORT_USER_SWITCH_MSG: { 1707 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1708 break; 1709 } 1710 case CONTINUE_USER_SWITCH_MSG: { 1711 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1712 break; 1713 } 1714 case USER_SWITCH_TIMEOUT_MSG: { 1715 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1716 break; 1717 } 1718 case IMMERSIVE_MODE_LOCK_MSG: { 1719 final boolean nextState = (msg.arg1 != 0); 1720 if (mUpdateLock.isHeld() != nextState) { 1721 if (DEBUG_IMMERSIVE) { 1722 final ActivityRecord r = (ActivityRecord) msg.obj; 1723 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1724 } 1725 if (nextState) { 1726 mUpdateLock.acquire(); 1727 } else { 1728 mUpdateLock.release(); 1729 } 1730 } 1731 break; 1732 } 1733 case PERSIST_URI_GRANTS_MSG: { 1734 writeGrantedUriPermissions(); 1735 break; 1736 } 1737 case REQUEST_ALL_PSS_MSG: { 1738 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1739 break; 1740 } 1741 case START_PROFILES_MSG: { 1742 synchronized (ActivityManagerService.this) { 1743 startProfilesLocked(); 1744 } 1745 break; 1746 } 1747 case UPDATE_TIME: { 1748 synchronized (ActivityManagerService.this) { 1749 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1750 ProcessRecord r = mLruProcesses.get(i); 1751 if (r.thread != null) { 1752 try { 1753 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1754 } catch (RemoteException ex) { 1755 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1756 } 1757 } 1758 } 1759 } 1760 break; 1761 } 1762 case SYSTEM_USER_START_MSG: { 1763 mSystemServiceManager.startUser(msg.arg1); 1764 break; 1765 } 1766 case SYSTEM_USER_CURRENT_MSG: { 1767 mSystemServiceManager.switchUser(msg.arg1); 1768 break; 1769 } 1770 } 1771 } 1772 }; 1773 1774 static final int COLLECT_PSS_BG_MSG = 1; 1775 1776 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1777 @Override 1778 public void handleMessage(Message msg) { 1779 switch (msg.what) { 1780 case COLLECT_PSS_BG_MSG: { 1781 int i=0, num=0; 1782 long start = SystemClock.uptimeMillis(); 1783 long[] tmp = new long[1]; 1784 do { 1785 ProcessRecord proc; 1786 int procState; 1787 int pid; 1788 synchronized (ActivityManagerService.this) { 1789 if (i >= mPendingPssProcesses.size()) { 1790 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1791 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1792 mPendingPssProcesses.clear(); 1793 return; 1794 } 1795 proc = mPendingPssProcesses.get(i); 1796 procState = proc.pssProcState; 1797 if (proc.thread != null && procState == proc.setProcState) { 1798 pid = proc.pid; 1799 } else { 1800 proc = null; 1801 pid = 0; 1802 } 1803 i++; 1804 } 1805 if (proc != null) { 1806 long pss = Debug.getPss(pid, tmp); 1807 synchronized (ActivityManagerService.this) { 1808 if (proc.thread != null && proc.setProcState == procState 1809 && proc.pid == pid) { 1810 num++; 1811 proc.lastPssTime = SystemClock.uptimeMillis(); 1812 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1813 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1814 + ": " + pss + " lastPss=" + proc.lastPss 1815 + " state=" + ProcessList.makeProcStateString(procState)); 1816 if (proc.initialIdlePss == 0) { 1817 proc.initialIdlePss = pss; 1818 } 1819 proc.lastPss = pss; 1820 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1821 proc.lastCachedPss = pss; 1822 } 1823 } 1824 } 1825 } 1826 } while (true); 1827 } 1828 } 1829 } 1830 }; 1831 1832 /** 1833 * Monitor for package changes and update our internal state. 1834 */ 1835 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1836 @Override 1837 public void onPackageRemoved(String packageName, int uid) { 1838 // Remove all tasks with activities in the specified package from the list of recent tasks 1839 synchronized (ActivityManagerService.this) { 1840 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1841 TaskRecord tr = mRecentTasks.get(i); 1842 ComponentName cn = tr.intent.getComponent(); 1843 if (cn != null && cn.getPackageName().equals(packageName)) { 1844 // If the package name matches, remove the task and kill the process 1845 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1846 } 1847 } 1848 } 1849 } 1850 1851 @Override 1852 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1853 onPackageModified(packageName); 1854 return true; 1855 } 1856 1857 @Override 1858 public void onPackageModified(String packageName) { 1859 final PackageManager pm = mContext.getPackageManager(); 1860 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1861 new ArrayList<Pair<Intent, Integer>>(); 1862 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1863 // Copy the list of recent tasks so that we don't hold onto the lock on 1864 // ActivityManagerService for long periods while checking if components exist. 1865 synchronized (ActivityManagerService.this) { 1866 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1867 TaskRecord tr = mRecentTasks.get(i); 1868 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1869 } 1870 } 1871 // Check the recent tasks and filter out all tasks with components that no longer exist. 1872 Intent tmpI = new Intent(); 1873 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1874 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1875 ComponentName cn = p.first.getComponent(); 1876 if (cn != null && cn.getPackageName().equals(packageName)) { 1877 try { 1878 // Add the task to the list to remove if the component no longer exists 1879 tmpI.setComponent(cn); 1880 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1881 tasksToRemove.add(p.second); 1882 } 1883 } catch (Exception e) {} 1884 } 1885 } 1886 // Prune all the tasks with removed components from the list of recent tasks 1887 synchronized (ActivityManagerService.this) { 1888 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1889 // Remove the task but don't kill the process (since other components in that 1890 // package may still be running and in the background) 1891 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1892 } 1893 } 1894 } 1895 1896 @Override 1897 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1898 // Force stop the specified packages 1899 if (packages != null) { 1900 for (String pkg : packages) { 1901 synchronized (ActivityManagerService.this) { 1902 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1903 "finished booting")) { 1904 return true; 1905 } 1906 } 1907 } 1908 } 1909 return false; 1910 } 1911 }; 1912 1913 public void setSystemProcess() { 1914 try { 1915 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1916 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1917 ServiceManager.addService("meminfo", new MemBinder(this)); 1918 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1919 ServiceManager.addService("dbinfo", new DbBinder(this)); 1920 if (MONITOR_CPU_USAGE) { 1921 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1922 } 1923 ServiceManager.addService("permission", new PermissionController(this)); 1924 1925 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1926 "android", STOCK_PM_FLAGS); 1927 mSystemThread.installSystemApplicationInfo(info); 1928 1929 synchronized (this) { 1930 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1931 app.persistent = true; 1932 app.pid = MY_PID; 1933 app.maxAdj = ProcessList.SYSTEM_ADJ; 1934 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1935 mProcessNames.put(app.processName, app.uid, app); 1936 synchronized (mPidsSelfLocked) { 1937 mPidsSelfLocked.put(app.pid, app); 1938 } 1939 updateLruProcessLocked(app, false, null); 1940 updateOomAdjLocked(); 1941 } 1942 } catch (PackageManager.NameNotFoundException e) { 1943 throw new RuntimeException( 1944 "Unable to find android system package", e); 1945 } 1946 } 1947 1948 public void setWindowManager(WindowManagerService wm) { 1949 mWindowManager = wm; 1950 mStackSupervisor.setWindowManager(wm); 1951 } 1952 1953 public void startObservingNativeCrashes() { 1954 final NativeCrashListener ncl = new NativeCrashListener(this); 1955 ncl.start(); 1956 } 1957 1958 public IAppOpsService getAppOpsService() { 1959 return mAppOpsService; 1960 } 1961 1962 static class MemBinder extends Binder { 1963 ActivityManagerService mActivityManagerService; 1964 MemBinder(ActivityManagerService activityManagerService) { 1965 mActivityManagerService = activityManagerService; 1966 } 1967 1968 @Override 1969 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1970 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1971 != PackageManager.PERMISSION_GRANTED) { 1972 pw.println("Permission Denial: can't dump meminfo from from pid=" 1973 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1974 + " without permission " + android.Manifest.permission.DUMP); 1975 return; 1976 } 1977 1978 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1979 } 1980 } 1981 1982 static class GraphicsBinder extends Binder { 1983 ActivityManagerService mActivityManagerService; 1984 GraphicsBinder(ActivityManagerService activityManagerService) { 1985 mActivityManagerService = activityManagerService; 1986 } 1987 1988 @Override 1989 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1990 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1991 != PackageManager.PERMISSION_GRANTED) { 1992 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1993 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1994 + " without permission " + android.Manifest.permission.DUMP); 1995 return; 1996 } 1997 1998 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1999 } 2000 } 2001 2002 static class DbBinder extends Binder { 2003 ActivityManagerService mActivityManagerService; 2004 DbBinder(ActivityManagerService activityManagerService) { 2005 mActivityManagerService = activityManagerService; 2006 } 2007 2008 @Override 2009 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2010 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2011 != PackageManager.PERMISSION_GRANTED) { 2012 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2013 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2014 + " without permission " + android.Manifest.permission.DUMP); 2015 return; 2016 } 2017 2018 mActivityManagerService.dumpDbInfo(fd, pw, args); 2019 } 2020 } 2021 2022 static class CpuBinder extends Binder { 2023 ActivityManagerService mActivityManagerService; 2024 CpuBinder(ActivityManagerService activityManagerService) { 2025 mActivityManagerService = activityManagerService; 2026 } 2027 2028 @Override 2029 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2030 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2031 != PackageManager.PERMISSION_GRANTED) { 2032 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2033 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2034 + " without permission " + android.Manifest.permission.DUMP); 2035 return; 2036 } 2037 2038 synchronized (mActivityManagerService.mProcessCpuThread) { 2039 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2040 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2041 SystemClock.uptimeMillis())); 2042 } 2043 } 2044 } 2045 2046 public static final class Lifecycle extends SystemService { 2047 private final ActivityManagerService mService; 2048 2049 public Lifecycle(Context context) { 2050 super(context); 2051 mService = new ActivityManagerService(context); 2052 } 2053 2054 @Override 2055 public void onStart() { 2056 mService.start(); 2057 } 2058 2059 public ActivityManagerService getService() { 2060 return mService; 2061 } 2062 } 2063 2064 // Note: This method is invoked on the main thread but may need to attach various 2065 // handlers to other threads. So take care to be explicit about the looper. 2066 public ActivityManagerService(Context systemContext) { 2067 mContext = systemContext; 2068 mFactoryTest = FactoryTest.getMode(); 2069 mSystemThread = ActivityThread.currentActivityThread(); 2070 2071 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2072 2073 mHandlerThread = new ServiceThread(TAG, 2074 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2075 mHandlerThread.start(); 2076 mHandler = new MainHandler(mHandlerThread.getLooper()); 2077 2078 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2079 "foreground", BROADCAST_FG_TIMEOUT, false); 2080 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2081 "background", BROADCAST_BG_TIMEOUT, true); 2082 mBroadcastQueues[0] = mFgBroadcastQueue; 2083 mBroadcastQueues[1] = mBgBroadcastQueue; 2084 2085 mServices = new ActiveServices(this); 2086 mProviderMap = new ProviderMap(this); 2087 2088 // TODO: Move creation of battery stats service outside of activity manager service. 2089 File dataDir = Environment.getDataDirectory(); 2090 File systemDir = new File(dataDir, "system"); 2091 systemDir.mkdirs(); 2092 mBatteryStatsService = new BatteryStatsService(new File( 2093 systemDir, "batterystats.bin").toString(), mHandler); 2094 mBatteryStatsService.getActiveStatistics().readLocked(); 2095 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2096 mOnBattery = DEBUG_POWER ? true 2097 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2098 mBatteryStatsService.getActiveStatistics().setCallback(this); 2099 2100 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2101 2102 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2103 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2104 2105 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2106 2107 // User 0 is the first and only user that runs at boot. 2108 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2109 mUserLru.add(Integer.valueOf(0)); 2110 updateStartedUserArrayLocked(); 2111 2112 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2113 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2114 2115 mConfiguration.setToDefaults(); 2116 mConfiguration.setLocale(Locale.getDefault()); 2117 2118 mConfigurationSeq = mConfiguration.seq = 1; 2119 mProcessCpuTracker.init(); 2120 2121 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2122 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2123 mStackSupervisor = new ActivityStackSupervisor(this); 2124 2125 mProcessCpuThread = new Thread("CpuTracker") { 2126 @Override 2127 public void run() { 2128 while (true) { 2129 try { 2130 try { 2131 synchronized(this) { 2132 final long now = SystemClock.uptimeMillis(); 2133 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2134 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2135 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2136 // + ", write delay=" + nextWriteDelay); 2137 if (nextWriteDelay < nextCpuDelay) { 2138 nextCpuDelay = nextWriteDelay; 2139 } 2140 if (nextCpuDelay > 0) { 2141 mProcessCpuMutexFree.set(true); 2142 this.wait(nextCpuDelay); 2143 } 2144 } 2145 } catch (InterruptedException e) { 2146 } 2147 updateCpuStatsNow(); 2148 } catch (Exception e) { 2149 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2150 } 2151 } 2152 } 2153 }; 2154 2155 Watchdog.getInstance().addMonitor(this); 2156 Watchdog.getInstance().addThread(mHandler); 2157 } 2158 2159 public void setSystemServiceManager(SystemServiceManager mgr) { 2160 mSystemServiceManager = mgr; 2161 } 2162 2163 private void start() { 2164 mProcessCpuThread.start(); 2165 2166 mBatteryStatsService.publish(mContext); 2167 mUsageStatsService.publish(mContext); 2168 mAppOpsService.publish(mContext); 2169 2170 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2171 } 2172 2173 @Override 2174 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2175 throws RemoteException { 2176 if (code == SYSPROPS_TRANSACTION) { 2177 // We need to tell all apps about the system property change. 2178 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2179 synchronized(this) { 2180 final int NP = mProcessNames.getMap().size(); 2181 for (int ip=0; ip<NP; ip++) { 2182 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2183 final int NA = apps.size(); 2184 for (int ia=0; ia<NA; ia++) { 2185 ProcessRecord app = apps.valueAt(ia); 2186 if (app.thread != null) { 2187 procs.add(app.thread.asBinder()); 2188 } 2189 } 2190 } 2191 } 2192 2193 int N = procs.size(); 2194 for (int i=0; i<N; i++) { 2195 Parcel data2 = Parcel.obtain(); 2196 try { 2197 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2198 } catch (RemoteException e) { 2199 } 2200 data2.recycle(); 2201 } 2202 } 2203 try { 2204 return super.onTransact(code, data, reply, flags); 2205 } catch (RuntimeException e) { 2206 // The activity manager only throws security exceptions, so let's 2207 // log all others. 2208 if (!(e instanceof SecurityException)) { 2209 Slog.wtf(TAG, "Activity Manager Crash", e); 2210 } 2211 throw e; 2212 } 2213 } 2214 2215 void updateCpuStats() { 2216 final long now = SystemClock.uptimeMillis(); 2217 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2218 return; 2219 } 2220 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2221 synchronized (mProcessCpuThread) { 2222 mProcessCpuThread.notify(); 2223 } 2224 } 2225 } 2226 2227 void updateCpuStatsNow() { 2228 synchronized (mProcessCpuThread) { 2229 mProcessCpuMutexFree.set(false); 2230 final long now = SystemClock.uptimeMillis(); 2231 boolean haveNewCpuStats = false; 2232 2233 if (MONITOR_CPU_USAGE && 2234 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2235 mLastCpuTime.set(now); 2236 haveNewCpuStats = true; 2237 mProcessCpuTracker.update(); 2238 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2239 //Slog.i(TAG, "Total CPU usage: " 2240 // + mProcessCpu.getTotalCpuPercent() + "%"); 2241 2242 // Slog the cpu usage if the property is set. 2243 if ("true".equals(SystemProperties.get("events.cpu"))) { 2244 int user = mProcessCpuTracker.getLastUserTime(); 2245 int system = mProcessCpuTracker.getLastSystemTime(); 2246 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2247 int irq = mProcessCpuTracker.getLastIrqTime(); 2248 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2249 int idle = mProcessCpuTracker.getLastIdleTime(); 2250 2251 int total = user + system + iowait + irq + softIrq + idle; 2252 if (total == 0) total = 1; 2253 2254 EventLog.writeEvent(EventLogTags.CPU, 2255 ((user+system+iowait+irq+softIrq) * 100) / total, 2256 (user * 100) / total, 2257 (system * 100) / total, 2258 (iowait * 100) / total, 2259 (irq * 100) / total, 2260 (softIrq * 100) / total); 2261 } 2262 } 2263 2264 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2265 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2266 synchronized(bstats) { 2267 synchronized(mPidsSelfLocked) { 2268 if (haveNewCpuStats) { 2269 if (mOnBattery) { 2270 int perc = bstats.startAddingCpuLocked(); 2271 int totalUTime = 0; 2272 int totalSTime = 0; 2273 final int N = mProcessCpuTracker.countStats(); 2274 for (int i=0; i<N; i++) { 2275 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2276 if (!st.working) { 2277 continue; 2278 } 2279 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2280 int otherUTime = (st.rel_utime*perc)/100; 2281 int otherSTime = (st.rel_stime*perc)/100; 2282 totalUTime += otherUTime; 2283 totalSTime += otherSTime; 2284 if (pr != null) { 2285 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2286 if (ps == null || !ps.isActive()) { 2287 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2288 pr.info.uid, pr.processName); 2289 } 2290 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2291 st.rel_stime-otherSTime); 2292 ps.addSpeedStepTimes(cpuSpeedTimes); 2293 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2294 } else { 2295 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2296 if (ps == null || !ps.isActive()) { 2297 st.batteryStats = ps = bstats.getProcessStatsLocked( 2298 bstats.mapUid(st.uid), st.name); 2299 } 2300 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2301 st.rel_stime-otherSTime); 2302 ps.addSpeedStepTimes(cpuSpeedTimes); 2303 } 2304 } 2305 bstats.finishAddingCpuLocked(perc, totalUTime, 2306 totalSTime, cpuSpeedTimes); 2307 } 2308 } 2309 } 2310 2311 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2312 mLastWriteTime = now; 2313 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2314 } 2315 } 2316 } 2317 } 2318 2319 @Override 2320 public void batteryNeedsCpuUpdate() { 2321 updateCpuStatsNow(); 2322 } 2323 2324 @Override 2325 public void batteryPowerChanged(boolean onBattery) { 2326 // When plugging in, update the CPU stats first before changing 2327 // the plug state. 2328 updateCpuStatsNow(); 2329 synchronized (this) { 2330 synchronized(mPidsSelfLocked) { 2331 mOnBattery = DEBUG_POWER ? true : onBattery; 2332 } 2333 } 2334 } 2335 2336 /** 2337 * Initialize the application bind args. These are passed to each 2338 * process when the bindApplication() IPC is sent to the process. They're 2339 * lazily setup to make sure the services are running when they're asked for. 2340 */ 2341 private HashMap<String, IBinder> getCommonServicesLocked() { 2342 if (mAppBindArgs == null) { 2343 mAppBindArgs = new HashMap<String, IBinder>(); 2344 2345 // Setup the application init args 2346 mAppBindArgs.put("package", ServiceManager.getService("package")); 2347 mAppBindArgs.put("window", ServiceManager.getService("window")); 2348 mAppBindArgs.put(Context.ALARM_SERVICE, 2349 ServiceManager.getService(Context.ALARM_SERVICE)); 2350 } 2351 return mAppBindArgs; 2352 } 2353 2354 final void setFocusedActivityLocked(ActivityRecord r) { 2355 if (mFocusedActivity != r) { 2356 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2357 mFocusedActivity = r; 2358 if (r.task != null && r.task.voiceInteractor != null) { 2359 startRunningVoiceLocked(); 2360 } else { 2361 finishRunningVoiceLocked(); 2362 } 2363 mStackSupervisor.setFocusedStack(r); 2364 if (r != null) { 2365 mWindowManager.setFocusedApp(r.appToken, true); 2366 } 2367 applyUpdateLockStateLocked(r); 2368 } 2369 } 2370 2371 final void clearFocusedActivity(ActivityRecord r) { 2372 if (mFocusedActivity == r) { 2373 mFocusedActivity = null; 2374 } 2375 } 2376 2377 @Override 2378 public void setFocusedStack(int stackId) { 2379 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2380 synchronized (ActivityManagerService.this) { 2381 ActivityStack stack = mStackSupervisor.getStack(stackId); 2382 if (stack != null) { 2383 ActivityRecord r = stack.topRunningActivityLocked(null); 2384 if (r != null) { 2385 setFocusedActivityLocked(r); 2386 } 2387 } 2388 } 2389 } 2390 2391 @Override 2392 public void notifyActivityDrawn(IBinder token) { 2393 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2394 synchronized (this) { 2395 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2396 if (r != null) { 2397 r.task.stack.notifyActivityDrawnLocked(r); 2398 } 2399 } 2400 } 2401 2402 final void applyUpdateLockStateLocked(ActivityRecord r) { 2403 // Modifications to the UpdateLock state are done on our handler, outside 2404 // the activity manager's locks. The new state is determined based on the 2405 // state *now* of the relevant activity record. The object is passed to 2406 // the handler solely for logging detail, not to be consulted/modified. 2407 final boolean nextState = r != null && r.immersive; 2408 mHandler.sendMessage( 2409 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2410 } 2411 2412 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2413 Message msg = Message.obtain(); 2414 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2415 msg.obj = r.task.askedCompatMode ? null : r; 2416 mHandler.sendMessage(msg); 2417 } 2418 2419 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2420 String what, Object obj, ProcessRecord srcApp) { 2421 app.lastActivityTime = now; 2422 2423 if (app.activities.size() > 0) { 2424 // Don't want to touch dependent processes that are hosting activities. 2425 return index; 2426 } 2427 2428 int lrui = mLruProcesses.lastIndexOf(app); 2429 if (lrui < 0) { 2430 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2431 + what + " " + obj + " from " + srcApp); 2432 return index; 2433 } 2434 2435 if (lrui >= index) { 2436 // Don't want to cause this to move dependent processes *back* in the 2437 // list as if they were less frequently used. 2438 return index; 2439 } 2440 2441 if (lrui >= mLruProcessActivityStart) { 2442 // Don't want to touch dependent processes that are hosting activities. 2443 return index; 2444 } 2445 2446 mLruProcesses.remove(lrui); 2447 if (index > 0) { 2448 index--; 2449 } 2450 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2451 + " in LRU list: " + app); 2452 mLruProcesses.add(index, app); 2453 return index; 2454 } 2455 2456 final void removeLruProcessLocked(ProcessRecord app) { 2457 int lrui = mLruProcesses.lastIndexOf(app); 2458 if (lrui >= 0) { 2459 if (lrui <= mLruProcessActivityStart) { 2460 mLruProcessActivityStart--; 2461 } 2462 if (lrui <= mLruProcessServiceStart) { 2463 mLruProcessServiceStart--; 2464 } 2465 mLruProcesses.remove(lrui); 2466 } 2467 } 2468 2469 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2470 ProcessRecord client) { 2471 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2472 || app.treatLikeActivity; 2473 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2474 if (!activityChange && hasActivity) { 2475 // The process has activities, so we are only allowing activity-based adjustments 2476 // to move it. It should be kept in the front of the list with other 2477 // processes that have activities, and we don't want those to change their 2478 // order except due to activity operations. 2479 return; 2480 } 2481 2482 mLruSeq++; 2483 final long now = SystemClock.uptimeMillis(); 2484 app.lastActivityTime = now; 2485 2486 // First a quick reject: if the app is already at the position we will 2487 // put it, then there is nothing to do. 2488 if (hasActivity) { 2489 final int N = mLruProcesses.size(); 2490 if (N > 0 && mLruProcesses.get(N-1) == app) { 2491 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2492 return; 2493 } 2494 } else { 2495 if (mLruProcessServiceStart > 0 2496 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2497 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2498 return; 2499 } 2500 } 2501 2502 int lrui = mLruProcesses.lastIndexOf(app); 2503 2504 if (app.persistent && lrui >= 0) { 2505 // We don't care about the position of persistent processes, as long as 2506 // they are in the list. 2507 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2508 return; 2509 } 2510 2511 /* In progress: compute new position first, so we can avoid doing work 2512 if the process is not actually going to move. Not yet working. 2513 int addIndex; 2514 int nextIndex; 2515 boolean inActivity = false, inService = false; 2516 if (hasActivity) { 2517 // Process has activities, put it at the very tipsy-top. 2518 addIndex = mLruProcesses.size(); 2519 nextIndex = mLruProcessServiceStart; 2520 inActivity = true; 2521 } else if (hasService) { 2522 // Process has services, put it at the top of the service list. 2523 addIndex = mLruProcessActivityStart; 2524 nextIndex = mLruProcessServiceStart; 2525 inActivity = true; 2526 inService = true; 2527 } else { 2528 // Process not otherwise of interest, it goes to the top of the non-service area. 2529 addIndex = mLruProcessServiceStart; 2530 if (client != null) { 2531 int clientIndex = mLruProcesses.lastIndexOf(client); 2532 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2533 + app); 2534 if (clientIndex >= 0 && addIndex > clientIndex) { 2535 addIndex = clientIndex; 2536 } 2537 } 2538 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2539 } 2540 2541 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2542 + mLruProcessActivityStart + "): " + app); 2543 */ 2544 2545 if (lrui >= 0) { 2546 if (lrui < mLruProcessActivityStart) { 2547 mLruProcessActivityStart--; 2548 } 2549 if (lrui < mLruProcessServiceStart) { 2550 mLruProcessServiceStart--; 2551 } 2552 /* 2553 if (addIndex > lrui) { 2554 addIndex--; 2555 } 2556 if (nextIndex > lrui) { 2557 nextIndex--; 2558 } 2559 */ 2560 mLruProcesses.remove(lrui); 2561 } 2562 2563 /* 2564 mLruProcesses.add(addIndex, app); 2565 if (inActivity) { 2566 mLruProcessActivityStart++; 2567 } 2568 if (inService) { 2569 mLruProcessActivityStart++; 2570 } 2571 */ 2572 2573 int nextIndex; 2574 if (hasActivity) { 2575 final int N = mLruProcesses.size(); 2576 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2577 // Process doesn't have activities, but has clients with 2578 // activities... move it up, but one below the top (the top 2579 // should always have a real activity). 2580 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2581 mLruProcesses.add(N-1, app); 2582 // To keep it from spamming the LRU list (by making a bunch of clients), 2583 // we will push down any other entries owned by the app. 2584 final int uid = app.info.uid; 2585 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2586 ProcessRecord subProc = mLruProcesses.get(i); 2587 if (subProc.info.uid == uid) { 2588 // We want to push this one down the list. If the process after 2589 // it is for the same uid, however, don't do so, because we don't 2590 // want them internally to be re-ordered. 2591 if (mLruProcesses.get(i-1).info.uid != uid) { 2592 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2593 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2594 ProcessRecord tmp = mLruProcesses.get(i); 2595 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2596 mLruProcesses.set(i-1, tmp); 2597 i--; 2598 } 2599 } else { 2600 // A gap, we can stop here. 2601 break; 2602 } 2603 } 2604 } else { 2605 // Process has activities, put it at the very tipsy-top. 2606 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2607 mLruProcesses.add(app); 2608 } 2609 nextIndex = mLruProcessServiceStart; 2610 } else if (hasService) { 2611 // Process has services, put it at the top of the service list. 2612 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2613 mLruProcesses.add(mLruProcessActivityStart, app); 2614 nextIndex = mLruProcessServiceStart; 2615 mLruProcessActivityStart++; 2616 } else { 2617 // Process not otherwise of interest, it goes to the top of the non-service area. 2618 int index = mLruProcessServiceStart; 2619 if (client != null) { 2620 // If there is a client, don't allow the process to be moved up higher 2621 // in the list than that client. 2622 int clientIndex = mLruProcesses.lastIndexOf(client); 2623 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2624 + " when updating " + app); 2625 if (clientIndex <= lrui) { 2626 // Don't allow the client index restriction to push it down farther in the 2627 // list than it already is. 2628 clientIndex = lrui; 2629 } 2630 if (clientIndex >= 0 && index > clientIndex) { 2631 index = clientIndex; 2632 } 2633 } 2634 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2635 mLruProcesses.add(index, app); 2636 nextIndex = index-1; 2637 mLruProcessActivityStart++; 2638 mLruProcessServiceStart++; 2639 } 2640 2641 // If the app is currently using a content provider or service, 2642 // bump those processes as well. 2643 for (int j=app.connections.size()-1; j>=0; j--) { 2644 ConnectionRecord cr = app.connections.valueAt(j); 2645 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2646 && cr.binding.service.app != null 2647 && cr.binding.service.app.lruSeq != mLruSeq 2648 && !cr.binding.service.app.persistent) { 2649 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2650 "service connection", cr, app); 2651 } 2652 } 2653 for (int j=app.conProviders.size()-1; j>=0; j--) { 2654 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2655 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2656 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2657 "provider reference", cpr, app); 2658 } 2659 } 2660 } 2661 2662 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2663 if (uid == Process.SYSTEM_UID) { 2664 // The system gets to run in any process. If there are multiple 2665 // processes with the same uid, just pick the first (this 2666 // should never happen). 2667 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2668 if (procs == null) return null; 2669 final int N = procs.size(); 2670 for (int i = 0; i < N; i++) { 2671 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2672 } 2673 } 2674 ProcessRecord proc = mProcessNames.get(processName, uid); 2675 if (false && proc != null && !keepIfLarge 2676 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2677 && proc.lastCachedPss >= 4000) { 2678 // Turn this condition on to cause killing to happen regularly, for testing. 2679 if (proc.baseProcessTracker != null) { 2680 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2681 } 2682 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2683 + "k from cached"); 2684 } else if (proc != null && !keepIfLarge 2685 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2686 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2687 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2688 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2689 if (proc.baseProcessTracker != null) { 2690 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2691 } 2692 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2693 + "k from cached"); 2694 } 2695 } 2696 return proc; 2697 } 2698 2699 void ensurePackageDexOpt(String packageName) { 2700 IPackageManager pm = AppGlobals.getPackageManager(); 2701 try { 2702 if (pm.performDexOpt(packageName)) { 2703 mDidDexOpt = true; 2704 } 2705 } catch (RemoteException e) { 2706 } 2707 } 2708 2709 boolean isNextTransitionForward() { 2710 int transit = mWindowManager.getPendingAppTransition(); 2711 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2712 || transit == AppTransition.TRANSIT_TASK_OPEN 2713 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2714 } 2715 2716 final ProcessRecord startProcessLocked(String processName, 2717 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2718 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2719 boolean isolated, boolean keepIfLarge) { 2720 ProcessRecord app; 2721 if (!isolated) { 2722 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2723 } else { 2724 // If this is an isolated process, it can't re-use an existing process. 2725 app = null; 2726 } 2727 // We don't have to do anything more if: 2728 // (1) There is an existing application record; and 2729 // (2) The caller doesn't think it is dead, OR there is no thread 2730 // object attached to it so we know it couldn't have crashed; and 2731 // (3) There is a pid assigned to it, so it is either starting or 2732 // already running. 2733 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2734 + " app=" + app + " knownToBeDead=" + knownToBeDead 2735 + " thread=" + (app != null ? app.thread : null) 2736 + " pid=" + (app != null ? app.pid : -1)); 2737 if (app != null && app.pid > 0) { 2738 if (!knownToBeDead || app.thread == null) { 2739 // We already have the app running, or are waiting for it to 2740 // come up (we have a pid but not yet its thread), so keep it. 2741 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2742 // If this is a new package in the process, add the package to the list 2743 app.addPackage(info.packageName, mProcessStats); 2744 return app; 2745 } 2746 2747 // An application record is attached to a previous process, 2748 // clean it up now. 2749 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2750 handleAppDiedLocked(app, true, true); 2751 } 2752 2753 String hostingNameStr = hostingName != null 2754 ? hostingName.flattenToShortString() : null; 2755 2756 if (!isolated) { 2757 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2758 // If we are in the background, then check to see if this process 2759 // is bad. If so, we will just silently fail. 2760 if (mBadProcesses.get(info.processName, info.uid) != null) { 2761 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2762 + "/" + info.processName); 2763 return null; 2764 } 2765 } else { 2766 // When the user is explicitly starting a process, then clear its 2767 // crash count so that we won't make it bad until they see at 2768 // least one crash dialog again, and make the process good again 2769 // if it had been bad. 2770 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2771 + "/" + info.processName); 2772 mProcessCrashTimes.remove(info.processName, info.uid); 2773 if (mBadProcesses.get(info.processName, info.uid) != null) { 2774 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2775 UserHandle.getUserId(info.uid), info.uid, 2776 info.processName); 2777 mBadProcesses.remove(info.processName, info.uid); 2778 if (app != null) { 2779 app.bad = false; 2780 } 2781 } 2782 } 2783 } 2784 2785 if (app == null) { 2786 app = newProcessRecordLocked(info, processName, isolated); 2787 if (app == null) { 2788 Slog.w(TAG, "Failed making new process record for " 2789 + processName + "/" + info.uid + " isolated=" + isolated); 2790 return null; 2791 } 2792 mProcessNames.put(processName, app.uid, app); 2793 if (isolated) { 2794 mIsolatedProcesses.put(app.uid, app); 2795 } 2796 } else { 2797 // If this is a new package in the process, add the package to the list 2798 app.addPackage(info.packageName, mProcessStats); 2799 } 2800 2801 // If the system is not ready yet, then hold off on starting this 2802 // process until it is. 2803 if (!mProcessesReady 2804 && !isAllowedWhileBooting(info) 2805 && !allowWhileBooting) { 2806 if (!mProcessesOnHold.contains(app)) { 2807 mProcessesOnHold.add(app); 2808 } 2809 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2810 return app; 2811 } 2812 2813 startProcessLocked(app, hostingType, hostingNameStr); 2814 return (app.pid != 0) ? app : null; 2815 } 2816 2817 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2818 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2819 } 2820 2821 private final void startProcessLocked(ProcessRecord app, 2822 String hostingType, String hostingNameStr) { 2823 if (app.pid > 0 && app.pid != MY_PID) { 2824 synchronized (mPidsSelfLocked) { 2825 mPidsSelfLocked.remove(app.pid); 2826 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2827 } 2828 app.setPid(0); 2829 } 2830 2831 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2832 "startProcessLocked removing on hold: " + app); 2833 mProcessesOnHold.remove(app); 2834 2835 updateCpuStats(); 2836 2837 try { 2838 int uid = app.uid; 2839 2840 int[] gids = null; 2841 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2842 if (!app.isolated) { 2843 int[] permGids = null; 2844 try { 2845 final PackageManager pm = mContext.getPackageManager(); 2846 permGids = pm.getPackageGids(app.info.packageName); 2847 2848 if (Environment.isExternalStorageEmulated()) { 2849 if (pm.checkPermission( 2850 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2851 app.info.packageName) == PERMISSION_GRANTED) { 2852 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2853 } else { 2854 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2855 } 2856 } 2857 } catch (PackageManager.NameNotFoundException e) { 2858 Slog.w(TAG, "Unable to retrieve gids", e); 2859 } 2860 2861 /* 2862 * Add shared application GID so applications can share some 2863 * resources like shared libraries 2864 */ 2865 if (permGids == null) { 2866 gids = new int[1]; 2867 } else { 2868 gids = new int[permGids.length + 1]; 2869 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2870 } 2871 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2872 } 2873 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2874 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2875 && mTopComponent != null 2876 && app.processName.equals(mTopComponent.getPackageName())) { 2877 uid = 0; 2878 } 2879 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2880 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2881 uid = 0; 2882 } 2883 } 2884 int debugFlags = 0; 2885 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2886 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2887 // Also turn on CheckJNI for debuggable apps. It's quite 2888 // awkward to turn on otherwise. 2889 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2890 } 2891 // Run the app in safe mode if its manifest requests so or the 2892 // system is booted in safe mode. 2893 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2894 mSafeMode == true) { 2895 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2896 } 2897 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2898 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2899 } 2900 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2901 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2902 } 2903 if ("1".equals(SystemProperties.get("debug.assert"))) { 2904 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2905 } 2906 2907 String requiredAbi = app.info.requiredCpuAbi; 2908 if (requiredAbi == null) { 2909 requiredAbi = Build.SUPPORTED_ABIS[0]; 2910 } 2911 2912 // Start the process. It will either succeed and return a result containing 2913 // the PID of the new process, or else throw a RuntimeException. 2914 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2915 app.processName, uid, uid, gids, debugFlags, mountExternal, 2916 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2917 2918 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2919 synchronized (bs) { 2920 if (bs.isOnBattery()) { 2921 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2922 } 2923 } 2924 2925 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2926 UserHandle.getUserId(uid), startResult.pid, uid, 2927 app.processName, hostingType, 2928 hostingNameStr != null ? hostingNameStr : ""); 2929 2930 if (app.persistent) { 2931 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2932 } 2933 2934 StringBuilder buf = mStringBuilder; 2935 buf.setLength(0); 2936 buf.append("Start proc "); 2937 buf.append(app.processName); 2938 buf.append(" for "); 2939 buf.append(hostingType); 2940 if (hostingNameStr != null) { 2941 buf.append(" "); 2942 buf.append(hostingNameStr); 2943 } 2944 buf.append(": pid="); 2945 buf.append(startResult.pid); 2946 buf.append(" uid="); 2947 buf.append(uid); 2948 buf.append(" gids={"); 2949 if (gids != null) { 2950 for (int gi=0; gi<gids.length; gi++) { 2951 if (gi != 0) buf.append(", "); 2952 buf.append(gids[gi]); 2953 2954 } 2955 } 2956 buf.append("}"); 2957 Slog.i(TAG, buf.toString()); 2958 app.setPid(startResult.pid); 2959 app.usingWrapper = startResult.usingWrapper; 2960 app.removed = false; 2961 synchronized (mPidsSelfLocked) { 2962 this.mPidsSelfLocked.put(startResult.pid, app); 2963 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2964 msg.obj = app; 2965 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2966 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2967 } 2968 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2969 app.processName, app.info.uid); 2970 if (app.isolated) { 2971 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2972 } 2973 } catch (RuntimeException e) { 2974 // XXX do better error recovery. 2975 app.setPid(0); 2976 Slog.e(TAG, "Failure starting process " + app.processName, e); 2977 } 2978 } 2979 2980 void updateUsageStats(ActivityRecord component, boolean resumed) { 2981 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2982 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2983 if (resumed) { 2984 mUsageStatsService.noteResumeComponent(component.realActivity); 2985 synchronized (stats) { 2986 stats.noteActivityResumedLocked(component.app.uid); 2987 } 2988 } else { 2989 mUsageStatsService.notePauseComponent(component.realActivity); 2990 synchronized (stats) { 2991 stats.noteActivityPausedLocked(component.app.uid); 2992 } 2993 } 2994 } 2995 2996 Intent getHomeIntent() { 2997 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2998 intent.setComponent(mTopComponent); 2999 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3000 intent.addCategory(Intent.CATEGORY_HOME); 3001 } 3002 return intent; 3003 } 3004 3005 boolean startHomeActivityLocked(int userId) { 3006 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3007 && mTopAction == null) { 3008 // We are running in factory test mode, but unable to find 3009 // the factory test app, so just sit around displaying the 3010 // error message and don't try to start anything. 3011 return false; 3012 } 3013 Intent intent = getHomeIntent(); 3014 ActivityInfo aInfo = 3015 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3016 if (aInfo != null) { 3017 intent.setComponent(new ComponentName( 3018 aInfo.applicationInfo.packageName, aInfo.name)); 3019 // Don't do this if the home app is currently being 3020 // instrumented. 3021 aInfo = new ActivityInfo(aInfo); 3022 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3023 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3024 aInfo.applicationInfo.uid, true); 3025 if (app == null || app.instrumentationClass == null) { 3026 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3027 mStackSupervisor.startHomeActivity(intent, aInfo); 3028 } 3029 } 3030 3031 return true; 3032 } 3033 3034 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3035 ActivityInfo ai = null; 3036 ComponentName comp = intent.getComponent(); 3037 try { 3038 if (comp != null) { 3039 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3040 } else { 3041 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3042 intent, 3043 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3044 flags, userId); 3045 3046 if (info != null) { 3047 ai = info.activityInfo; 3048 } 3049 } 3050 } catch (RemoteException e) { 3051 // ignore 3052 } 3053 3054 return ai; 3055 } 3056 3057 /** 3058 * Starts the "new version setup screen" if appropriate. 3059 */ 3060 void startSetupActivityLocked() { 3061 // Only do this once per boot. 3062 if (mCheckedForSetup) { 3063 return; 3064 } 3065 3066 // We will show this screen if the current one is a different 3067 // version than the last one shown, and we are not running in 3068 // low-level factory test mode. 3069 final ContentResolver resolver = mContext.getContentResolver(); 3070 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3071 Settings.Global.getInt(resolver, 3072 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3073 mCheckedForSetup = true; 3074 3075 // See if we should be showing the platform update setup UI. 3076 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3077 List<ResolveInfo> ris = mContext.getPackageManager() 3078 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3079 3080 // We don't allow third party apps to replace this. 3081 ResolveInfo ri = null; 3082 for (int i=0; ris != null && i<ris.size(); i++) { 3083 if ((ris.get(i).activityInfo.applicationInfo.flags 3084 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3085 ri = ris.get(i); 3086 break; 3087 } 3088 } 3089 3090 if (ri != null) { 3091 String vers = ri.activityInfo.metaData != null 3092 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3093 : null; 3094 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3095 vers = ri.activityInfo.applicationInfo.metaData.getString( 3096 Intent.METADATA_SETUP_VERSION); 3097 } 3098 String lastVers = Settings.Secure.getString( 3099 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3100 if (vers != null && !vers.equals(lastVers)) { 3101 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3102 intent.setComponent(new ComponentName( 3103 ri.activityInfo.packageName, ri.activityInfo.name)); 3104 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3105 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3106 } 3107 } 3108 } 3109 } 3110 3111 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3112 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3113 } 3114 3115 void enforceNotIsolatedCaller(String caller) { 3116 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3117 throw new SecurityException("Isolated process not allowed to call " + caller); 3118 } 3119 } 3120 3121 @Override 3122 public int getFrontActivityScreenCompatMode() { 3123 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3124 synchronized (this) { 3125 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3126 } 3127 } 3128 3129 @Override 3130 public void setFrontActivityScreenCompatMode(int mode) { 3131 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3132 "setFrontActivityScreenCompatMode"); 3133 synchronized (this) { 3134 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3135 } 3136 } 3137 3138 @Override 3139 public int getPackageScreenCompatMode(String packageName) { 3140 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3141 synchronized (this) { 3142 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3143 } 3144 } 3145 3146 @Override 3147 public void setPackageScreenCompatMode(String packageName, int mode) { 3148 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3149 "setPackageScreenCompatMode"); 3150 synchronized (this) { 3151 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3152 } 3153 } 3154 3155 @Override 3156 public boolean getPackageAskScreenCompat(String packageName) { 3157 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3158 synchronized (this) { 3159 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3160 } 3161 } 3162 3163 @Override 3164 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3165 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3166 "setPackageAskScreenCompat"); 3167 synchronized (this) { 3168 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3169 } 3170 } 3171 3172 private void dispatchProcessesChanged() { 3173 int N; 3174 synchronized (this) { 3175 N = mPendingProcessChanges.size(); 3176 if (mActiveProcessChanges.length < N) { 3177 mActiveProcessChanges = new ProcessChangeItem[N]; 3178 } 3179 mPendingProcessChanges.toArray(mActiveProcessChanges); 3180 mAvailProcessChanges.addAll(mPendingProcessChanges); 3181 mPendingProcessChanges.clear(); 3182 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3183 } 3184 3185 int i = mProcessObservers.beginBroadcast(); 3186 while (i > 0) { 3187 i--; 3188 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3189 if (observer != null) { 3190 try { 3191 for (int j=0; j<N; j++) { 3192 ProcessChangeItem item = mActiveProcessChanges[j]; 3193 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3194 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3195 + item.pid + " uid=" + item.uid + ": " 3196 + item.foregroundActivities); 3197 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3198 item.foregroundActivities); 3199 } 3200 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3201 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3202 + item.pid + " uid=" + item.uid + ": " + item.processState); 3203 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3204 } 3205 } 3206 } catch (RemoteException e) { 3207 } 3208 } 3209 } 3210 mProcessObservers.finishBroadcast(); 3211 } 3212 3213 private void dispatchProcessDied(int pid, int uid) { 3214 int i = mProcessObservers.beginBroadcast(); 3215 while (i > 0) { 3216 i--; 3217 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3218 if (observer != null) { 3219 try { 3220 observer.onProcessDied(pid, uid); 3221 } catch (RemoteException e) { 3222 } 3223 } 3224 } 3225 mProcessObservers.finishBroadcast(); 3226 } 3227 3228 final void doPendingActivityLaunchesLocked(boolean doResume) { 3229 final int N = mPendingActivityLaunches.size(); 3230 if (N <= 0) { 3231 return; 3232 } 3233 for (int i=0; i<N; i++) { 3234 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3235 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3236 doResume && i == (N-1), null); 3237 } 3238 mPendingActivityLaunches.clear(); 3239 } 3240 3241 @Override 3242 public final int startActivity(IApplicationThread caller, String callingPackage, 3243 Intent intent, String resolvedType, IBinder resultTo, 3244 String resultWho, int requestCode, int startFlags, 3245 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3246 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3247 resultWho, requestCode, 3248 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3249 } 3250 3251 @Override 3252 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3253 Intent intent, String resolvedType, IBinder resultTo, 3254 String resultWho, int requestCode, int startFlags, 3255 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3256 enforceNotIsolatedCaller("startActivity"); 3257 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3258 false, true, "startActivity", null); 3259 // TODO: Switch to user app stacks here. 3260 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3261 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3262 null, null, options, userId, null); 3263 } 3264 3265 @Override 3266 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3267 Intent intent, String resolvedType, IBinder resultTo, 3268 String resultWho, int requestCode, int startFlags, String profileFile, 3269 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3270 enforceNotIsolatedCaller("startActivityAndWait"); 3271 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3272 false, true, "startActivityAndWait", null); 3273 WaitResult res = new WaitResult(); 3274 // TODO: Switch to user app stacks here. 3275 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3276 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3277 res, null, options, UserHandle.getCallingUserId(), null); 3278 return res; 3279 } 3280 3281 @Override 3282 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3283 Intent intent, String resolvedType, IBinder resultTo, 3284 String resultWho, int requestCode, int startFlags, Configuration config, 3285 Bundle options, int userId) { 3286 enforceNotIsolatedCaller("startActivityWithConfig"); 3287 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3288 false, true, "startActivityWithConfig", null); 3289 // TODO: Switch to user app stacks here. 3290 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3291 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3292 null, null, null, config, options, userId, null); 3293 return ret; 3294 } 3295 3296 @Override 3297 public int startActivityIntentSender(IApplicationThread caller, 3298 IntentSender intent, Intent fillInIntent, String resolvedType, 3299 IBinder resultTo, String resultWho, int requestCode, 3300 int flagsMask, int flagsValues, Bundle options) { 3301 enforceNotIsolatedCaller("startActivityIntentSender"); 3302 // Refuse possible leaked file descriptors 3303 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3304 throw new IllegalArgumentException("File descriptors passed in Intent"); 3305 } 3306 3307 IIntentSender sender = intent.getTarget(); 3308 if (!(sender instanceof PendingIntentRecord)) { 3309 throw new IllegalArgumentException("Bad PendingIntent object"); 3310 } 3311 3312 PendingIntentRecord pir = (PendingIntentRecord)sender; 3313 3314 synchronized (this) { 3315 // If this is coming from the currently resumed activity, it is 3316 // effectively saying that app switches are allowed at this point. 3317 final ActivityStack stack = getFocusedStack(); 3318 if (stack.mResumedActivity != null && 3319 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3320 mAppSwitchesAllowedTime = 0; 3321 } 3322 } 3323 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3324 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3325 return ret; 3326 } 3327 3328 @Override 3329 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3330 Intent intent, String resolvedType, IVoiceInteractionSession session, 3331 IVoiceInteractor interactor, int startFlags, String profileFile, 3332 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3333 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3334 != PackageManager.PERMISSION_GRANTED) { 3335 String msg = "Permission Denial: startVoiceActivity() from pid=" 3336 + Binder.getCallingPid() 3337 + ", uid=" + Binder.getCallingUid() 3338 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3339 Slog.w(TAG, msg); 3340 throw new SecurityException(msg); 3341 } 3342 if (session == null || interactor == null) { 3343 throw new NullPointerException("null session or interactor"); 3344 } 3345 userId = handleIncomingUser(callingPid, callingUid, userId, 3346 false, true, "startVoiceActivity", null); 3347 // TODO: Switch to user app stacks here. 3348 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3349 resolvedType, session, interactor, null, null, 0, startFlags, 3350 profileFile, profileFd, null, null, options, userId, null); 3351 } 3352 3353 @Override 3354 public boolean startNextMatchingActivity(IBinder callingActivity, 3355 Intent intent, Bundle options) { 3356 // Refuse possible leaked file descriptors 3357 if (intent != null && intent.hasFileDescriptors() == true) { 3358 throw new IllegalArgumentException("File descriptors passed in Intent"); 3359 } 3360 3361 synchronized (this) { 3362 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3363 if (r == null) { 3364 ActivityOptions.abort(options); 3365 return false; 3366 } 3367 if (r.app == null || r.app.thread == null) { 3368 // The caller is not running... d'oh! 3369 ActivityOptions.abort(options); 3370 return false; 3371 } 3372 intent = new Intent(intent); 3373 // The caller is not allowed to change the data. 3374 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3375 // And we are resetting to find the next component... 3376 intent.setComponent(null); 3377 3378 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3379 3380 ActivityInfo aInfo = null; 3381 try { 3382 List<ResolveInfo> resolves = 3383 AppGlobals.getPackageManager().queryIntentActivities( 3384 intent, r.resolvedType, 3385 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3386 UserHandle.getCallingUserId()); 3387 3388 // Look for the original activity in the list... 3389 final int N = resolves != null ? resolves.size() : 0; 3390 for (int i=0; i<N; i++) { 3391 ResolveInfo rInfo = resolves.get(i); 3392 if (rInfo.activityInfo.packageName.equals(r.packageName) 3393 && rInfo.activityInfo.name.equals(r.info.name)) { 3394 // We found the current one... the next matching is 3395 // after it. 3396 i++; 3397 if (i<N) { 3398 aInfo = resolves.get(i).activityInfo; 3399 } 3400 if (debug) { 3401 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3402 + "/" + r.info.name); 3403 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3404 + "/" + aInfo.name); 3405 } 3406 break; 3407 } 3408 } 3409 } catch (RemoteException e) { 3410 } 3411 3412 if (aInfo == null) { 3413 // Nobody who is next! 3414 ActivityOptions.abort(options); 3415 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3416 return false; 3417 } 3418 3419 intent.setComponent(new ComponentName( 3420 aInfo.applicationInfo.packageName, aInfo.name)); 3421 intent.setFlags(intent.getFlags()&~( 3422 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3423 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3424 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3425 Intent.FLAG_ACTIVITY_NEW_TASK)); 3426 3427 // Okay now we need to start the new activity, replacing the 3428 // currently running activity. This is a little tricky because 3429 // we want to start the new one as if the current one is finished, 3430 // but not finish the current one first so that there is no flicker. 3431 // And thus... 3432 final boolean wasFinishing = r.finishing; 3433 r.finishing = true; 3434 3435 // Propagate reply information over to the new activity. 3436 final ActivityRecord resultTo = r.resultTo; 3437 final String resultWho = r.resultWho; 3438 final int requestCode = r.requestCode; 3439 r.resultTo = null; 3440 if (resultTo != null) { 3441 resultTo.removeResultsLocked(r, resultWho, requestCode); 3442 } 3443 3444 final long origId = Binder.clearCallingIdentity(); 3445 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3446 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3447 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3448 options, false, null, null); 3449 Binder.restoreCallingIdentity(origId); 3450 3451 r.finishing = wasFinishing; 3452 if (res != ActivityManager.START_SUCCESS) { 3453 return false; 3454 } 3455 return true; 3456 } 3457 } 3458 3459 final int startActivityInPackage(int uid, String callingPackage, 3460 Intent intent, String resolvedType, IBinder resultTo, 3461 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3462 IActivityContainer container) { 3463 3464 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3465 false, true, "startActivityInPackage", null); 3466 3467 // TODO: Switch to user app stacks here. 3468 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3469 null, null, resultTo, resultWho, requestCode, startFlags, 3470 null, null, null, null, options, userId, container); 3471 return ret; 3472 } 3473 3474 @Override 3475 public final int startActivities(IApplicationThread caller, String callingPackage, 3476 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3477 int userId) { 3478 enforceNotIsolatedCaller("startActivities"); 3479 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3480 false, true, "startActivity", null); 3481 // TODO: Switch to user app stacks here. 3482 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3483 resolvedTypes, resultTo, options, userId); 3484 return ret; 3485 } 3486 3487 final int startActivitiesInPackage(int uid, String callingPackage, 3488 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3489 Bundle options, int userId) { 3490 3491 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3492 false, true, "startActivityInPackage", null); 3493 // TODO: Switch to user app stacks here. 3494 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3495 resultTo, options, userId); 3496 return ret; 3497 } 3498 3499 final void addRecentTaskLocked(TaskRecord task) { 3500 int N = mRecentTasks.size(); 3501 // Quick case: check if the top-most recent task is the same. 3502 if (N > 0 && mRecentTasks.get(0) == task) { 3503 return; 3504 } 3505 // Another quick case: never add voice sessions. 3506 if (task.voiceSession != null) { 3507 return; 3508 } 3509 // Remove any existing entries that are the same kind of task. 3510 final Intent intent = task.intent; 3511 final boolean document = intent != null && intent.isDocument(); 3512 for (int i=0; i<N; i++) { 3513 TaskRecord tr = mRecentTasks.get(i); 3514 if (task != tr) { 3515 if (task.userId != tr.userId) { 3516 continue; 3517 } 3518 final Intent trIntent = tr.intent; 3519 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3520 (intent == null || !intent.filterEquals(trIntent))) { 3521 continue; 3522 } 3523 if (document || trIntent != null && trIntent.isDocument()) { 3524 // Document tasks do not match other tasks. 3525 continue; 3526 } 3527 } 3528 3529 // Either task and tr are the same or, their affinities match or their intents match 3530 // and neither of them is a document. 3531 tr.disposeThumbnail(); 3532 mRecentTasks.remove(i); 3533 i--; 3534 N--; 3535 if (task.intent == null) { 3536 // If the new recent task we are adding is not fully 3537 // specified, then replace it with the existing recent task. 3538 task = tr; 3539 } 3540 } 3541 if (N >= MAX_RECENT_TASKS) { 3542 mRecentTasks.remove(N-1).disposeThumbnail(); 3543 } 3544 mRecentTasks.add(0, task); 3545 } 3546 3547 @Override 3548 public void reportActivityFullyDrawn(IBinder token) { 3549 synchronized (this) { 3550 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3551 if (r == null) { 3552 return; 3553 } 3554 r.reportFullyDrawnLocked(); 3555 } 3556 } 3557 3558 @Override 3559 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3560 synchronized (this) { 3561 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3562 if (r == null) { 3563 return; 3564 } 3565 final long origId = Binder.clearCallingIdentity(); 3566 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3567 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3568 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3569 if (config != null) { 3570 r.frozenBeforeDestroy = true; 3571 if (!updateConfigurationLocked(config, r, false, false)) { 3572 mStackSupervisor.resumeTopActivitiesLocked(); 3573 } 3574 } 3575 Binder.restoreCallingIdentity(origId); 3576 } 3577 } 3578 3579 @Override 3580 public int getRequestedOrientation(IBinder token) { 3581 synchronized (this) { 3582 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3583 if (r == null) { 3584 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3585 } 3586 return mWindowManager.getAppOrientation(r.appToken); 3587 } 3588 } 3589 3590 /** 3591 * This is the internal entry point for handling Activity.finish(). 3592 * 3593 * @param token The Binder token referencing the Activity we want to finish. 3594 * @param resultCode Result code, if any, from this Activity. 3595 * @param resultData Result data (Intent), if any, from this Activity. 3596 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3597 * the root Activity in the task. 3598 * 3599 * @return Returns true if the activity successfully finished, or false if it is still running. 3600 */ 3601 @Override 3602 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3603 boolean finishTask) { 3604 // Refuse possible leaked file descriptors 3605 if (resultData != null && resultData.hasFileDescriptors() == true) { 3606 throw new IllegalArgumentException("File descriptors passed in Intent"); 3607 } 3608 3609 synchronized(this) { 3610 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3611 if (r == null) { 3612 return true; 3613 } 3614 // Keep track of the root activity of the task before we finish it 3615 TaskRecord tr = r.task; 3616 ActivityRecord rootR = tr.getRootActivity(); 3617 if (mController != null) { 3618 // Find the first activity that is not finishing. 3619 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3620 if (next != null) { 3621 // ask watcher if this is allowed 3622 boolean resumeOK = true; 3623 try { 3624 resumeOK = mController.activityResuming(next.packageName); 3625 } catch (RemoteException e) { 3626 mController = null; 3627 Watchdog.getInstance().setActivityController(null); 3628 } 3629 3630 if (!resumeOK) { 3631 return false; 3632 } 3633 } 3634 } 3635 final long origId = Binder.clearCallingIdentity(); 3636 try { 3637 boolean res; 3638 if (finishTask && r == rootR) { 3639 // If requested, remove the task that is associated to this activity only if it 3640 // was the root activity in the task. The result code and data is ignored because 3641 // we don't support returning them across task boundaries. 3642 res = removeTaskByIdLocked(tr.taskId, 0); 3643 } else { 3644 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3645 resultData, "app-request", true); 3646 } 3647 return res; 3648 } finally { 3649 Binder.restoreCallingIdentity(origId); 3650 } 3651 } 3652 } 3653 3654 @Override 3655 public final void finishHeavyWeightApp() { 3656 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3657 != PackageManager.PERMISSION_GRANTED) { 3658 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3659 + Binder.getCallingPid() 3660 + ", uid=" + Binder.getCallingUid() 3661 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3662 Slog.w(TAG, msg); 3663 throw new SecurityException(msg); 3664 } 3665 3666 synchronized(this) { 3667 if (mHeavyWeightProcess == null) { 3668 return; 3669 } 3670 3671 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3672 mHeavyWeightProcess.activities); 3673 for (int i=0; i<activities.size(); i++) { 3674 ActivityRecord r = activities.get(i); 3675 if (!r.finishing) { 3676 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3677 null, "finish-heavy", true); 3678 } 3679 } 3680 3681 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3682 mHeavyWeightProcess.userId, 0)); 3683 mHeavyWeightProcess = null; 3684 } 3685 } 3686 3687 @Override 3688 public void crashApplication(int uid, int initialPid, String packageName, 3689 String message) { 3690 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3691 != PackageManager.PERMISSION_GRANTED) { 3692 String msg = "Permission Denial: crashApplication() from pid=" 3693 + Binder.getCallingPid() 3694 + ", uid=" + Binder.getCallingUid() 3695 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3696 Slog.w(TAG, msg); 3697 throw new SecurityException(msg); 3698 } 3699 3700 synchronized(this) { 3701 ProcessRecord proc = null; 3702 3703 // Figure out which process to kill. We don't trust that initialPid 3704 // still has any relation to current pids, so must scan through the 3705 // list. 3706 synchronized (mPidsSelfLocked) { 3707 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3708 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3709 if (p.uid != uid) { 3710 continue; 3711 } 3712 if (p.pid == initialPid) { 3713 proc = p; 3714 break; 3715 } 3716 if (p.pkgList.containsKey(packageName)) { 3717 proc = p; 3718 } 3719 } 3720 } 3721 3722 if (proc == null) { 3723 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3724 + " initialPid=" + initialPid 3725 + " packageName=" + packageName); 3726 return; 3727 } 3728 3729 if (proc.thread != null) { 3730 if (proc.pid == Process.myPid()) { 3731 Log.w(TAG, "crashApplication: trying to crash self!"); 3732 return; 3733 } 3734 long ident = Binder.clearCallingIdentity(); 3735 try { 3736 proc.thread.scheduleCrash(message); 3737 } catch (RemoteException e) { 3738 } 3739 Binder.restoreCallingIdentity(ident); 3740 } 3741 } 3742 } 3743 3744 @Override 3745 public final void finishSubActivity(IBinder token, String resultWho, 3746 int requestCode) { 3747 synchronized(this) { 3748 final long origId = Binder.clearCallingIdentity(); 3749 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3750 if (r != null) { 3751 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3752 } 3753 Binder.restoreCallingIdentity(origId); 3754 } 3755 } 3756 3757 @Override 3758 public boolean finishActivityAffinity(IBinder token) { 3759 synchronized(this) { 3760 final long origId = Binder.clearCallingIdentity(); 3761 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3762 boolean res = false; 3763 if (r != null) { 3764 res = r.task.stack.finishActivityAffinityLocked(r); 3765 } 3766 Binder.restoreCallingIdentity(origId); 3767 return res; 3768 } 3769 } 3770 3771 @Override 3772 public boolean willActivityBeVisible(IBinder token) { 3773 synchronized(this) { 3774 ActivityStack stack = ActivityRecord.getStackLocked(token); 3775 if (stack != null) { 3776 return stack.willActivityBeVisibleLocked(token); 3777 } 3778 return false; 3779 } 3780 } 3781 3782 @Override 3783 public void overridePendingTransition(IBinder token, String packageName, 3784 int enterAnim, int exitAnim) { 3785 synchronized(this) { 3786 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3787 if (self == null) { 3788 return; 3789 } 3790 3791 final long origId = Binder.clearCallingIdentity(); 3792 3793 if (self.state == ActivityState.RESUMED 3794 || self.state == ActivityState.PAUSING) { 3795 mWindowManager.overridePendingAppTransition(packageName, 3796 enterAnim, exitAnim, null); 3797 } 3798 3799 Binder.restoreCallingIdentity(origId); 3800 } 3801 } 3802 3803 /** 3804 * Main function for removing an existing process from the activity manager 3805 * as a result of that process going away. Clears out all connections 3806 * to the process. 3807 */ 3808 private final void handleAppDiedLocked(ProcessRecord app, 3809 boolean restarting, boolean allowRestart) { 3810 int pid = app.pid; 3811 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3812 if (!restarting) { 3813 removeLruProcessLocked(app); 3814 if (pid > 0) { 3815 ProcessList.remove(pid); 3816 } 3817 } 3818 3819 if (mProfileProc == app) { 3820 clearProfilerLocked(); 3821 } 3822 3823 // Remove this application's activities from active lists. 3824 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3825 3826 app.activities.clear(); 3827 3828 if (app.instrumentationClass != null) { 3829 Slog.w(TAG, "Crash of app " + app.processName 3830 + " running instrumentation " + app.instrumentationClass); 3831 Bundle info = new Bundle(); 3832 info.putString("shortMsg", "Process crashed."); 3833 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3834 } 3835 3836 if (!restarting) { 3837 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3838 // If there was nothing to resume, and we are not already 3839 // restarting this process, but there is a visible activity that 3840 // is hosted by the process... then make sure all visible 3841 // activities are running, taking care of restarting this 3842 // process. 3843 if (hasVisibleActivities) { 3844 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3845 } 3846 } 3847 } 3848 } 3849 3850 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3851 IBinder threadBinder = thread.asBinder(); 3852 // Find the application record. 3853 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3854 ProcessRecord rec = mLruProcesses.get(i); 3855 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3856 return i; 3857 } 3858 } 3859 return -1; 3860 } 3861 3862 final ProcessRecord getRecordForAppLocked( 3863 IApplicationThread thread) { 3864 if (thread == null) { 3865 return null; 3866 } 3867 3868 int appIndex = getLRURecordIndexForAppLocked(thread); 3869 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3870 } 3871 3872 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3873 // If there are no longer any background processes running, 3874 // and the app that died was not running instrumentation, 3875 // then tell everyone we are now low on memory. 3876 boolean haveBg = false; 3877 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3878 ProcessRecord rec = mLruProcesses.get(i); 3879 if (rec.thread != null 3880 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3881 haveBg = true; 3882 break; 3883 } 3884 } 3885 3886 if (!haveBg) { 3887 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3888 if (doReport) { 3889 long now = SystemClock.uptimeMillis(); 3890 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3891 doReport = false; 3892 } else { 3893 mLastMemUsageReportTime = now; 3894 } 3895 } 3896 final ArrayList<ProcessMemInfo> memInfos 3897 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3898 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3899 long now = SystemClock.uptimeMillis(); 3900 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3901 ProcessRecord rec = mLruProcesses.get(i); 3902 if (rec == dyingProc || rec.thread == null) { 3903 continue; 3904 } 3905 if (doReport) { 3906 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3907 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3908 } 3909 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3910 // The low memory report is overriding any current 3911 // state for a GC request. Make sure to do 3912 // heavy/important/visible/foreground processes first. 3913 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3914 rec.lastRequestedGc = 0; 3915 } else { 3916 rec.lastRequestedGc = rec.lastLowMemory; 3917 } 3918 rec.reportLowMemory = true; 3919 rec.lastLowMemory = now; 3920 mProcessesToGc.remove(rec); 3921 addProcessToGcListLocked(rec); 3922 } 3923 } 3924 if (doReport) { 3925 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3926 mHandler.sendMessage(msg); 3927 } 3928 scheduleAppGcsLocked(); 3929 } 3930 } 3931 3932 final void appDiedLocked(ProcessRecord app, int pid, 3933 IApplicationThread thread) { 3934 3935 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3936 synchronized (stats) { 3937 stats.noteProcessDiedLocked(app.info.uid, pid); 3938 } 3939 3940 // Clean up already done if the process has been re-started. 3941 if (app.pid == pid && app.thread != null && 3942 app.thread.asBinder() == thread.asBinder()) { 3943 boolean doLowMem = app.instrumentationClass == null; 3944 boolean doOomAdj = doLowMem; 3945 if (!app.killedByAm) { 3946 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3947 + ") has died."); 3948 mAllowLowerMemLevel = true; 3949 } else { 3950 // Note that we always want to do oom adj to update our state with the 3951 // new number of procs. 3952 mAllowLowerMemLevel = false; 3953 doLowMem = false; 3954 } 3955 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3956 if (DEBUG_CLEANUP) Slog.v( 3957 TAG, "Dying app: " + app + ", pid: " + pid 3958 + ", thread: " + thread.asBinder()); 3959 handleAppDiedLocked(app, false, true); 3960 3961 if (doOomAdj) { 3962 updateOomAdjLocked(); 3963 } 3964 if (doLowMem) { 3965 doLowMemReportIfNeededLocked(app); 3966 } 3967 } else if (app.pid != pid) { 3968 // A new process has already been started. 3969 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3970 + ") has died and restarted (pid " + app.pid + ")."); 3971 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3972 } else if (DEBUG_PROCESSES) { 3973 Slog.d(TAG, "Received spurious death notification for thread " 3974 + thread.asBinder()); 3975 } 3976 } 3977 3978 /** 3979 * If a stack trace dump file is configured, dump process stack traces. 3980 * @param clearTraces causes the dump file to be erased prior to the new 3981 * traces being written, if true; when false, the new traces will be 3982 * appended to any existing file content. 3983 * @param firstPids of dalvik VM processes to dump stack traces for first 3984 * @param lastPids of dalvik VM processes to dump stack traces for last 3985 * @param nativeProcs optional list of native process names to dump stack crawls 3986 * @return file containing stack traces, or null if no dump file is configured 3987 */ 3988 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3989 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3990 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3991 if (tracesPath == null || tracesPath.length() == 0) { 3992 return null; 3993 } 3994 3995 File tracesFile = new File(tracesPath); 3996 try { 3997 File tracesDir = tracesFile.getParentFile(); 3998 if (!tracesDir.exists()) { 3999 tracesFile.mkdirs(); 4000 if (!SELinux.restorecon(tracesDir)) { 4001 return null; 4002 } 4003 } 4004 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4005 4006 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4007 tracesFile.createNewFile(); 4008 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4009 } catch (IOException e) { 4010 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4011 return null; 4012 } 4013 4014 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4015 return tracesFile; 4016 } 4017 4018 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4019 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4020 // Use a FileObserver to detect when traces finish writing. 4021 // The order of traces is considered important to maintain for legibility. 4022 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4023 @Override 4024 public synchronized void onEvent(int event, String path) { notify(); } 4025 }; 4026 4027 try { 4028 observer.startWatching(); 4029 4030 // First collect all of the stacks of the most important pids. 4031 if (firstPids != null) { 4032 try { 4033 int num = firstPids.size(); 4034 for (int i = 0; i < num; i++) { 4035 synchronized (observer) { 4036 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4037 observer.wait(200); // Wait for write-close, give up after 200msec 4038 } 4039 } 4040 } catch (InterruptedException e) { 4041 Log.wtf(TAG, e); 4042 } 4043 } 4044 4045 // Next collect the stacks of the native pids 4046 if (nativeProcs != null) { 4047 int[] pids = Process.getPidsForCommands(nativeProcs); 4048 if (pids != null) { 4049 for (int pid : pids) { 4050 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4051 } 4052 } 4053 } 4054 4055 // Lastly, measure CPU usage. 4056 if (processCpuTracker != null) { 4057 processCpuTracker.init(); 4058 System.gc(); 4059 processCpuTracker.update(); 4060 try { 4061 synchronized (processCpuTracker) { 4062 processCpuTracker.wait(500); // measure over 1/2 second. 4063 } 4064 } catch (InterruptedException e) { 4065 } 4066 processCpuTracker.update(); 4067 4068 // We'll take the stack crawls of just the top apps using CPU. 4069 final int N = processCpuTracker.countWorkingStats(); 4070 int numProcs = 0; 4071 for (int i=0; i<N && numProcs<5; i++) { 4072 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4073 if (lastPids.indexOfKey(stats.pid) >= 0) { 4074 numProcs++; 4075 try { 4076 synchronized (observer) { 4077 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4078 observer.wait(200); // Wait for write-close, give up after 200msec 4079 } 4080 } catch (InterruptedException e) { 4081 Log.wtf(TAG, e); 4082 } 4083 4084 } 4085 } 4086 } 4087 } finally { 4088 observer.stopWatching(); 4089 } 4090 } 4091 4092 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4093 if (true || IS_USER_BUILD) { 4094 return; 4095 } 4096 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4097 if (tracesPath == null || tracesPath.length() == 0) { 4098 return; 4099 } 4100 4101 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4102 StrictMode.allowThreadDiskWrites(); 4103 try { 4104 final File tracesFile = new File(tracesPath); 4105 final File tracesDir = tracesFile.getParentFile(); 4106 final File tracesTmp = new File(tracesDir, "__tmp__"); 4107 try { 4108 if (!tracesDir.exists()) { 4109 tracesFile.mkdirs(); 4110 if (!SELinux.restorecon(tracesDir.getPath())) { 4111 return; 4112 } 4113 } 4114 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4115 4116 if (tracesFile.exists()) { 4117 tracesTmp.delete(); 4118 tracesFile.renameTo(tracesTmp); 4119 } 4120 StringBuilder sb = new StringBuilder(); 4121 Time tobj = new Time(); 4122 tobj.set(System.currentTimeMillis()); 4123 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4124 sb.append(": "); 4125 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4126 sb.append(" since "); 4127 sb.append(msg); 4128 FileOutputStream fos = new FileOutputStream(tracesFile); 4129 fos.write(sb.toString().getBytes()); 4130 if (app == null) { 4131 fos.write("\n*** No application process!".getBytes()); 4132 } 4133 fos.close(); 4134 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4135 } catch (IOException e) { 4136 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4137 return; 4138 } 4139 4140 if (app != null) { 4141 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4142 firstPids.add(app.pid); 4143 dumpStackTraces(tracesPath, firstPids, null, null, null); 4144 } 4145 4146 File lastTracesFile = null; 4147 File curTracesFile = null; 4148 for (int i=9; i>=0; i--) { 4149 String name = String.format(Locale.US, "slow%02d.txt", i); 4150 curTracesFile = new File(tracesDir, name); 4151 if (curTracesFile.exists()) { 4152 if (lastTracesFile != null) { 4153 curTracesFile.renameTo(lastTracesFile); 4154 } else { 4155 curTracesFile.delete(); 4156 } 4157 } 4158 lastTracesFile = curTracesFile; 4159 } 4160 tracesFile.renameTo(curTracesFile); 4161 if (tracesTmp.exists()) { 4162 tracesTmp.renameTo(tracesFile); 4163 } 4164 } finally { 4165 StrictMode.setThreadPolicy(oldPolicy); 4166 } 4167 } 4168 4169 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4170 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4171 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4172 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4173 4174 if (mController != null) { 4175 try { 4176 // 0 == continue, -1 = kill process immediately 4177 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4178 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4179 } catch (RemoteException e) { 4180 mController = null; 4181 Watchdog.getInstance().setActivityController(null); 4182 } 4183 } 4184 4185 long anrTime = SystemClock.uptimeMillis(); 4186 if (MONITOR_CPU_USAGE) { 4187 updateCpuStatsNow(); 4188 } 4189 4190 synchronized (this) { 4191 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4192 if (mShuttingDown) { 4193 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4194 return; 4195 } else if (app.notResponding) { 4196 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4197 return; 4198 } else if (app.crashing) { 4199 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4200 return; 4201 } 4202 4203 // In case we come through here for the same app before completing 4204 // this one, mark as anring now so we will bail out. 4205 app.notResponding = true; 4206 4207 // Log the ANR to the event log. 4208 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4209 app.processName, app.info.flags, annotation); 4210 4211 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4212 firstPids.add(app.pid); 4213 4214 int parentPid = app.pid; 4215 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4216 if (parentPid != app.pid) firstPids.add(parentPid); 4217 4218 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4219 4220 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4221 ProcessRecord r = mLruProcesses.get(i); 4222 if (r != null && r.thread != null) { 4223 int pid = r.pid; 4224 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4225 if (r.persistent) { 4226 firstPids.add(pid); 4227 } else { 4228 lastPids.put(pid, Boolean.TRUE); 4229 } 4230 } 4231 } 4232 } 4233 } 4234 4235 // Log the ANR to the main log. 4236 StringBuilder info = new StringBuilder(); 4237 info.setLength(0); 4238 info.append("ANR in ").append(app.processName); 4239 if (activity != null && activity.shortComponentName != null) { 4240 info.append(" (").append(activity.shortComponentName).append(")"); 4241 } 4242 info.append("\n"); 4243 info.append("PID: ").append(app.pid).append("\n"); 4244 if (annotation != null) { 4245 info.append("Reason: ").append(annotation).append("\n"); 4246 } 4247 if (parent != null && parent != activity) { 4248 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4249 } 4250 4251 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4252 4253 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4254 NATIVE_STACKS_OF_INTEREST); 4255 4256 String cpuInfo = null; 4257 if (MONITOR_CPU_USAGE) { 4258 updateCpuStatsNow(); 4259 synchronized (mProcessCpuThread) { 4260 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4261 } 4262 info.append(processCpuTracker.printCurrentLoad()); 4263 info.append(cpuInfo); 4264 } 4265 4266 info.append(processCpuTracker.printCurrentState(anrTime)); 4267 4268 Slog.e(TAG, info.toString()); 4269 if (tracesFile == null) { 4270 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4271 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4272 } 4273 4274 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4275 cpuInfo, tracesFile, null); 4276 4277 if (mController != null) { 4278 try { 4279 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4280 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4281 if (res != 0) { 4282 if (res < 0 && app.pid != MY_PID) { 4283 Process.killProcess(app.pid); 4284 } else { 4285 synchronized (this) { 4286 mServices.scheduleServiceTimeoutLocked(app); 4287 } 4288 } 4289 return; 4290 } 4291 } catch (RemoteException e) { 4292 mController = null; 4293 Watchdog.getInstance().setActivityController(null); 4294 } 4295 } 4296 4297 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4298 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4299 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4300 4301 synchronized (this) { 4302 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4303 killUnneededProcessLocked(app, "background ANR"); 4304 return; 4305 } 4306 4307 // Set the app's notResponding state, and look up the errorReportReceiver 4308 makeAppNotRespondingLocked(app, 4309 activity != null ? activity.shortComponentName : null, 4310 annotation != null ? "ANR " + annotation : "ANR", 4311 info.toString()); 4312 4313 // Bring up the infamous App Not Responding dialog 4314 Message msg = Message.obtain(); 4315 HashMap<String, Object> map = new HashMap<String, Object>(); 4316 msg.what = SHOW_NOT_RESPONDING_MSG; 4317 msg.obj = map; 4318 msg.arg1 = aboveSystem ? 1 : 0; 4319 map.put("app", app); 4320 if (activity != null) { 4321 map.put("activity", activity); 4322 } 4323 4324 mHandler.sendMessage(msg); 4325 } 4326 } 4327 4328 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4329 if (!mLaunchWarningShown) { 4330 mLaunchWarningShown = true; 4331 mHandler.post(new Runnable() { 4332 @Override 4333 public void run() { 4334 synchronized (ActivityManagerService.this) { 4335 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4336 d.show(); 4337 mHandler.postDelayed(new Runnable() { 4338 @Override 4339 public void run() { 4340 synchronized (ActivityManagerService.this) { 4341 d.dismiss(); 4342 mLaunchWarningShown = false; 4343 } 4344 } 4345 }, 4000); 4346 } 4347 } 4348 }); 4349 } 4350 } 4351 4352 @Override 4353 public boolean clearApplicationUserData(final String packageName, 4354 final IPackageDataObserver observer, int userId) { 4355 enforceNotIsolatedCaller("clearApplicationUserData"); 4356 int uid = Binder.getCallingUid(); 4357 int pid = Binder.getCallingPid(); 4358 userId = handleIncomingUser(pid, uid, 4359 userId, false, true, "clearApplicationUserData", null); 4360 long callingId = Binder.clearCallingIdentity(); 4361 try { 4362 IPackageManager pm = AppGlobals.getPackageManager(); 4363 int pkgUid = -1; 4364 synchronized(this) { 4365 try { 4366 pkgUid = pm.getPackageUid(packageName, userId); 4367 } catch (RemoteException e) { 4368 } 4369 if (pkgUid == -1) { 4370 Slog.w(TAG, "Invalid packageName: " + packageName); 4371 if (observer != null) { 4372 try { 4373 observer.onRemoveCompleted(packageName, false); 4374 } catch (RemoteException e) { 4375 Slog.i(TAG, "Observer no longer exists."); 4376 } 4377 } 4378 return false; 4379 } 4380 if (uid == pkgUid || checkComponentPermission( 4381 android.Manifest.permission.CLEAR_APP_USER_DATA, 4382 pid, uid, -1, true) 4383 == PackageManager.PERMISSION_GRANTED) { 4384 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4385 } else { 4386 throw new SecurityException("PID " + pid + " does not have permission " 4387 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4388 + " of package " + packageName); 4389 } 4390 } 4391 4392 try { 4393 // Clear application user data 4394 pm.clearApplicationUserData(packageName, observer, userId); 4395 4396 // Remove all permissions granted from/to this package 4397 removeUriPermissionsForPackageLocked(packageName, userId, true); 4398 4399 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4400 Uri.fromParts("package", packageName, null)); 4401 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4402 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4403 null, null, 0, null, null, null, false, false, userId); 4404 } catch (RemoteException e) { 4405 } 4406 } finally { 4407 Binder.restoreCallingIdentity(callingId); 4408 } 4409 return true; 4410 } 4411 4412 @Override 4413 public void killBackgroundProcesses(final String packageName, int userId) { 4414 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4415 != PackageManager.PERMISSION_GRANTED && 4416 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4417 != PackageManager.PERMISSION_GRANTED) { 4418 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4419 + Binder.getCallingPid() 4420 + ", uid=" + Binder.getCallingUid() 4421 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4422 Slog.w(TAG, msg); 4423 throw new SecurityException(msg); 4424 } 4425 4426 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4427 userId, true, true, "killBackgroundProcesses", null); 4428 long callingId = Binder.clearCallingIdentity(); 4429 try { 4430 IPackageManager pm = AppGlobals.getPackageManager(); 4431 synchronized(this) { 4432 int appId = -1; 4433 try { 4434 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4435 } catch (RemoteException e) { 4436 } 4437 if (appId == -1) { 4438 Slog.w(TAG, "Invalid packageName: " + packageName); 4439 return; 4440 } 4441 killPackageProcessesLocked(packageName, appId, userId, 4442 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4443 } 4444 } finally { 4445 Binder.restoreCallingIdentity(callingId); 4446 } 4447 } 4448 4449 @Override 4450 public void killAllBackgroundProcesses() { 4451 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4452 != PackageManager.PERMISSION_GRANTED) { 4453 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4454 + Binder.getCallingPid() 4455 + ", uid=" + Binder.getCallingUid() 4456 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4457 Slog.w(TAG, msg); 4458 throw new SecurityException(msg); 4459 } 4460 4461 long callingId = Binder.clearCallingIdentity(); 4462 try { 4463 synchronized(this) { 4464 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4465 final int NP = mProcessNames.getMap().size(); 4466 for (int ip=0; ip<NP; ip++) { 4467 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4468 final int NA = apps.size(); 4469 for (int ia=0; ia<NA; ia++) { 4470 ProcessRecord app = apps.valueAt(ia); 4471 if (app.persistent) { 4472 // we don't kill persistent processes 4473 continue; 4474 } 4475 if (app.removed) { 4476 procs.add(app); 4477 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4478 app.removed = true; 4479 procs.add(app); 4480 } 4481 } 4482 } 4483 4484 int N = procs.size(); 4485 for (int i=0; i<N; i++) { 4486 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4487 } 4488 mAllowLowerMemLevel = true; 4489 updateOomAdjLocked(); 4490 doLowMemReportIfNeededLocked(null); 4491 } 4492 } finally { 4493 Binder.restoreCallingIdentity(callingId); 4494 } 4495 } 4496 4497 @Override 4498 public void forceStopPackage(final String packageName, int userId) { 4499 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4500 != PackageManager.PERMISSION_GRANTED) { 4501 String msg = "Permission Denial: forceStopPackage() from pid=" 4502 + Binder.getCallingPid() 4503 + ", uid=" + Binder.getCallingUid() 4504 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4505 Slog.w(TAG, msg); 4506 throw new SecurityException(msg); 4507 } 4508 final int callingPid = Binder.getCallingPid(); 4509 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4510 userId, true, true, "forceStopPackage", null); 4511 long callingId = Binder.clearCallingIdentity(); 4512 try { 4513 IPackageManager pm = AppGlobals.getPackageManager(); 4514 synchronized(this) { 4515 int[] users = userId == UserHandle.USER_ALL 4516 ? getUsersLocked() : new int[] { userId }; 4517 for (int user : users) { 4518 int pkgUid = -1; 4519 try { 4520 pkgUid = pm.getPackageUid(packageName, user); 4521 } catch (RemoteException e) { 4522 } 4523 if (pkgUid == -1) { 4524 Slog.w(TAG, "Invalid packageName: " + packageName); 4525 continue; 4526 } 4527 try { 4528 pm.setPackageStoppedState(packageName, true, user); 4529 } catch (RemoteException e) { 4530 } catch (IllegalArgumentException e) { 4531 Slog.w(TAG, "Failed trying to unstop package " 4532 + packageName + ": " + e); 4533 } 4534 if (isUserRunningLocked(user, false)) { 4535 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4536 } 4537 } 4538 } 4539 } finally { 4540 Binder.restoreCallingIdentity(callingId); 4541 } 4542 } 4543 4544 /* 4545 * The pkg name and app id have to be specified. 4546 */ 4547 @Override 4548 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4549 if (pkg == null) { 4550 return; 4551 } 4552 // Make sure the uid is valid. 4553 if (appid < 0) { 4554 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4555 return; 4556 } 4557 int callerUid = Binder.getCallingUid(); 4558 // Only the system server can kill an application 4559 if (callerUid == Process.SYSTEM_UID) { 4560 // Post an aysnc message to kill the application 4561 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4562 msg.arg1 = appid; 4563 msg.arg2 = 0; 4564 Bundle bundle = new Bundle(); 4565 bundle.putString("pkg", pkg); 4566 bundle.putString("reason", reason); 4567 msg.obj = bundle; 4568 mHandler.sendMessage(msg); 4569 } else { 4570 throw new SecurityException(callerUid + " cannot kill pkg: " + 4571 pkg); 4572 } 4573 } 4574 4575 @Override 4576 public void closeSystemDialogs(String reason) { 4577 enforceNotIsolatedCaller("closeSystemDialogs"); 4578 4579 final int pid = Binder.getCallingPid(); 4580 final int uid = Binder.getCallingUid(); 4581 final long origId = Binder.clearCallingIdentity(); 4582 try { 4583 synchronized (this) { 4584 // Only allow this from foreground processes, so that background 4585 // applications can't abuse it to prevent system UI from being shown. 4586 if (uid >= Process.FIRST_APPLICATION_UID) { 4587 ProcessRecord proc; 4588 synchronized (mPidsSelfLocked) { 4589 proc = mPidsSelfLocked.get(pid); 4590 } 4591 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4592 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4593 + " from background process " + proc); 4594 return; 4595 } 4596 } 4597 closeSystemDialogsLocked(reason); 4598 } 4599 } finally { 4600 Binder.restoreCallingIdentity(origId); 4601 } 4602 } 4603 4604 void closeSystemDialogsLocked(String reason) { 4605 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4606 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4607 | Intent.FLAG_RECEIVER_FOREGROUND); 4608 if (reason != null) { 4609 intent.putExtra("reason", reason); 4610 } 4611 mWindowManager.closeSystemDialogs(reason); 4612 4613 mStackSupervisor.closeSystemDialogsLocked(); 4614 4615 broadcastIntentLocked(null, null, intent, null, 4616 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4617 Process.SYSTEM_UID, UserHandle.USER_ALL); 4618 } 4619 4620 @Override 4621 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4622 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4623 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4624 for (int i=pids.length-1; i>=0; i--) { 4625 ProcessRecord proc; 4626 int oomAdj; 4627 synchronized (this) { 4628 synchronized (mPidsSelfLocked) { 4629 proc = mPidsSelfLocked.get(pids[i]); 4630 oomAdj = proc != null ? proc.setAdj : 0; 4631 } 4632 } 4633 infos[i] = new Debug.MemoryInfo(); 4634 Debug.getMemoryInfo(pids[i], infos[i]); 4635 if (proc != null) { 4636 synchronized (this) { 4637 if (proc.thread != null && proc.setAdj == oomAdj) { 4638 // Record this for posterity if the process has been stable. 4639 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4640 infos[i].getTotalUss(), false, proc.pkgList); 4641 } 4642 } 4643 } 4644 } 4645 return infos; 4646 } 4647 4648 @Override 4649 public long[] getProcessPss(int[] pids) { 4650 enforceNotIsolatedCaller("getProcessPss"); 4651 long[] pss = new long[pids.length]; 4652 for (int i=pids.length-1; i>=0; i--) { 4653 ProcessRecord proc; 4654 int oomAdj; 4655 synchronized (this) { 4656 synchronized (mPidsSelfLocked) { 4657 proc = mPidsSelfLocked.get(pids[i]); 4658 oomAdj = proc != null ? proc.setAdj : 0; 4659 } 4660 } 4661 long[] tmpUss = new long[1]; 4662 pss[i] = Debug.getPss(pids[i], tmpUss); 4663 if (proc != null) { 4664 synchronized (this) { 4665 if (proc.thread != null && proc.setAdj == oomAdj) { 4666 // Record this for posterity if the process has been stable. 4667 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4668 } 4669 } 4670 } 4671 } 4672 return pss; 4673 } 4674 4675 @Override 4676 public void killApplicationProcess(String processName, int uid) { 4677 if (processName == null) { 4678 return; 4679 } 4680 4681 int callerUid = Binder.getCallingUid(); 4682 // Only the system server can kill an application 4683 if (callerUid == Process.SYSTEM_UID) { 4684 synchronized (this) { 4685 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4686 if (app != null && app.thread != null) { 4687 try { 4688 app.thread.scheduleSuicide(); 4689 } catch (RemoteException e) { 4690 // If the other end already died, then our work here is done. 4691 } 4692 } else { 4693 Slog.w(TAG, "Process/uid not found attempting kill of " 4694 + processName + " / " + uid); 4695 } 4696 } 4697 } else { 4698 throw new SecurityException(callerUid + " cannot kill app process: " + 4699 processName); 4700 } 4701 } 4702 4703 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4704 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4705 false, true, false, false, UserHandle.getUserId(uid), reason); 4706 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4707 Uri.fromParts("package", packageName, null)); 4708 if (!mProcessesReady) { 4709 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4710 | Intent.FLAG_RECEIVER_FOREGROUND); 4711 } 4712 intent.putExtra(Intent.EXTRA_UID, uid); 4713 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4714 broadcastIntentLocked(null, null, intent, 4715 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4716 false, false, 4717 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4718 } 4719 4720 private void forceStopUserLocked(int userId, String reason) { 4721 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4722 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4723 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4724 | Intent.FLAG_RECEIVER_FOREGROUND); 4725 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4726 broadcastIntentLocked(null, null, intent, 4727 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4728 false, false, 4729 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4730 } 4731 4732 private final boolean killPackageProcessesLocked(String packageName, int appId, 4733 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4734 boolean doit, boolean evenPersistent, String reason) { 4735 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4736 4737 // Remove all processes this package may have touched: all with the 4738 // same UID (except for the system or root user), and all whose name 4739 // matches the package name. 4740 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4741 final int NP = mProcessNames.getMap().size(); 4742 for (int ip=0; ip<NP; ip++) { 4743 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4744 final int NA = apps.size(); 4745 for (int ia=0; ia<NA; ia++) { 4746 ProcessRecord app = apps.valueAt(ia); 4747 if (app.persistent && !evenPersistent) { 4748 // we don't kill persistent processes 4749 continue; 4750 } 4751 if (app.removed) { 4752 if (doit) { 4753 procs.add(app); 4754 } 4755 continue; 4756 } 4757 4758 // Skip process if it doesn't meet our oom adj requirement. 4759 if (app.setAdj < minOomAdj) { 4760 continue; 4761 } 4762 4763 // If no package is specified, we call all processes under the 4764 // give user id. 4765 if (packageName == null) { 4766 if (app.userId != userId) { 4767 continue; 4768 } 4769 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4770 continue; 4771 } 4772 // Package has been specified, we want to hit all processes 4773 // that match it. We need to qualify this by the processes 4774 // that are running under the specified app and user ID. 4775 } else { 4776 if (UserHandle.getAppId(app.uid) != appId) { 4777 continue; 4778 } 4779 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4780 continue; 4781 } 4782 if (!app.pkgList.containsKey(packageName)) { 4783 continue; 4784 } 4785 } 4786 4787 // Process has passed all conditions, kill it! 4788 if (!doit) { 4789 return true; 4790 } 4791 app.removed = true; 4792 procs.add(app); 4793 } 4794 } 4795 4796 int N = procs.size(); 4797 for (int i=0; i<N; i++) { 4798 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4799 } 4800 updateOomAdjLocked(); 4801 return N > 0; 4802 } 4803 4804 private final boolean forceStopPackageLocked(String name, int appId, 4805 boolean callerWillRestart, boolean purgeCache, boolean doit, 4806 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4807 int i; 4808 int N; 4809 4810 if (userId == UserHandle.USER_ALL && name == null) { 4811 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4812 } 4813 4814 if (appId < 0 && name != null) { 4815 try { 4816 appId = UserHandle.getAppId( 4817 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4818 } catch (RemoteException e) { 4819 } 4820 } 4821 4822 if (doit) { 4823 if (name != null) { 4824 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4825 + " user=" + userId + ": " + reason); 4826 } else { 4827 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4828 } 4829 4830 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4831 for (int ip=pmap.size()-1; ip>=0; ip--) { 4832 SparseArray<Long> ba = pmap.valueAt(ip); 4833 for (i=ba.size()-1; i>=0; i--) { 4834 boolean remove = false; 4835 final int entUid = ba.keyAt(i); 4836 if (name != null) { 4837 if (userId == UserHandle.USER_ALL) { 4838 if (UserHandle.getAppId(entUid) == appId) { 4839 remove = true; 4840 } 4841 } else { 4842 if (entUid == UserHandle.getUid(userId, appId)) { 4843 remove = true; 4844 } 4845 } 4846 } else if (UserHandle.getUserId(entUid) == userId) { 4847 remove = true; 4848 } 4849 if (remove) { 4850 ba.removeAt(i); 4851 } 4852 } 4853 if (ba.size() == 0) { 4854 pmap.removeAt(ip); 4855 } 4856 } 4857 } 4858 4859 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4860 -100, callerWillRestart, true, doit, evenPersistent, 4861 name == null ? ("stop user " + userId) : ("stop " + name)); 4862 4863 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4864 if (!doit) { 4865 return true; 4866 } 4867 didSomething = true; 4868 } 4869 4870 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4871 if (!doit) { 4872 return true; 4873 } 4874 didSomething = true; 4875 } 4876 4877 if (name == null) { 4878 // Remove all sticky broadcasts from this user. 4879 mStickyBroadcasts.remove(userId); 4880 } 4881 4882 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4883 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4884 userId, providers)) { 4885 if (!doit) { 4886 return true; 4887 } 4888 didSomething = true; 4889 } 4890 N = providers.size(); 4891 for (i=0; i<N; i++) { 4892 removeDyingProviderLocked(null, providers.get(i), true); 4893 } 4894 4895 // Remove transient permissions granted from/to this package/user 4896 removeUriPermissionsForPackageLocked(name, userId, false); 4897 4898 if (name == null || uninstalling) { 4899 // Remove pending intents. For now we only do this when force 4900 // stopping users, because we have some problems when doing this 4901 // for packages -- app widgets are not currently cleaned up for 4902 // such packages, so they can be left with bad pending intents. 4903 if (mIntentSenderRecords.size() > 0) { 4904 Iterator<WeakReference<PendingIntentRecord>> it 4905 = mIntentSenderRecords.values().iterator(); 4906 while (it.hasNext()) { 4907 WeakReference<PendingIntentRecord> wpir = it.next(); 4908 if (wpir == null) { 4909 it.remove(); 4910 continue; 4911 } 4912 PendingIntentRecord pir = wpir.get(); 4913 if (pir == null) { 4914 it.remove(); 4915 continue; 4916 } 4917 if (name == null) { 4918 // Stopping user, remove all objects for the user. 4919 if (pir.key.userId != userId) { 4920 // Not the same user, skip it. 4921 continue; 4922 } 4923 } else { 4924 if (UserHandle.getAppId(pir.uid) != appId) { 4925 // Different app id, skip it. 4926 continue; 4927 } 4928 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4929 // Different user, skip it. 4930 continue; 4931 } 4932 if (!pir.key.packageName.equals(name)) { 4933 // Different package, skip it. 4934 continue; 4935 } 4936 } 4937 if (!doit) { 4938 return true; 4939 } 4940 didSomething = true; 4941 it.remove(); 4942 pir.canceled = true; 4943 if (pir.key.activity != null) { 4944 pir.key.activity.pendingResults.remove(pir.ref); 4945 } 4946 } 4947 } 4948 } 4949 4950 if (doit) { 4951 if (purgeCache && name != null) { 4952 AttributeCache ac = AttributeCache.instance(); 4953 if (ac != null) { 4954 ac.removePackage(name); 4955 } 4956 } 4957 if (mBooted) { 4958 mStackSupervisor.resumeTopActivitiesLocked(); 4959 mStackSupervisor.scheduleIdleLocked(); 4960 } 4961 } 4962 4963 return didSomething; 4964 } 4965 4966 private final boolean removeProcessLocked(ProcessRecord app, 4967 boolean callerWillRestart, boolean allowRestart, String reason) { 4968 final String name = app.processName; 4969 final int uid = app.uid; 4970 if (DEBUG_PROCESSES) Slog.d( 4971 TAG, "Force removing proc " + app.toShortString() + " (" + name 4972 + "/" + uid + ")"); 4973 4974 mProcessNames.remove(name, uid); 4975 mIsolatedProcesses.remove(app.uid); 4976 if (mHeavyWeightProcess == app) { 4977 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4978 mHeavyWeightProcess.userId, 0)); 4979 mHeavyWeightProcess = null; 4980 } 4981 boolean needRestart = false; 4982 if (app.pid > 0 && app.pid != MY_PID) { 4983 int pid = app.pid; 4984 synchronized (mPidsSelfLocked) { 4985 mPidsSelfLocked.remove(pid); 4986 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4987 } 4988 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4989 app.processName, app.info.uid); 4990 if (app.isolated) { 4991 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4992 } 4993 killUnneededProcessLocked(app, reason); 4994 handleAppDiedLocked(app, true, allowRestart); 4995 removeLruProcessLocked(app); 4996 4997 if (app.persistent && !app.isolated) { 4998 if (!callerWillRestart) { 4999 addAppLocked(app.info, false); 5000 } else { 5001 needRestart = true; 5002 } 5003 } 5004 } else { 5005 mRemovedProcesses.add(app); 5006 } 5007 5008 return needRestart; 5009 } 5010 5011 private final void processStartTimedOutLocked(ProcessRecord app) { 5012 final int pid = app.pid; 5013 boolean gone = false; 5014 synchronized (mPidsSelfLocked) { 5015 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5016 if (knownApp != null && knownApp.thread == null) { 5017 mPidsSelfLocked.remove(pid); 5018 gone = true; 5019 } 5020 } 5021 5022 if (gone) { 5023 Slog.w(TAG, "Process " + app + " failed to attach"); 5024 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5025 pid, app.uid, app.processName); 5026 mProcessNames.remove(app.processName, app.uid); 5027 mIsolatedProcesses.remove(app.uid); 5028 if (mHeavyWeightProcess == app) { 5029 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5030 mHeavyWeightProcess.userId, 0)); 5031 mHeavyWeightProcess = null; 5032 } 5033 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5034 app.processName, app.info.uid); 5035 if (app.isolated) { 5036 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5037 } 5038 // Take care of any launching providers waiting for this process. 5039 checkAppInLaunchingProvidersLocked(app, true); 5040 // Take care of any services that are waiting for the process. 5041 mServices.processStartTimedOutLocked(app); 5042 killUnneededProcessLocked(app, "start timeout"); 5043 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5044 Slog.w(TAG, "Unattached app died before backup, skipping"); 5045 try { 5046 IBackupManager bm = IBackupManager.Stub.asInterface( 5047 ServiceManager.getService(Context.BACKUP_SERVICE)); 5048 bm.agentDisconnected(app.info.packageName); 5049 } catch (RemoteException e) { 5050 // Can't happen; the backup manager is local 5051 } 5052 } 5053 if (isPendingBroadcastProcessLocked(pid)) { 5054 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5055 skipPendingBroadcastLocked(pid); 5056 } 5057 } else { 5058 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5059 } 5060 } 5061 5062 private final boolean attachApplicationLocked(IApplicationThread thread, 5063 int pid) { 5064 5065 // Find the application record that is being attached... either via 5066 // the pid if we are running in multiple processes, or just pull the 5067 // next app record if we are emulating process with anonymous threads. 5068 ProcessRecord app; 5069 if (pid != MY_PID && pid >= 0) { 5070 synchronized (mPidsSelfLocked) { 5071 app = mPidsSelfLocked.get(pid); 5072 } 5073 } else { 5074 app = null; 5075 } 5076 5077 if (app == null) { 5078 Slog.w(TAG, "No pending application record for pid " + pid 5079 + " (IApplicationThread " + thread + "); dropping process"); 5080 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5081 if (pid > 0 && pid != MY_PID) { 5082 Process.killProcessQuiet(pid); 5083 } else { 5084 try { 5085 thread.scheduleExit(); 5086 } catch (Exception e) { 5087 // Ignore exceptions. 5088 } 5089 } 5090 return false; 5091 } 5092 5093 // If this application record is still attached to a previous 5094 // process, clean it up now. 5095 if (app.thread != null) { 5096 handleAppDiedLocked(app, true, true); 5097 } 5098 5099 // Tell the process all about itself. 5100 5101 if (localLOGV) Slog.v( 5102 TAG, "Binding process pid " + pid + " to record " + app); 5103 5104 final String processName = app.processName; 5105 try { 5106 AppDeathRecipient adr = new AppDeathRecipient( 5107 app, pid, thread); 5108 thread.asBinder().linkToDeath(adr, 0); 5109 app.deathRecipient = adr; 5110 } catch (RemoteException e) { 5111 app.resetPackageList(mProcessStats); 5112 startProcessLocked(app, "link fail", processName); 5113 return false; 5114 } 5115 5116 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5117 5118 app.makeActive(thread, mProcessStats); 5119 app.curAdj = app.setAdj = -100; 5120 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5121 app.forcingToForeground = null; 5122 updateProcessForegroundLocked(app, false, false); 5123 app.hasShownUi = false; 5124 app.debugging = false; 5125 app.cached = false; 5126 5127 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5128 5129 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5130 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5131 5132 if (!normalMode) { 5133 Slog.i(TAG, "Launching preboot mode app: " + app); 5134 } 5135 5136 if (localLOGV) Slog.v( 5137 TAG, "New app record " + app 5138 + " thread=" + thread.asBinder() + " pid=" + pid); 5139 try { 5140 int testMode = IApplicationThread.DEBUG_OFF; 5141 if (mDebugApp != null && mDebugApp.equals(processName)) { 5142 testMode = mWaitForDebugger 5143 ? IApplicationThread.DEBUG_WAIT 5144 : IApplicationThread.DEBUG_ON; 5145 app.debugging = true; 5146 if (mDebugTransient) { 5147 mDebugApp = mOrigDebugApp; 5148 mWaitForDebugger = mOrigWaitForDebugger; 5149 } 5150 } 5151 String profileFile = app.instrumentationProfileFile; 5152 ParcelFileDescriptor profileFd = null; 5153 boolean profileAutoStop = false; 5154 if (mProfileApp != null && mProfileApp.equals(processName)) { 5155 mProfileProc = app; 5156 profileFile = mProfileFile; 5157 profileFd = mProfileFd; 5158 profileAutoStop = mAutoStopProfiler; 5159 } 5160 boolean enableOpenGlTrace = false; 5161 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5162 enableOpenGlTrace = true; 5163 mOpenGlTraceApp = null; 5164 } 5165 5166 // If the app is being launched for restore or full backup, set it up specially 5167 boolean isRestrictedBackupMode = false; 5168 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5169 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5170 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5171 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5172 } 5173 5174 ensurePackageDexOpt(app.instrumentationInfo != null 5175 ? app.instrumentationInfo.packageName 5176 : app.info.packageName); 5177 if (app.instrumentationClass != null) { 5178 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5179 } 5180 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5181 + processName + " with config " + mConfiguration); 5182 ApplicationInfo appInfo = app.instrumentationInfo != null 5183 ? app.instrumentationInfo : app.info; 5184 app.compat = compatibilityInfoForPackageLocked(appInfo); 5185 if (profileFd != null) { 5186 profileFd = profileFd.dup(); 5187 } 5188 thread.bindApplication(processName, appInfo, providers, 5189 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5190 app.instrumentationArguments, app.instrumentationWatcher, 5191 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5192 isRestrictedBackupMode || !normalMode, app.persistent, 5193 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5194 mCoreSettingsObserver.getCoreSettingsLocked()); 5195 updateLruProcessLocked(app, false, null); 5196 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5197 } catch (Exception e) { 5198 // todo: Yikes! What should we do? For now we will try to 5199 // start another process, but that could easily get us in 5200 // an infinite loop of restarting processes... 5201 Slog.w(TAG, "Exception thrown during bind!", e); 5202 5203 app.resetPackageList(mProcessStats); 5204 app.unlinkDeathRecipient(); 5205 startProcessLocked(app, "bind fail", processName); 5206 return false; 5207 } 5208 5209 // Remove this record from the list of starting applications. 5210 mPersistentStartingProcesses.remove(app); 5211 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5212 "Attach application locked removing on hold: " + app); 5213 mProcessesOnHold.remove(app); 5214 5215 boolean badApp = false; 5216 boolean didSomething = false; 5217 5218 // See if the top visible activity is waiting to run in this process... 5219 if (normalMode) { 5220 try { 5221 if (mStackSupervisor.attachApplicationLocked(app)) { 5222 didSomething = true; 5223 } 5224 } catch (Exception e) { 5225 badApp = true; 5226 } 5227 } 5228 5229 // Find any services that should be running in this process... 5230 if (!badApp) { 5231 try { 5232 didSomething |= mServices.attachApplicationLocked(app, processName); 5233 } catch (Exception e) { 5234 badApp = true; 5235 } 5236 } 5237 5238 // Check if a next-broadcast receiver is in this process... 5239 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5240 try { 5241 didSomething |= sendPendingBroadcastsLocked(app); 5242 } catch (Exception e) { 5243 // If the app died trying to launch the receiver we declare it 'bad' 5244 badApp = true; 5245 } 5246 } 5247 5248 // Check whether the next backup agent is in this process... 5249 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5250 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5251 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5252 try { 5253 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5254 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5255 mBackupTarget.backupMode); 5256 } catch (Exception e) { 5257 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5258 e.printStackTrace(); 5259 } 5260 } 5261 5262 if (badApp) { 5263 // todo: Also need to kill application to deal with all 5264 // kinds of exceptions. 5265 handleAppDiedLocked(app, false, true); 5266 return false; 5267 } 5268 5269 if (!didSomething) { 5270 updateOomAdjLocked(); 5271 } 5272 5273 return true; 5274 } 5275 5276 @Override 5277 public final void attachApplication(IApplicationThread thread) { 5278 synchronized (this) { 5279 int callingPid = Binder.getCallingPid(); 5280 final long origId = Binder.clearCallingIdentity(); 5281 attachApplicationLocked(thread, callingPid); 5282 Binder.restoreCallingIdentity(origId); 5283 } 5284 } 5285 5286 @Override 5287 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5288 final long origId = Binder.clearCallingIdentity(); 5289 synchronized (this) { 5290 ActivityStack stack = ActivityRecord.getStackLocked(token); 5291 if (stack != null) { 5292 ActivityRecord r = 5293 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5294 if (stopProfiling) { 5295 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5296 try { 5297 mProfileFd.close(); 5298 } catch (IOException e) { 5299 } 5300 clearProfilerLocked(); 5301 } 5302 } 5303 } 5304 } 5305 Binder.restoreCallingIdentity(origId); 5306 } 5307 5308 void enableScreenAfterBoot() { 5309 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5310 SystemClock.uptimeMillis()); 5311 mWindowManager.enableScreenAfterBoot(); 5312 5313 synchronized (this) { 5314 updateEventDispatchingLocked(); 5315 } 5316 } 5317 5318 @Override 5319 public void showBootMessage(final CharSequence msg, final boolean always) { 5320 enforceNotIsolatedCaller("showBootMessage"); 5321 mWindowManager.showBootMessage(msg, always); 5322 } 5323 5324 @Override 5325 public void dismissKeyguardOnNextActivity() { 5326 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5327 final long token = Binder.clearCallingIdentity(); 5328 try { 5329 synchronized (this) { 5330 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5331 if (mLockScreenShown) { 5332 mLockScreenShown = false; 5333 comeOutOfSleepIfNeededLocked(); 5334 } 5335 mStackSupervisor.setDismissKeyguard(true); 5336 } 5337 } finally { 5338 Binder.restoreCallingIdentity(token); 5339 } 5340 } 5341 5342 final void finishBooting() { 5343 // Register receivers to handle package update events 5344 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5345 5346 synchronized (this) { 5347 // Ensure that any processes we had put on hold are now started 5348 // up. 5349 final int NP = mProcessesOnHold.size(); 5350 if (NP > 0) { 5351 ArrayList<ProcessRecord> procs = 5352 new ArrayList<ProcessRecord>(mProcessesOnHold); 5353 for (int ip=0; ip<NP; ip++) { 5354 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5355 + procs.get(ip)); 5356 startProcessLocked(procs.get(ip), "on-hold", null); 5357 } 5358 } 5359 5360 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5361 // Start looking for apps that are abusing wake locks. 5362 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5363 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5364 // Tell anyone interested that we are done booting! 5365 SystemProperties.set("sys.boot_completed", "1"); 5366 SystemProperties.set("dev.bootcomplete", "1"); 5367 for (int i=0; i<mStartedUsers.size(); i++) { 5368 UserStartedState uss = mStartedUsers.valueAt(i); 5369 if (uss.mState == UserStartedState.STATE_BOOTING) { 5370 uss.mState = UserStartedState.STATE_RUNNING; 5371 final int userId = mStartedUsers.keyAt(i); 5372 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5373 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5374 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5375 broadcastIntentLocked(null, null, intent, null, 5376 new IIntentReceiver.Stub() { 5377 @Override 5378 public void performReceive(Intent intent, int resultCode, 5379 String data, Bundle extras, boolean ordered, 5380 boolean sticky, int sendingUser) { 5381 synchronized (ActivityManagerService.this) { 5382 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5383 true, false); 5384 } 5385 } 5386 }, 5387 0, null, null, 5388 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5389 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5390 userId); 5391 } 5392 } 5393 scheduleStartProfilesLocked(); 5394 } 5395 } 5396 } 5397 5398 final void ensureBootCompleted() { 5399 boolean booting; 5400 boolean enableScreen; 5401 synchronized (this) { 5402 booting = mBooting; 5403 mBooting = false; 5404 enableScreen = !mBooted; 5405 mBooted = true; 5406 } 5407 5408 if (booting) { 5409 finishBooting(); 5410 } 5411 5412 if (enableScreen) { 5413 enableScreenAfterBoot(); 5414 } 5415 } 5416 5417 @Override 5418 public final void activityResumed(IBinder token) { 5419 final long origId = Binder.clearCallingIdentity(); 5420 synchronized(this) { 5421 ActivityStack stack = ActivityRecord.getStackLocked(token); 5422 if (stack != null) { 5423 ActivityRecord.activityResumedLocked(token); 5424 } 5425 } 5426 Binder.restoreCallingIdentity(origId); 5427 } 5428 5429 @Override 5430 public final void activityPaused(IBinder token) { 5431 final long origId = Binder.clearCallingIdentity(); 5432 synchronized(this) { 5433 ActivityStack stack = ActivityRecord.getStackLocked(token); 5434 if (stack != null) { 5435 stack.activityPausedLocked(token, false); 5436 } 5437 } 5438 Binder.restoreCallingIdentity(origId); 5439 } 5440 5441 @Override 5442 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5443 CharSequence description) { 5444 if (localLOGV) Slog.v( 5445 TAG, "Activity stopped: token=" + token); 5446 5447 // Refuse possible leaked file descriptors 5448 if (icicle != null && icicle.hasFileDescriptors()) { 5449 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5450 } 5451 5452 final long origId = Binder.clearCallingIdentity(); 5453 5454 synchronized (this) { 5455 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5456 if (r != null) { 5457 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5458 } 5459 } 5460 5461 trimApplications(); 5462 5463 Binder.restoreCallingIdentity(origId); 5464 } 5465 5466 @Override 5467 public final void activityDestroyed(IBinder token) { 5468 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5469 synchronized (this) { 5470 ActivityStack stack = ActivityRecord.getStackLocked(token); 5471 if (stack != null) { 5472 stack.activityDestroyedLocked(token); 5473 } 5474 } 5475 } 5476 5477 @Override 5478 public String getCallingPackage(IBinder token) { 5479 synchronized (this) { 5480 ActivityRecord r = getCallingRecordLocked(token); 5481 return r != null ? r.info.packageName : null; 5482 } 5483 } 5484 5485 @Override 5486 public ComponentName getCallingActivity(IBinder token) { 5487 synchronized (this) { 5488 ActivityRecord r = getCallingRecordLocked(token); 5489 return r != null ? r.intent.getComponent() : null; 5490 } 5491 } 5492 5493 private ActivityRecord getCallingRecordLocked(IBinder token) { 5494 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5495 if (r == null) { 5496 return null; 5497 } 5498 return r.resultTo; 5499 } 5500 5501 @Override 5502 public ComponentName getActivityClassForToken(IBinder token) { 5503 synchronized(this) { 5504 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5505 if (r == null) { 5506 return null; 5507 } 5508 return r.intent.getComponent(); 5509 } 5510 } 5511 5512 @Override 5513 public String getPackageForToken(IBinder token) { 5514 synchronized(this) { 5515 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5516 if (r == null) { 5517 return null; 5518 } 5519 return r.packageName; 5520 } 5521 } 5522 5523 @Override 5524 public IIntentSender getIntentSender(int type, 5525 String packageName, IBinder token, String resultWho, 5526 int requestCode, Intent[] intents, String[] resolvedTypes, 5527 int flags, Bundle options, int userId) { 5528 enforceNotIsolatedCaller("getIntentSender"); 5529 // Refuse possible leaked file descriptors 5530 if (intents != null) { 5531 if (intents.length < 1) { 5532 throw new IllegalArgumentException("Intents array length must be >= 1"); 5533 } 5534 for (int i=0; i<intents.length; i++) { 5535 Intent intent = intents[i]; 5536 if (intent != null) { 5537 if (intent.hasFileDescriptors()) { 5538 throw new IllegalArgumentException("File descriptors passed in Intent"); 5539 } 5540 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5541 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5542 throw new IllegalArgumentException( 5543 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5544 } 5545 intents[i] = new Intent(intent); 5546 } 5547 } 5548 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5549 throw new IllegalArgumentException( 5550 "Intent array length does not match resolvedTypes length"); 5551 } 5552 } 5553 if (options != null) { 5554 if (options.hasFileDescriptors()) { 5555 throw new IllegalArgumentException("File descriptors passed in options"); 5556 } 5557 } 5558 5559 synchronized(this) { 5560 int callingUid = Binder.getCallingUid(); 5561 int origUserId = userId; 5562 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5563 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5564 "getIntentSender", null); 5565 if (origUserId == UserHandle.USER_CURRENT) { 5566 // We don't want to evaluate this until the pending intent is 5567 // actually executed. However, we do want to always do the 5568 // security checking for it above. 5569 userId = UserHandle.USER_CURRENT; 5570 } 5571 try { 5572 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5573 int uid = AppGlobals.getPackageManager() 5574 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5575 if (!UserHandle.isSameApp(callingUid, uid)) { 5576 String msg = "Permission Denial: getIntentSender() from pid=" 5577 + Binder.getCallingPid() 5578 + ", uid=" + Binder.getCallingUid() 5579 + ", (need uid=" + uid + ")" 5580 + " is not allowed to send as package " + packageName; 5581 Slog.w(TAG, msg); 5582 throw new SecurityException(msg); 5583 } 5584 } 5585 5586 return getIntentSenderLocked(type, packageName, callingUid, userId, 5587 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5588 5589 } catch (RemoteException e) { 5590 throw new SecurityException(e); 5591 } 5592 } 5593 } 5594 5595 IIntentSender getIntentSenderLocked(int type, String packageName, 5596 int callingUid, int userId, IBinder token, String resultWho, 5597 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5598 Bundle options) { 5599 if (DEBUG_MU) 5600 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5601 ActivityRecord activity = null; 5602 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5603 activity = ActivityRecord.isInStackLocked(token); 5604 if (activity == null) { 5605 return null; 5606 } 5607 if (activity.finishing) { 5608 return null; 5609 } 5610 } 5611 5612 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5613 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5614 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5615 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5616 |PendingIntent.FLAG_UPDATE_CURRENT); 5617 5618 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5619 type, packageName, activity, resultWho, 5620 requestCode, intents, resolvedTypes, flags, options, userId); 5621 WeakReference<PendingIntentRecord> ref; 5622 ref = mIntentSenderRecords.get(key); 5623 PendingIntentRecord rec = ref != null ? ref.get() : null; 5624 if (rec != null) { 5625 if (!cancelCurrent) { 5626 if (updateCurrent) { 5627 if (rec.key.requestIntent != null) { 5628 rec.key.requestIntent.replaceExtras(intents != null ? 5629 intents[intents.length - 1] : null); 5630 } 5631 if (intents != null) { 5632 intents[intents.length-1] = rec.key.requestIntent; 5633 rec.key.allIntents = intents; 5634 rec.key.allResolvedTypes = resolvedTypes; 5635 } else { 5636 rec.key.allIntents = null; 5637 rec.key.allResolvedTypes = null; 5638 } 5639 } 5640 return rec; 5641 } 5642 rec.canceled = true; 5643 mIntentSenderRecords.remove(key); 5644 } 5645 if (noCreate) { 5646 return rec; 5647 } 5648 rec = new PendingIntentRecord(this, key, callingUid); 5649 mIntentSenderRecords.put(key, rec.ref); 5650 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5651 if (activity.pendingResults == null) { 5652 activity.pendingResults 5653 = new HashSet<WeakReference<PendingIntentRecord>>(); 5654 } 5655 activity.pendingResults.add(rec.ref); 5656 } 5657 return rec; 5658 } 5659 5660 @Override 5661 public void cancelIntentSender(IIntentSender sender) { 5662 if (!(sender instanceof PendingIntentRecord)) { 5663 return; 5664 } 5665 synchronized(this) { 5666 PendingIntentRecord rec = (PendingIntentRecord)sender; 5667 try { 5668 int uid = AppGlobals.getPackageManager() 5669 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5670 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5671 String msg = "Permission Denial: cancelIntentSender() from pid=" 5672 + Binder.getCallingPid() 5673 + ", uid=" + Binder.getCallingUid() 5674 + " is not allowed to cancel packges " 5675 + rec.key.packageName; 5676 Slog.w(TAG, msg); 5677 throw new SecurityException(msg); 5678 } 5679 } catch (RemoteException e) { 5680 throw new SecurityException(e); 5681 } 5682 cancelIntentSenderLocked(rec, true); 5683 } 5684 } 5685 5686 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5687 rec.canceled = true; 5688 mIntentSenderRecords.remove(rec.key); 5689 if (cleanActivity && rec.key.activity != null) { 5690 rec.key.activity.pendingResults.remove(rec.ref); 5691 } 5692 } 5693 5694 @Override 5695 public String getPackageForIntentSender(IIntentSender pendingResult) { 5696 if (!(pendingResult instanceof PendingIntentRecord)) { 5697 return null; 5698 } 5699 try { 5700 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5701 return res.key.packageName; 5702 } catch (ClassCastException e) { 5703 } 5704 return null; 5705 } 5706 5707 @Override 5708 public int getUidForIntentSender(IIntentSender sender) { 5709 if (sender instanceof PendingIntentRecord) { 5710 try { 5711 PendingIntentRecord res = (PendingIntentRecord)sender; 5712 return res.uid; 5713 } catch (ClassCastException e) { 5714 } 5715 } 5716 return -1; 5717 } 5718 5719 @Override 5720 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5721 if (!(pendingResult instanceof PendingIntentRecord)) { 5722 return false; 5723 } 5724 try { 5725 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5726 if (res.key.allIntents == null) { 5727 return false; 5728 } 5729 for (int i=0; i<res.key.allIntents.length; i++) { 5730 Intent intent = res.key.allIntents[i]; 5731 if (intent.getPackage() != null && intent.getComponent() != null) { 5732 return false; 5733 } 5734 } 5735 return true; 5736 } catch (ClassCastException e) { 5737 } 5738 return false; 5739 } 5740 5741 @Override 5742 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5743 if (!(pendingResult instanceof PendingIntentRecord)) { 5744 return false; 5745 } 5746 try { 5747 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5748 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5749 return true; 5750 } 5751 return false; 5752 } catch (ClassCastException e) { 5753 } 5754 return false; 5755 } 5756 5757 @Override 5758 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5759 if (!(pendingResult instanceof PendingIntentRecord)) { 5760 return null; 5761 } 5762 try { 5763 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5764 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5765 } catch (ClassCastException e) { 5766 } 5767 return null; 5768 } 5769 5770 @Override 5771 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5772 if (!(pendingResult instanceof PendingIntentRecord)) { 5773 return null; 5774 } 5775 try { 5776 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5777 Intent intent = res.key.requestIntent; 5778 if (intent != null) { 5779 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5780 || res.lastTagPrefix.equals(prefix))) { 5781 return res.lastTag; 5782 } 5783 res.lastTagPrefix = prefix; 5784 StringBuilder sb = new StringBuilder(128); 5785 if (prefix != null) { 5786 sb.append(prefix); 5787 } 5788 if (intent.getAction() != null) { 5789 sb.append(intent.getAction()); 5790 } else if (intent.getComponent() != null) { 5791 intent.getComponent().appendShortString(sb); 5792 } else { 5793 sb.append("?"); 5794 } 5795 return res.lastTag = sb.toString(); 5796 } 5797 } catch (ClassCastException e) { 5798 } 5799 return null; 5800 } 5801 5802 @Override 5803 public void setProcessLimit(int max) { 5804 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5805 "setProcessLimit()"); 5806 synchronized (this) { 5807 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5808 mProcessLimitOverride = max; 5809 } 5810 trimApplications(); 5811 } 5812 5813 @Override 5814 public int getProcessLimit() { 5815 synchronized (this) { 5816 return mProcessLimitOverride; 5817 } 5818 } 5819 5820 void foregroundTokenDied(ForegroundToken token) { 5821 synchronized (ActivityManagerService.this) { 5822 synchronized (mPidsSelfLocked) { 5823 ForegroundToken cur 5824 = mForegroundProcesses.get(token.pid); 5825 if (cur != token) { 5826 return; 5827 } 5828 mForegroundProcesses.remove(token.pid); 5829 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5830 if (pr == null) { 5831 return; 5832 } 5833 pr.forcingToForeground = null; 5834 updateProcessForegroundLocked(pr, false, false); 5835 } 5836 updateOomAdjLocked(); 5837 } 5838 } 5839 5840 @Override 5841 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5842 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5843 "setProcessForeground()"); 5844 synchronized(this) { 5845 boolean changed = false; 5846 5847 synchronized (mPidsSelfLocked) { 5848 ProcessRecord pr = mPidsSelfLocked.get(pid); 5849 if (pr == null && isForeground) { 5850 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5851 return; 5852 } 5853 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5854 if (oldToken != null) { 5855 oldToken.token.unlinkToDeath(oldToken, 0); 5856 mForegroundProcesses.remove(pid); 5857 if (pr != null) { 5858 pr.forcingToForeground = null; 5859 } 5860 changed = true; 5861 } 5862 if (isForeground && token != null) { 5863 ForegroundToken newToken = new ForegroundToken() { 5864 @Override 5865 public void binderDied() { 5866 foregroundTokenDied(this); 5867 } 5868 }; 5869 newToken.pid = pid; 5870 newToken.token = token; 5871 try { 5872 token.linkToDeath(newToken, 0); 5873 mForegroundProcesses.put(pid, newToken); 5874 pr.forcingToForeground = token; 5875 changed = true; 5876 } catch (RemoteException e) { 5877 // If the process died while doing this, we will later 5878 // do the cleanup with the process death link. 5879 } 5880 } 5881 } 5882 5883 if (changed) { 5884 updateOomAdjLocked(); 5885 } 5886 } 5887 } 5888 5889 // ========================================================= 5890 // PERMISSIONS 5891 // ========================================================= 5892 5893 static class PermissionController extends IPermissionController.Stub { 5894 ActivityManagerService mActivityManagerService; 5895 PermissionController(ActivityManagerService activityManagerService) { 5896 mActivityManagerService = activityManagerService; 5897 } 5898 5899 @Override 5900 public boolean checkPermission(String permission, int pid, int uid) { 5901 return mActivityManagerService.checkPermission(permission, pid, 5902 uid) == PackageManager.PERMISSION_GRANTED; 5903 } 5904 } 5905 5906 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5907 @Override 5908 public int checkComponentPermission(String permission, int pid, int uid, 5909 int owningUid, boolean exported) { 5910 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5911 owningUid, exported); 5912 } 5913 5914 @Override 5915 public Object getAMSLock() { 5916 return ActivityManagerService.this; 5917 } 5918 } 5919 5920 /** 5921 * This can be called with or without the global lock held. 5922 */ 5923 int checkComponentPermission(String permission, int pid, int uid, 5924 int owningUid, boolean exported) { 5925 // We might be performing an operation on behalf of an indirect binder 5926 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5927 // client identity accordingly before proceeding. 5928 Identity tlsIdentity = sCallerIdentity.get(); 5929 if (tlsIdentity != null) { 5930 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5931 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5932 uid = tlsIdentity.uid; 5933 pid = tlsIdentity.pid; 5934 } 5935 5936 if (pid == MY_PID) { 5937 return PackageManager.PERMISSION_GRANTED; 5938 } 5939 5940 return ActivityManager.checkComponentPermission(permission, uid, 5941 owningUid, exported); 5942 } 5943 5944 /** 5945 * As the only public entry point for permissions checking, this method 5946 * can enforce the semantic that requesting a check on a null global 5947 * permission is automatically denied. (Internally a null permission 5948 * string is used when calling {@link #checkComponentPermission} in cases 5949 * when only uid-based security is needed.) 5950 * 5951 * This can be called with or without the global lock held. 5952 */ 5953 @Override 5954 public int checkPermission(String permission, int pid, int uid) { 5955 if (permission == null) { 5956 return PackageManager.PERMISSION_DENIED; 5957 } 5958 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5959 } 5960 5961 /** 5962 * Binder IPC calls go through the public entry point. 5963 * This can be called with or without the global lock held. 5964 */ 5965 int checkCallingPermission(String permission) { 5966 return checkPermission(permission, 5967 Binder.getCallingPid(), 5968 UserHandle.getAppId(Binder.getCallingUid())); 5969 } 5970 5971 /** 5972 * This can be called with or without the global lock held. 5973 */ 5974 void enforceCallingPermission(String permission, String func) { 5975 if (checkCallingPermission(permission) 5976 == PackageManager.PERMISSION_GRANTED) { 5977 return; 5978 } 5979 5980 String msg = "Permission Denial: " + func + " from pid=" 5981 + Binder.getCallingPid() 5982 + ", uid=" + Binder.getCallingUid() 5983 + " requires " + permission; 5984 Slog.w(TAG, msg); 5985 throw new SecurityException(msg); 5986 } 5987 5988 /** 5989 * Determine if UID is holding permissions required to access {@link Uri} in 5990 * the given {@link ProviderInfo}. Final permission checking is always done 5991 * in {@link ContentProvider}. 5992 */ 5993 private final boolean checkHoldingPermissionsLocked( 5994 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) { 5995 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5996 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5997 5998 if (pi.applicationInfo.uid == uid) { 5999 return true; 6000 } else if (!pi.exported) { 6001 return false; 6002 } 6003 6004 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6005 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6006 try { 6007 // check if target holds top-level <provider> permissions 6008 if (!readMet && pi.readPermission != null 6009 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6010 readMet = true; 6011 } 6012 if (!writeMet && pi.writePermission != null 6013 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6014 writeMet = true; 6015 } 6016 6017 // track if unprotected read/write is allowed; any denied 6018 // <path-permission> below removes this ability 6019 boolean allowDefaultRead = pi.readPermission == null; 6020 boolean allowDefaultWrite = pi.writePermission == null; 6021 6022 // check if target holds any <path-permission> that match uri 6023 final PathPermission[] pps = pi.pathPermissions; 6024 if (pps != null) { 6025 final String path = uri.getPath(); 6026 int i = pps.length; 6027 while (i > 0 && (!readMet || !writeMet)) { 6028 i--; 6029 PathPermission pp = pps[i]; 6030 if (pp.match(path)) { 6031 if (!readMet) { 6032 final String pprperm = pp.getReadPermission(); 6033 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6034 + pprperm + " for " + pp.getPath() 6035 + ": match=" + pp.match(path) 6036 + " check=" + pm.checkUidPermission(pprperm, uid)); 6037 if (pprperm != null) { 6038 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 6039 readMet = true; 6040 } else { 6041 allowDefaultRead = false; 6042 } 6043 } 6044 } 6045 if (!writeMet) { 6046 final String ppwperm = pp.getWritePermission(); 6047 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6048 + ppwperm + " for " + pp.getPath() 6049 + ": match=" + pp.match(path) 6050 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6051 if (ppwperm != null) { 6052 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 6053 writeMet = true; 6054 } else { 6055 allowDefaultWrite = false; 6056 } 6057 } 6058 } 6059 } 6060 } 6061 } 6062 6063 // grant unprotected <provider> read/write, if not blocked by 6064 // <path-permission> above 6065 if (allowDefaultRead) readMet = true; 6066 if (allowDefaultWrite) writeMet = true; 6067 6068 } catch (RemoteException e) { 6069 return false; 6070 } 6071 6072 return readMet && writeMet; 6073 } 6074 6075 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6076 ProviderInfo pi = null; 6077 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6078 if (cpr != null) { 6079 pi = cpr.info; 6080 } else { 6081 try { 6082 pi = AppGlobals.getPackageManager().resolveContentProvider( 6083 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6084 } catch (RemoteException ex) { 6085 } 6086 } 6087 return pi; 6088 } 6089 6090 private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) { 6091 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6092 if (targetUris != null) { 6093 return targetUris.get(uri); 6094 } 6095 return null; 6096 } 6097 6098 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6099 String targetPkg, int targetUid, GrantUri uri) { 6100 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6101 if (targetUris == null) { 6102 targetUris = Maps.newArrayMap(); 6103 mGrantedUriPermissions.put(targetUid, targetUris); 6104 } 6105 6106 UriPermission perm = targetUris.get(uri); 6107 if (perm == null) { 6108 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 6109 targetUris.put(uri, perm); 6110 } 6111 6112 return perm; 6113 } 6114 6115 private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) { 6116 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6117 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6118 : UriPermission.STRENGTH_OWNED; 6119 6120 // Root gets to do everything. 6121 if (uid == 0) { 6122 return true; 6123 } 6124 6125 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6126 if (perms == null) return false; 6127 6128 // First look for exact match 6129 final UriPermission exactPerm = perms.get(new GrantUri(uri, false)); 6130 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6131 return true; 6132 } 6133 6134 // No exact match, look for prefixes 6135 final int N = perms.size(); 6136 for (int i = 0; i < N; i++) { 6137 final UriPermission perm = perms.valueAt(i); 6138 if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri) 6139 && perm.getStrength(modeFlags) >= minStrength) { 6140 return true; 6141 } 6142 } 6143 6144 return false; 6145 } 6146 6147 @Override 6148 public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) { 6149 enforceNotIsolatedCaller("checkUriPermission"); 6150 6151 // Another redirected-binder-call permissions check as in 6152 // {@link checkComponentPermission}. 6153 Identity tlsIdentity = sCallerIdentity.get(); 6154 if (tlsIdentity != null) { 6155 uid = tlsIdentity.uid; 6156 pid = tlsIdentity.pid; 6157 } 6158 6159 // Our own process gets to do everything. 6160 if (pid == MY_PID) { 6161 return PackageManager.PERMISSION_GRANTED; 6162 } 6163 synchronized (this) { 6164 return checkUriPermissionLocked(uri, uid, modeFlags) 6165 ? PackageManager.PERMISSION_GRANTED 6166 : PackageManager.PERMISSION_DENIED; 6167 } 6168 } 6169 6170 /** 6171 * Check if the targetPkg can be granted permission to access uri by 6172 * the callingUid using the given modeFlags. Throws a security exception 6173 * if callingUid is not allowed to do this. Returns the uid of the target 6174 * if the URI permission grant should be performed; returns -1 if it is not 6175 * needed (for example targetPkg already has permission to access the URI). 6176 * If you already know the uid of the target, you can supply it in 6177 * lastTargetUid else set that to -1. 6178 */ 6179 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 6180 Uri uri, final int modeFlags, int lastTargetUid) { 6181 if (!Intent.isAccessUriMode(modeFlags)) { 6182 return -1; 6183 } 6184 6185 if (targetPkg != null) { 6186 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6187 "Checking grant " + targetPkg + " permission to " + uri); 6188 } 6189 6190 final IPackageManager pm = AppGlobals.getPackageManager(); 6191 6192 // If this is not a content: uri, we can't do anything with it. 6193 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 6194 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6195 "Can't grant URI permission for non-content URI: " + uri); 6196 return -1; 6197 } 6198 6199 final String authority = uri.getAuthority(); 6200 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6201 if (pi == null) { 6202 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 6203 return -1; 6204 } 6205 6206 int targetUid = lastTargetUid; 6207 if (targetUid < 0 && targetPkg != null) { 6208 try { 6209 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6210 if (targetUid < 0) { 6211 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6212 "Can't grant URI permission no uid for: " + targetPkg); 6213 return -1; 6214 } 6215 } catch (RemoteException ex) { 6216 return -1; 6217 } 6218 } 6219 6220 if (targetUid >= 0) { 6221 // First... does the target actually need this permission? 6222 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 6223 // No need to grant the target this permission. 6224 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6225 "Target " + targetPkg + " already has full permission to " + uri); 6226 return -1; 6227 } 6228 } else { 6229 // First... there is no target package, so can anyone access it? 6230 boolean allowed = pi.exported; 6231 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6232 if (pi.readPermission != null) { 6233 allowed = false; 6234 } 6235 } 6236 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6237 if (pi.writePermission != null) { 6238 allowed = false; 6239 } 6240 } 6241 if (allowed) { 6242 return -1; 6243 } 6244 } 6245 6246 // Second... is the provider allowing granting of URI permissions? 6247 if (!pi.grantUriPermissions) { 6248 throw new SecurityException("Provider " + pi.packageName 6249 + "/" + pi.name 6250 + " does not allow granting of Uri permissions (uri " 6251 + uri + ")"); 6252 } 6253 if (pi.uriPermissionPatterns != null) { 6254 final int N = pi.uriPermissionPatterns.length; 6255 boolean allowed = false; 6256 for (int i=0; i<N; i++) { 6257 if (pi.uriPermissionPatterns[i] != null 6258 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6259 allowed = true; 6260 break; 6261 } 6262 } 6263 if (!allowed) { 6264 throw new SecurityException("Provider " + pi.packageName 6265 + "/" + pi.name 6266 + " does not allow granting of permission to path of Uri " 6267 + uri); 6268 } 6269 } 6270 6271 // Third... does the caller itself have permission to access 6272 // this uri? 6273 if (callingUid != Process.myUid()) { 6274 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6275 // Require they hold a strong enough Uri permission 6276 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6277 throw new SecurityException("Uid " + callingUid 6278 + " does not have permission to uri " + uri); 6279 } 6280 } 6281 } 6282 6283 return targetUid; 6284 } 6285 6286 @Override 6287 public int checkGrantUriPermission(int callingUid, String targetPkg, 6288 Uri uri, final int modeFlags) { 6289 enforceNotIsolatedCaller("checkGrantUriPermission"); 6290 synchronized(this) { 6291 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6292 } 6293 } 6294 6295 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri, 6296 final int modeFlags, UriPermissionOwner owner) { 6297 if (!Intent.isAccessUriMode(modeFlags)) { 6298 return; 6299 } 6300 6301 // So here we are: the caller has the assumed permission 6302 // to the uri, and the target doesn't. Let's now give this to 6303 // the target. 6304 6305 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6306 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6307 6308 final String authority = uri.getAuthority(); 6309 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6310 if (pi == null) { 6311 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6312 return; 6313 } 6314 6315 final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0; 6316 final UriPermission perm = findOrCreateUriPermissionLocked( 6317 pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix)); 6318 perm.grantModes(modeFlags, owner); 6319 } 6320 6321 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6322 final int modeFlags, UriPermissionOwner owner) { 6323 if (targetPkg == null) { 6324 throw new NullPointerException("targetPkg"); 6325 } 6326 6327 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6328 if (targetUid < 0) { 6329 return; 6330 } 6331 6332 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6333 } 6334 6335 static class NeededUriGrants extends ArrayList<Uri> { 6336 final String targetPkg; 6337 final int targetUid; 6338 final int flags; 6339 6340 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6341 this.targetPkg = targetPkg; 6342 this.targetUid = targetUid; 6343 this.flags = flags; 6344 } 6345 } 6346 6347 /** 6348 * Like checkGrantUriPermissionLocked, but takes an Intent. 6349 */ 6350 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6351 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6352 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6353 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6354 + " clip=" + (intent != null ? intent.getClipData() : null) 6355 + " from " + intent + "; flags=0x" 6356 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6357 6358 if (targetPkg == null) { 6359 throw new NullPointerException("targetPkg"); 6360 } 6361 6362 if (intent == null) { 6363 return null; 6364 } 6365 Uri data = intent.getData(); 6366 ClipData clip = intent.getClipData(); 6367 if (data == null && clip == null) { 6368 return null; 6369 } 6370 6371 if (data != null) { 6372 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6373 mode, needed != null ? needed.targetUid : -1); 6374 if (targetUid > 0) { 6375 if (needed == null) { 6376 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6377 } 6378 needed.add(data); 6379 } 6380 } 6381 if (clip != null) { 6382 for (int i=0; i<clip.getItemCount(); i++) { 6383 Uri uri = clip.getItemAt(i).getUri(); 6384 if (uri != null) { 6385 int targetUid = -1; 6386 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6387 mode, needed != null ? needed.targetUid : -1); 6388 if (targetUid > 0) { 6389 if (needed == null) { 6390 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6391 } 6392 needed.add(uri); 6393 } 6394 } else { 6395 Intent clipIntent = clip.getItemAt(i).getIntent(); 6396 if (clipIntent != null) { 6397 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6398 callingUid, targetPkg, clipIntent, mode, needed); 6399 if (newNeeded != null) { 6400 needed = newNeeded; 6401 } 6402 } 6403 } 6404 } 6405 } 6406 6407 return needed; 6408 } 6409 6410 /** 6411 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6412 */ 6413 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6414 UriPermissionOwner owner) { 6415 if (needed != null) { 6416 for (int i=0; i<needed.size(); i++) { 6417 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6418 needed.get(i), needed.flags, owner); 6419 } 6420 } 6421 } 6422 6423 void grantUriPermissionFromIntentLocked(int callingUid, 6424 String targetPkg, Intent intent, UriPermissionOwner owner) { 6425 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6426 intent, intent != null ? intent.getFlags() : 0, null); 6427 if (needed == null) { 6428 return; 6429 } 6430 6431 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6432 } 6433 6434 @Override 6435 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6436 Uri uri, final int modeFlags) { 6437 enforceNotIsolatedCaller("grantUriPermission"); 6438 synchronized(this) { 6439 final ProcessRecord r = getRecordForAppLocked(caller); 6440 if (r == null) { 6441 throw new SecurityException("Unable to find app for caller " 6442 + caller 6443 + " when granting permission to uri " + uri); 6444 } 6445 if (targetPkg == null) { 6446 throw new IllegalArgumentException("null target"); 6447 } 6448 if (uri == null) { 6449 throw new IllegalArgumentException("null uri"); 6450 } 6451 6452 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6453 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6454 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6455 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6456 6457 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null); 6458 } 6459 } 6460 6461 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6462 if (perm.modeFlags == 0) { 6463 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6464 perm.targetUid); 6465 if (perms != null) { 6466 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6467 "Removing " + perm.targetUid + " permission to " + perm.uri); 6468 6469 perms.remove(perm.uri); 6470 if (perms.isEmpty()) { 6471 mGrantedUriPermissions.remove(perm.targetUid); 6472 } 6473 } 6474 } 6475 } 6476 6477 private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) { 6478 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6479 6480 final IPackageManager pm = AppGlobals.getPackageManager(); 6481 final String authority = uri.getAuthority(); 6482 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6483 if (pi == null) { 6484 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6485 return; 6486 } 6487 6488 // Does the caller have this permission on the URI? 6489 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6490 // Right now, if you are not the original owner of the permission, 6491 // you are not allowed to revoke it. 6492 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6493 throw new SecurityException("Uid " + callingUid 6494 + " does not have permission to uri " + uri); 6495 //} 6496 } 6497 6498 boolean persistChanged = false; 6499 6500 // Go through all of the permissions and remove any that match. 6501 int N = mGrantedUriPermissions.size(); 6502 for (int i = 0; i < N; i++) { 6503 final int targetUid = mGrantedUriPermissions.keyAt(i); 6504 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6505 6506 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6507 final UriPermission perm = it.next(); 6508 if (perm.uri.uri.isPathPrefixMatch(uri)) { 6509 if (DEBUG_URI_PERMISSION) 6510 Slog.v(TAG, 6511 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6512 persistChanged |= perm.revokeModes( 6513 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6514 if (perm.modeFlags == 0) { 6515 it.remove(); 6516 } 6517 } 6518 } 6519 6520 if (perms.isEmpty()) { 6521 mGrantedUriPermissions.remove(targetUid); 6522 N--; 6523 i--; 6524 } 6525 } 6526 6527 if (persistChanged) { 6528 schedulePersistUriGrants(); 6529 } 6530 } 6531 6532 @Override 6533 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6534 final int modeFlags) { 6535 enforceNotIsolatedCaller("revokeUriPermission"); 6536 synchronized(this) { 6537 final ProcessRecord r = getRecordForAppLocked(caller); 6538 if (r == null) { 6539 throw new SecurityException("Unable to find app for caller " 6540 + caller 6541 + " when revoking permission to uri " + uri); 6542 } 6543 if (uri == null) { 6544 Slog.w(TAG, "revokeUriPermission: null uri"); 6545 return; 6546 } 6547 6548 if (!Intent.isAccessUriMode(modeFlags)) { 6549 return; 6550 } 6551 6552 final IPackageManager pm = AppGlobals.getPackageManager(); 6553 final String authority = uri.getAuthority(); 6554 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6555 if (pi == null) { 6556 Slog.w(TAG, "No content provider found for permission revoke: " 6557 + uri.toSafeString()); 6558 return; 6559 } 6560 6561 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6562 } 6563 } 6564 6565 /** 6566 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6567 * given package. 6568 * 6569 * @param packageName Package name to match, or {@code null} to apply to all 6570 * packages. 6571 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6572 * to all users. 6573 * @param persistable If persistable grants should be removed. 6574 */ 6575 private void removeUriPermissionsForPackageLocked( 6576 String packageName, int userHandle, boolean persistable) { 6577 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6578 throw new IllegalArgumentException("Must narrow by either package or user"); 6579 } 6580 6581 boolean persistChanged = false; 6582 6583 int N = mGrantedUriPermissions.size(); 6584 for (int i = 0; i < N; i++) { 6585 final int targetUid = mGrantedUriPermissions.keyAt(i); 6586 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6587 6588 // Only inspect grants matching user 6589 if (userHandle == UserHandle.USER_ALL 6590 || userHandle == UserHandle.getUserId(targetUid)) { 6591 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6592 final UriPermission perm = it.next(); 6593 6594 // Only inspect grants matching package 6595 if (packageName == null || perm.sourcePkg.equals(packageName) 6596 || perm.targetPkg.equals(packageName)) { 6597 persistChanged |= perm.revokeModes( 6598 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6599 6600 // Only remove when no modes remain; any persisted grants 6601 // will keep this alive. 6602 if (perm.modeFlags == 0) { 6603 it.remove(); 6604 } 6605 } 6606 } 6607 6608 if (perms.isEmpty()) { 6609 mGrantedUriPermissions.remove(targetUid); 6610 N--; 6611 i--; 6612 } 6613 } 6614 } 6615 6616 if (persistChanged) { 6617 schedulePersistUriGrants(); 6618 } 6619 } 6620 6621 @Override 6622 public IBinder newUriPermissionOwner(String name) { 6623 enforceNotIsolatedCaller("newUriPermissionOwner"); 6624 synchronized(this) { 6625 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6626 return owner.getExternalTokenLocked(); 6627 } 6628 } 6629 6630 @Override 6631 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6632 Uri uri, final int modeFlags) { 6633 synchronized(this) { 6634 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6635 if (owner == null) { 6636 throw new IllegalArgumentException("Unknown owner: " + token); 6637 } 6638 if (fromUid != Binder.getCallingUid()) { 6639 if (Binder.getCallingUid() != Process.myUid()) { 6640 // Only system code can grant URI permissions on behalf 6641 // of other users. 6642 throw new SecurityException("nice try"); 6643 } 6644 } 6645 if (targetPkg == null) { 6646 throw new IllegalArgumentException("null target"); 6647 } 6648 if (uri == null) { 6649 throw new IllegalArgumentException("null uri"); 6650 } 6651 6652 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6653 } 6654 } 6655 6656 @Override 6657 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6658 synchronized(this) { 6659 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6660 if (owner == null) { 6661 throw new IllegalArgumentException("Unknown owner: " + token); 6662 } 6663 6664 if (uri == null) { 6665 owner.removeUriPermissionsLocked(mode); 6666 } else { 6667 owner.removeUriPermissionLocked(uri, mode); 6668 } 6669 } 6670 } 6671 6672 private void schedulePersistUriGrants() { 6673 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6674 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6675 10 * DateUtils.SECOND_IN_MILLIS); 6676 } 6677 } 6678 6679 private void writeGrantedUriPermissions() { 6680 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6681 6682 // Snapshot permissions so we can persist without lock 6683 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6684 synchronized (this) { 6685 final int size = mGrantedUriPermissions.size(); 6686 for (int i = 0; i < size; i++) { 6687 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6688 for (UriPermission perm : perms.values()) { 6689 if (perm.persistedModeFlags != 0) { 6690 persist.add(perm.snapshot()); 6691 } 6692 } 6693 } 6694 } 6695 6696 FileOutputStream fos = null; 6697 try { 6698 fos = mGrantFile.startWrite(); 6699 6700 XmlSerializer out = new FastXmlSerializer(); 6701 out.setOutput(fos, "utf-8"); 6702 out.startDocument(null, true); 6703 out.startTag(null, TAG_URI_GRANTS); 6704 for (UriPermission.Snapshot perm : persist) { 6705 out.startTag(null, TAG_URI_GRANT); 6706 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6707 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6708 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6709 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6710 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6711 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6712 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6713 out.endTag(null, TAG_URI_GRANT); 6714 } 6715 out.endTag(null, TAG_URI_GRANTS); 6716 out.endDocument(); 6717 6718 mGrantFile.finishWrite(fos); 6719 } catch (IOException e) { 6720 if (fos != null) { 6721 mGrantFile.failWrite(fos); 6722 } 6723 } 6724 } 6725 6726 private void readGrantedUriPermissionsLocked() { 6727 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6728 6729 final long now = System.currentTimeMillis(); 6730 6731 FileInputStream fis = null; 6732 try { 6733 fis = mGrantFile.openRead(); 6734 final XmlPullParser in = Xml.newPullParser(); 6735 in.setInput(fis, null); 6736 6737 int type; 6738 while ((type = in.next()) != END_DOCUMENT) { 6739 final String tag = in.getName(); 6740 if (type == START_TAG) { 6741 if (TAG_URI_GRANT.equals(tag)) { 6742 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6743 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6744 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6745 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6746 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6747 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6748 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6749 6750 // Sanity check that provider still belongs to source package 6751 final ProviderInfo pi = getProviderInfoLocked( 6752 uri.getAuthority(), userHandle); 6753 if (pi != null && sourcePkg.equals(pi.packageName)) { 6754 int targetUid = -1; 6755 try { 6756 targetUid = AppGlobals.getPackageManager() 6757 .getPackageUid(targetPkg, userHandle); 6758 } catch (RemoteException e) { 6759 } 6760 if (targetUid != -1) { 6761 final UriPermission perm = findOrCreateUriPermissionLocked( 6762 sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix)); 6763 perm.initPersistedModes(modeFlags, createdTime); 6764 } 6765 } else { 6766 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6767 + " but instead found " + pi); 6768 } 6769 } 6770 } 6771 } 6772 } catch (FileNotFoundException e) { 6773 // Missing grants is okay 6774 } catch (IOException e) { 6775 Log.wtf(TAG, "Failed reading Uri grants", e); 6776 } catch (XmlPullParserException e) { 6777 Log.wtf(TAG, "Failed reading Uri grants", e); 6778 } finally { 6779 IoUtils.closeQuietly(fis); 6780 } 6781 } 6782 6783 @Override 6784 public void takePersistableUriPermission(Uri uri, final int modeFlags) { 6785 enforceNotIsolatedCaller("takePersistableUriPermission"); 6786 6787 Preconditions.checkFlagsArgument(modeFlags, 6788 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6789 6790 synchronized (this) { 6791 final int callingUid = Binder.getCallingUid(); 6792 boolean persistChanged = false; 6793 6794 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6795 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6796 6797 final boolean exactValid = (exactPerm != null) 6798 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6799 final boolean prefixValid = (prefixPerm != null) 6800 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6801 6802 if (!(exactValid || prefixValid)) { 6803 throw new SecurityException("No persistable permission grants found for UID " 6804 + callingUid + " and Uri " + uri.toSafeString()); 6805 } 6806 6807 if (exactValid) { 6808 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6809 } 6810 if (prefixValid) { 6811 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6812 } 6813 6814 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6815 6816 if (persistChanged) { 6817 schedulePersistUriGrants(); 6818 } 6819 } 6820 } 6821 6822 @Override 6823 public void releasePersistableUriPermission(Uri uri, final int modeFlags) { 6824 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6825 6826 Preconditions.checkFlagsArgument(modeFlags, 6827 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6828 6829 synchronized (this) { 6830 final int callingUid = Binder.getCallingUid(); 6831 boolean persistChanged = false; 6832 6833 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6834 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6835 if (exactPerm == null && prefixPerm == null) { 6836 throw new SecurityException("No permission grants found for UID " + callingUid 6837 + " and Uri " + uri.toSafeString()); 6838 } 6839 6840 if (exactPerm != null) { 6841 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6842 removeUriPermissionIfNeededLocked(exactPerm); 6843 } 6844 if (prefixPerm != null) { 6845 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6846 removeUriPermissionIfNeededLocked(prefixPerm); 6847 } 6848 6849 if (persistChanged) { 6850 schedulePersistUriGrants(); 6851 } 6852 } 6853 } 6854 6855 /** 6856 * Prune any older {@link UriPermission} for the given UID until outstanding 6857 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6858 * 6859 * @return if any mutations occured that require persisting. 6860 */ 6861 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6862 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6863 if (perms == null) return false; 6864 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6865 6866 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6867 for (UriPermission perm : perms.values()) { 6868 if (perm.persistedModeFlags != 0) { 6869 persisted.add(perm); 6870 } 6871 } 6872 6873 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6874 if (trimCount <= 0) return false; 6875 6876 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6877 for (int i = 0; i < trimCount; i++) { 6878 final UriPermission perm = persisted.get(i); 6879 6880 if (DEBUG_URI_PERMISSION) { 6881 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6882 } 6883 6884 perm.releasePersistableModes(~0); 6885 removeUriPermissionIfNeededLocked(perm); 6886 } 6887 6888 return true; 6889 } 6890 6891 @Override 6892 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6893 String packageName, boolean incoming) { 6894 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6895 Preconditions.checkNotNull(packageName, "packageName"); 6896 6897 final int callingUid = Binder.getCallingUid(); 6898 final IPackageManager pm = AppGlobals.getPackageManager(); 6899 try { 6900 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6901 if (packageUid != callingUid) { 6902 throw new SecurityException( 6903 "Package " + packageName + " does not belong to calling UID " + callingUid); 6904 } 6905 } catch (RemoteException e) { 6906 throw new SecurityException("Failed to verify package name ownership"); 6907 } 6908 6909 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6910 synchronized (this) { 6911 if (incoming) { 6912 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6913 callingUid); 6914 if (perms == null) { 6915 Slog.w(TAG, "No permission grants found for " + packageName); 6916 } else { 6917 for (UriPermission perm : perms.values()) { 6918 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6919 result.add(perm.buildPersistedPublicApiObject()); 6920 } 6921 } 6922 } 6923 } else { 6924 final int size = mGrantedUriPermissions.size(); 6925 for (int i = 0; i < size; i++) { 6926 final ArrayMap<GrantUri, UriPermission> perms = 6927 mGrantedUriPermissions.valueAt(i); 6928 for (UriPermission perm : perms.values()) { 6929 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6930 result.add(perm.buildPersistedPublicApiObject()); 6931 } 6932 } 6933 } 6934 } 6935 } 6936 return new ParceledListSlice<android.content.UriPermission>(result); 6937 } 6938 6939 @Override 6940 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6941 synchronized (this) { 6942 ProcessRecord app = 6943 who != null ? getRecordForAppLocked(who) : null; 6944 if (app == null) return; 6945 6946 Message msg = Message.obtain(); 6947 msg.what = WAIT_FOR_DEBUGGER_MSG; 6948 msg.obj = app; 6949 msg.arg1 = waiting ? 1 : 0; 6950 mHandler.sendMessage(msg); 6951 } 6952 } 6953 6954 @Override 6955 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6956 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6957 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6958 outInfo.availMem = Process.getFreeMemory(); 6959 outInfo.totalMem = Process.getTotalMemory(); 6960 outInfo.threshold = homeAppMem; 6961 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6962 outInfo.hiddenAppThreshold = cachedAppMem; 6963 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6964 ProcessList.SERVICE_ADJ); 6965 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6966 ProcessList.VISIBLE_APP_ADJ); 6967 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6968 ProcessList.FOREGROUND_APP_ADJ); 6969 } 6970 6971 // ========================================================= 6972 // TASK MANAGEMENT 6973 // ========================================================= 6974 6975 @Override 6976 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 6977 final int callingUid = Binder.getCallingUid(); 6978 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6979 6980 synchronized(this) { 6981 if (localLOGV) Slog.v( 6982 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 6983 6984 final boolean allowed = checkCallingPermission( 6985 android.Manifest.permission.GET_TASKS) 6986 == PackageManager.PERMISSION_GRANTED; 6987 if (!allowed) { 6988 Slog.w(TAG, "getTasks: caller " + callingUid 6989 + " does not hold GET_TASKS; limiting output"); 6990 } 6991 6992 // TODO: Improve with MRU list from all ActivityStacks. 6993 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 6994 } 6995 6996 return list; 6997 } 6998 6999 TaskRecord getMostRecentTask() { 7000 return mRecentTasks.get(0); 7001 } 7002 7003 @Override 7004 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7005 int flags, int userId) { 7006 final int callingUid = Binder.getCallingUid(); 7007 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7008 false, true, "getRecentTasks", null); 7009 7010 synchronized (this) { 7011 final boolean allowed = checkCallingPermission( 7012 android.Manifest.permission.GET_TASKS) 7013 == PackageManager.PERMISSION_GRANTED; 7014 if (!allowed) { 7015 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7016 + " does not hold GET_TASKS; limiting output"); 7017 } 7018 final boolean detailed = checkCallingPermission( 7019 android.Manifest.permission.GET_DETAILED_TASKS) 7020 == PackageManager.PERMISSION_GRANTED; 7021 7022 IPackageManager pm = AppGlobals.getPackageManager(); 7023 7024 final int N = mRecentTasks.size(); 7025 ArrayList<ActivityManager.RecentTaskInfo> res 7026 = new ArrayList<ActivityManager.RecentTaskInfo>( 7027 maxNum < N ? maxNum : N); 7028 7029 final Set<Integer> includedUsers; 7030 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7031 includedUsers = getProfileIdsLocked(userId); 7032 } else { 7033 includedUsers = new HashSet<Integer>(); 7034 } 7035 includedUsers.add(Integer.valueOf(userId)); 7036 for (int i=0; i<N && maxNum > 0; i++) { 7037 TaskRecord tr = mRecentTasks.get(i); 7038 // Only add calling user or related users recent tasks 7039 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7040 7041 // Return the entry if desired by the caller. We always return 7042 // the first entry, because callers always expect this to be the 7043 // foreground app. We may filter others if the caller has 7044 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7045 // we should exclude the entry. 7046 7047 if (i == 0 7048 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7049 || (tr.intent == null) 7050 || ((tr.intent.getFlags() 7051 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7052 if (!allowed) { 7053 // If the caller doesn't have the GET_TASKS permission, then only 7054 // allow them to see a small subset of tasks -- their own and home. 7055 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7056 continue; 7057 } 7058 } 7059 ActivityManager.RecentTaskInfo rti 7060 = new ActivityManager.RecentTaskInfo(); 7061 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 7062 rti.persistentId = tr.taskId; 7063 rti.baseIntent = new Intent( 7064 tr.intent != null ? tr.intent : tr.affinityIntent); 7065 if (!detailed) { 7066 rti.baseIntent.replaceExtras((Bundle)null); 7067 } 7068 rti.origActivity = tr.origActivity; 7069 rti.description = tr.lastDescription; 7070 rti.stackId = tr.stack.mStackId; 7071 rti.userId = tr.userId; 7072 7073 // Traverse upwards looking for any break between main task activities and 7074 // utility activities. 7075 final ArrayList<ActivityRecord> activities = tr.mActivities; 7076 int activityNdx; 7077 final int numActivities = activities.size(); 7078 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities; 7079 ++activityNdx) { 7080 final ActivityRecord r = activities.get(activityNdx); 7081 if (r.intent != null && 7082 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) 7083 != 0) { 7084 break; 7085 } 7086 } 7087 if (activityNdx > 0) { 7088 // Traverse downwards starting below break looking for set label, icon. 7089 // Note that if there are activities in the task but none of them set the 7090 // recent activity values, then we do not fall back to the last set 7091 // values in the TaskRecord. 7092 rti.activityValues = new ActivityManager.RecentsActivityValues(); 7093 for (--activityNdx; activityNdx >= 0; --activityNdx) { 7094 final ActivityRecord r = activities.get(activityNdx); 7095 if (r.activityValues != null) { 7096 if (rti.activityValues.label == null) { 7097 rti.activityValues.label = r.activityValues.label; 7098 tr.lastActivityValues.label = r.activityValues.label; 7099 } 7100 if (rti.activityValues.icon == null) { 7101 rti.activityValues.icon = r.activityValues.icon; 7102 tr.lastActivityValues.icon = r.activityValues.icon; 7103 } 7104 if (rti.activityValues.colorPrimary == 0) { 7105 rti.activityValues.colorPrimary = r.activityValues.colorPrimary; 7106 tr.lastActivityValues.colorPrimary = r.activityValues.colorPrimary; 7107 } 7108 } 7109 } 7110 } else { 7111 // If there are no activity records in this task, then we use the last 7112 // resolved values 7113 rti.activityValues = 7114 new ActivityManager.RecentsActivityValues(tr.lastActivityValues); 7115 } 7116 7117 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7118 // Check whether this activity is currently available. 7119 try { 7120 if (rti.origActivity != null) { 7121 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7122 == null) { 7123 continue; 7124 } 7125 } else if (rti.baseIntent != null) { 7126 if (pm.queryIntentActivities(rti.baseIntent, 7127 null, 0, userId) == null) { 7128 continue; 7129 } 7130 } 7131 } catch (RemoteException e) { 7132 // Will never happen. 7133 } 7134 } 7135 7136 res.add(rti); 7137 maxNum--; 7138 } 7139 } 7140 return res; 7141 } 7142 } 7143 7144 private TaskRecord recentTaskForIdLocked(int id) { 7145 final int N = mRecentTasks.size(); 7146 for (int i=0; i<N; i++) { 7147 TaskRecord tr = mRecentTasks.get(i); 7148 if (tr.taskId == id) { 7149 return tr; 7150 } 7151 } 7152 return null; 7153 } 7154 7155 @Override 7156 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7157 synchronized (this) { 7158 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7159 "getTaskThumbnails()"); 7160 TaskRecord tr = recentTaskForIdLocked(id); 7161 if (tr != null) { 7162 return tr.getTaskThumbnailsLocked(); 7163 } 7164 } 7165 return null; 7166 } 7167 7168 @Override 7169 public Bitmap getTaskTopThumbnail(int id) { 7170 synchronized (this) { 7171 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7172 "getTaskTopThumbnail()"); 7173 TaskRecord tr = recentTaskForIdLocked(id); 7174 if (tr != null) { 7175 return tr.getTaskTopThumbnailLocked(); 7176 } 7177 } 7178 return null; 7179 } 7180 7181 @Override 7182 public void setRecentsActivityValues(IBinder token, ActivityManager.RecentsActivityValues rav) { 7183 synchronized (this) { 7184 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7185 if (r != null) { 7186 r.activityValues = rav; 7187 } 7188 } 7189 } 7190 7191 @Override 7192 public boolean removeSubTask(int taskId, int subTaskIndex) { 7193 synchronized (this) { 7194 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7195 "removeSubTask()"); 7196 long ident = Binder.clearCallingIdentity(); 7197 try { 7198 TaskRecord tr = recentTaskForIdLocked(taskId); 7199 if (tr != null) { 7200 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7201 } 7202 return false; 7203 } finally { 7204 Binder.restoreCallingIdentity(ident); 7205 } 7206 } 7207 } 7208 7209 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7210 if (!pr.killedByAm) { 7211 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7212 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7213 pr.processName, pr.setAdj, reason); 7214 pr.killedByAm = true; 7215 Process.killProcessQuiet(pr.pid); 7216 } 7217 } 7218 7219 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7220 tr.disposeThumbnail(); 7221 mRecentTasks.remove(tr); 7222 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7223 Intent baseIntent = new Intent( 7224 tr.intent != null ? tr.intent : tr.affinityIntent); 7225 ComponentName component = baseIntent.getComponent(); 7226 if (component == null) { 7227 Slog.w(TAG, "Now component for base intent of task: " + tr); 7228 return; 7229 } 7230 7231 // Find any running services associated with this app. 7232 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7233 7234 if (killProcesses) { 7235 // Find any running processes associated with this app. 7236 final String pkg = component.getPackageName(); 7237 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7238 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7239 for (int i=0; i<pmap.size(); i++) { 7240 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7241 for (int j=0; j<uids.size(); j++) { 7242 ProcessRecord proc = uids.valueAt(j); 7243 if (proc.userId != tr.userId) { 7244 continue; 7245 } 7246 if (!proc.pkgList.containsKey(pkg)) { 7247 continue; 7248 } 7249 procs.add(proc); 7250 } 7251 } 7252 7253 // Kill the running processes. 7254 for (int i=0; i<procs.size(); i++) { 7255 ProcessRecord pr = procs.get(i); 7256 if (pr == mHomeProcess) { 7257 // Don't kill the home process along with tasks from the same package. 7258 continue; 7259 } 7260 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7261 killUnneededProcessLocked(pr, "remove task"); 7262 } else { 7263 pr.waitingToKill = "remove task"; 7264 } 7265 } 7266 } 7267 } 7268 7269 /** 7270 * Removes the task with the specified task id. 7271 * 7272 * @param taskId Identifier of the task to be removed. 7273 * @param flags Additional operational flags. May be 0 or 7274 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7275 * @return Returns true if the given task was found and removed. 7276 */ 7277 private boolean removeTaskByIdLocked(int taskId, int flags) { 7278 TaskRecord tr = recentTaskForIdLocked(taskId); 7279 if (tr != null) { 7280 tr.removeTaskActivitiesLocked(-1, false); 7281 cleanUpRemovedTaskLocked(tr, flags); 7282 return true; 7283 } 7284 return false; 7285 } 7286 7287 @Override 7288 public boolean removeTask(int taskId, int flags) { 7289 synchronized (this) { 7290 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7291 "removeTask()"); 7292 long ident = Binder.clearCallingIdentity(); 7293 try { 7294 return removeTaskByIdLocked(taskId, flags); 7295 } finally { 7296 Binder.restoreCallingIdentity(ident); 7297 } 7298 } 7299 } 7300 7301 /** 7302 * TODO: Add mController hook 7303 */ 7304 @Override 7305 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7306 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7307 "moveTaskToFront()"); 7308 7309 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7310 synchronized(this) { 7311 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7312 Binder.getCallingUid(), "Task to front")) { 7313 ActivityOptions.abort(options); 7314 return; 7315 } 7316 final long origId = Binder.clearCallingIdentity(); 7317 try { 7318 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7319 if (task == null) { 7320 return; 7321 } 7322 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7323 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7324 return; 7325 } 7326 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7327 } finally { 7328 Binder.restoreCallingIdentity(origId); 7329 } 7330 ActivityOptions.abort(options); 7331 } 7332 } 7333 7334 @Override 7335 public void moveTaskToBack(int taskId) { 7336 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7337 "moveTaskToBack()"); 7338 7339 synchronized(this) { 7340 TaskRecord tr = recentTaskForIdLocked(taskId); 7341 if (tr != null) { 7342 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7343 ActivityStack stack = tr.stack; 7344 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7345 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7346 Binder.getCallingUid(), "Task to back")) { 7347 return; 7348 } 7349 } 7350 final long origId = Binder.clearCallingIdentity(); 7351 try { 7352 stack.moveTaskToBackLocked(taskId, null); 7353 } finally { 7354 Binder.restoreCallingIdentity(origId); 7355 } 7356 } 7357 } 7358 } 7359 7360 /** 7361 * Moves an activity, and all of the other activities within the same task, to the bottom 7362 * of the history stack. The activity's order within the task is unchanged. 7363 * 7364 * @param token A reference to the activity we wish to move 7365 * @param nonRoot If false then this only works if the activity is the root 7366 * of a task; if true it will work for any activity in a task. 7367 * @return Returns true if the move completed, false if not. 7368 */ 7369 @Override 7370 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7371 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7372 synchronized(this) { 7373 final long origId = Binder.clearCallingIdentity(); 7374 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7375 if (taskId >= 0) { 7376 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7377 } 7378 Binder.restoreCallingIdentity(origId); 7379 } 7380 return false; 7381 } 7382 7383 @Override 7384 public void moveTaskBackwards(int task) { 7385 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7386 "moveTaskBackwards()"); 7387 7388 synchronized(this) { 7389 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7390 Binder.getCallingUid(), "Task backwards")) { 7391 return; 7392 } 7393 final long origId = Binder.clearCallingIdentity(); 7394 moveTaskBackwardsLocked(task); 7395 Binder.restoreCallingIdentity(origId); 7396 } 7397 } 7398 7399 private final void moveTaskBackwardsLocked(int task) { 7400 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7401 } 7402 7403 @Override 7404 public IBinder getHomeActivityToken() throws RemoteException { 7405 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7406 "getHomeActivityToken()"); 7407 synchronized (this) { 7408 return mStackSupervisor.getHomeActivityToken(); 7409 } 7410 } 7411 7412 @Override 7413 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7414 IActivityContainerCallback callback) throws RemoteException { 7415 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7416 "createActivityContainer()"); 7417 synchronized (this) { 7418 if (parentActivityToken == null) { 7419 throw new IllegalArgumentException("parent token must not be null"); 7420 } 7421 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7422 if (r == null) { 7423 return null; 7424 } 7425 if (callback == null) { 7426 throw new IllegalArgumentException("callback must not be null"); 7427 } 7428 return mStackSupervisor.createActivityContainer(r, callback); 7429 } 7430 } 7431 7432 @Override 7433 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7434 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7435 "deleteActivityContainer()"); 7436 synchronized (this) { 7437 mStackSupervisor.deleteActivityContainer(container); 7438 } 7439 } 7440 7441 @Override 7442 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7443 throws RemoteException { 7444 synchronized (this) { 7445 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7446 if (stack != null) { 7447 return stack.mActivityContainer; 7448 } 7449 return null; 7450 } 7451 } 7452 7453 @Override 7454 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7455 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7456 "moveTaskToStack()"); 7457 if (stackId == HOME_STACK_ID) { 7458 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7459 new RuntimeException("here").fillInStackTrace()); 7460 } 7461 synchronized (this) { 7462 long ident = Binder.clearCallingIdentity(); 7463 try { 7464 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7465 + stackId + " toTop=" + toTop); 7466 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7467 } finally { 7468 Binder.restoreCallingIdentity(ident); 7469 } 7470 } 7471 } 7472 7473 @Override 7474 public void resizeStack(int stackBoxId, Rect bounds) { 7475 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7476 "resizeStackBox()"); 7477 long ident = Binder.clearCallingIdentity(); 7478 try { 7479 mWindowManager.resizeStack(stackBoxId, bounds); 7480 } finally { 7481 Binder.restoreCallingIdentity(ident); 7482 } 7483 } 7484 7485 @Override 7486 public List<StackInfo> getAllStackInfos() { 7487 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7488 "getAllStackInfos()"); 7489 long ident = Binder.clearCallingIdentity(); 7490 try { 7491 synchronized (this) { 7492 return mStackSupervisor.getAllStackInfosLocked(); 7493 } 7494 } finally { 7495 Binder.restoreCallingIdentity(ident); 7496 } 7497 } 7498 7499 @Override 7500 public StackInfo getStackInfo(int stackId) { 7501 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7502 "getStackInfo()"); 7503 long ident = Binder.clearCallingIdentity(); 7504 try { 7505 synchronized (this) { 7506 return mStackSupervisor.getStackInfoLocked(stackId); 7507 } 7508 } finally { 7509 Binder.restoreCallingIdentity(ident); 7510 } 7511 } 7512 7513 @Override 7514 public boolean isInHomeStack(int taskId) { 7515 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7516 "getStackInfo()"); 7517 long ident = Binder.clearCallingIdentity(); 7518 try { 7519 synchronized (this) { 7520 TaskRecord tr = recentTaskForIdLocked(taskId); 7521 if (tr != null) { 7522 return tr.stack.isHomeStack(); 7523 } 7524 } 7525 } finally { 7526 Binder.restoreCallingIdentity(ident); 7527 } 7528 return false; 7529 } 7530 7531 @Override 7532 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7533 synchronized(this) { 7534 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7535 } 7536 } 7537 7538 private boolean isLockTaskAuthorized(ComponentName name) { 7539// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7540// "startLockTaskMode()"); 7541// DevicePolicyManager dpm = (DevicePolicyManager) 7542// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7543// return dpm != null && dpm.isLockTaskPermitted(name); 7544 return true; 7545 } 7546 7547 private void startLockTaskMode(TaskRecord task) { 7548 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7549 return; 7550 } 7551 long ident = Binder.clearCallingIdentity(); 7552 try { 7553 synchronized (this) { 7554 // Since we lost lock on task, make sure it is still there. 7555 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7556 if (task != null) { 7557 mStackSupervisor.setLockTaskModeLocked(task); 7558 } 7559 } 7560 } finally { 7561 Binder.restoreCallingIdentity(ident); 7562 } 7563 } 7564 7565 @Override 7566 public void startLockTaskMode(int taskId) { 7567 long ident = Binder.clearCallingIdentity(); 7568 try { 7569 final TaskRecord task; 7570 synchronized (this) { 7571 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7572 } 7573 if (task != null) { 7574 startLockTaskMode(task); 7575 } 7576 } finally { 7577 Binder.restoreCallingIdentity(ident); 7578 } 7579 } 7580 7581 @Override 7582 public void startLockTaskMode(IBinder token) { 7583 long ident = Binder.clearCallingIdentity(); 7584 try { 7585 final TaskRecord task; 7586 synchronized (this) { 7587 final ActivityRecord r = ActivityRecord.forToken(token); 7588 if (r == null) { 7589 return; 7590 } 7591 task = r.task; 7592 } 7593 if (task != null) { 7594 startLockTaskMode(task); 7595 } 7596 } finally { 7597 Binder.restoreCallingIdentity(ident); 7598 } 7599 } 7600 7601 @Override 7602 public void stopLockTaskMode() { 7603// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7604// "stopLockTaskMode()"); 7605 synchronized (this) { 7606 mStackSupervisor.setLockTaskModeLocked(null); 7607 } 7608 } 7609 7610 @Override 7611 public boolean isInLockTaskMode() { 7612 synchronized (this) { 7613 return mStackSupervisor.isInLockTaskMode(); 7614 } 7615 } 7616 7617 // ========================================================= 7618 // CONTENT PROVIDERS 7619 // ========================================================= 7620 7621 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7622 List<ProviderInfo> providers = null; 7623 try { 7624 providers = AppGlobals.getPackageManager(). 7625 queryContentProviders(app.processName, app.uid, 7626 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7627 } catch (RemoteException ex) { 7628 } 7629 if (DEBUG_MU) 7630 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7631 int userId = app.userId; 7632 if (providers != null) { 7633 int N = providers.size(); 7634 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7635 for (int i=0; i<N; i++) { 7636 ProviderInfo cpi = 7637 (ProviderInfo)providers.get(i); 7638 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7639 cpi.name, cpi.flags); 7640 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7641 // This is a singleton provider, but a user besides the 7642 // default user is asking to initialize a process it runs 7643 // in... well, no, it doesn't actually run in this process, 7644 // it runs in the process of the default user. Get rid of it. 7645 providers.remove(i); 7646 N--; 7647 i--; 7648 continue; 7649 } 7650 7651 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7652 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7653 if (cpr == null) { 7654 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7655 mProviderMap.putProviderByClass(comp, cpr); 7656 } 7657 if (DEBUG_MU) 7658 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7659 app.pubProviders.put(cpi.name, cpr); 7660 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7661 // Don't add this if it is a platform component that is marked 7662 // to run in multiple processes, because this is actually 7663 // part of the framework so doesn't make sense to track as a 7664 // separate apk in the process. 7665 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7666 } 7667 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7668 } 7669 } 7670 return providers; 7671 } 7672 7673 /** 7674 * Check if {@link ProcessRecord} has a possible chance at accessing the 7675 * given {@link ProviderInfo}. Final permission checking is always done 7676 * in {@link ContentProvider}. 7677 */ 7678 private final String checkContentProviderPermissionLocked( 7679 ProviderInfo cpi, ProcessRecord r) { 7680 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7681 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7682 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7683 cpi.applicationInfo.uid, cpi.exported) 7684 == PackageManager.PERMISSION_GRANTED) { 7685 return null; 7686 } 7687 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7688 cpi.applicationInfo.uid, cpi.exported) 7689 == PackageManager.PERMISSION_GRANTED) { 7690 return null; 7691 } 7692 7693 PathPermission[] pps = cpi.pathPermissions; 7694 if (pps != null) { 7695 int i = pps.length; 7696 while (i > 0) { 7697 i--; 7698 PathPermission pp = pps[i]; 7699 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7700 cpi.applicationInfo.uid, cpi.exported) 7701 == PackageManager.PERMISSION_GRANTED) { 7702 return null; 7703 } 7704 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7705 cpi.applicationInfo.uid, cpi.exported) 7706 == PackageManager.PERMISSION_GRANTED) { 7707 return null; 7708 } 7709 } 7710 } 7711 7712 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7713 if (perms != null) { 7714 for (GrantUri uri : perms.keySet()) { 7715 if (uri.uri.getAuthority().equals(cpi.authority)) { 7716 return null; 7717 } 7718 } 7719 } 7720 7721 String msg; 7722 if (!cpi.exported) { 7723 msg = "Permission Denial: opening provider " + cpi.name 7724 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7725 + ", uid=" + callingUid + ") that is not exported from uid " 7726 + cpi.applicationInfo.uid; 7727 } else { 7728 msg = "Permission Denial: opening provider " + cpi.name 7729 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7730 + ", uid=" + callingUid + ") requires " 7731 + cpi.readPermission + " or " + cpi.writePermission; 7732 } 7733 Slog.w(TAG, msg); 7734 return msg; 7735 } 7736 7737 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7738 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7739 if (r != null) { 7740 for (int i=0; i<r.conProviders.size(); i++) { 7741 ContentProviderConnection conn = r.conProviders.get(i); 7742 if (conn.provider == cpr) { 7743 if (DEBUG_PROVIDER) Slog.v(TAG, 7744 "Adding provider requested by " 7745 + r.processName + " from process " 7746 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7747 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7748 if (stable) { 7749 conn.stableCount++; 7750 conn.numStableIncs++; 7751 } else { 7752 conn.unstableCount++; 7753 conn.numUnstableIncs++; 7754 } 7755 return conn; 7756 } 7757 } 7758 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7759 if (stable) { 7760 conn.stableCount = 1; 7761 conn.numStableIncs = 1; 7762 } else { 7763 conn.unstableCount = 1; 7764 conn.numUnstableIncs = 1; 7765 } 7766 cpr.connections.add(conn); 7767 r.conProviders.add(conn); 7768 return conn; 7769 } 7770 cpr.addExternalProcessHandleLocked(externalProcessToken); 7771 return null; 7772 } 7773 7774 boolean decProviderCountLocked(ContentProviderConnection conn, 7775 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7776 if (conn != null) { 7777 cpr = conn.provider; 7778 if (DEBUG_PROVIDER) Slog.v(TAG, 7779 "Removing provider requested by " 7780 + conn.client.processName + " from process " 7781 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7782 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7783 if (stable) { 7784 conn.stableCount--; 7785 } else { 7786 conn.unstableCount--; 7787 } 7788 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7789 cpr.connections.remove(conn); 7790 conn.client.conProviders.remove(conn); 7791 return true; 7792 } 7793 return false; 7794 } 7795 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7796 return false; 7797 } 7798 7799 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7800 String name, IBinder token, boolean stable, int userId) { 7801 ContentProviderRecord cpr; 7802 ContentProviderConnection conn = null; 7803 ProviderInfo cpi = null; 7804 7805 synchronized(this) { 7806 ProcessRecord r = null; 7807 if (caller != null) { 7808 r = getRecordForAppLocked(caller); 7809 if (r == null) { 7810 throw new SecurityException( 7811 "Unable to find app for caller " + caller 7812 + " (pid=" + Binder.getCallingPid() 7813 + ") when getting content provider " + name); 7814 } 7815 } 7816 7817 // First check if this content provider has been published... 7818 cpr = mProviderMap.getProviderByName(name, userId); 7819 boolean providerRunning = cpr != null; 7820 if (providerRunning) { 7821 cpi = cpr.info; 7822 String msg; 7823 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7824 throw new SecurityException(msg); 7825 } 7826 7827 if (r != null && cpr.canRunHere(r)) { 7828 // This provider has been published or is in the process 7829 // of being published... but it is also allowed to run 7830 // in the caller's process, so don't make a connection 7831 // and just let the caller instantiate its own instance. 7832 ContentProviderHolder holder = cpr.newHolder(null); 7833 // don't give caller the provider object, it needs 7834 // to make its own. 7835 holder.provider = null; 7836 return holder; 7837 } 7838 7839 final long origId = Binder.clearCallingIdentity(); 7840 7841 // In this case the provider instance already exists, so we can 7842 // return it right away. 7843 conn = incProviderCountLocked(r, cpr, token, stable); 7844 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7845 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7846 // If this is a perceptible app accessing the provider, 7847 // make sure to count it as being accessed and thus 7848 // back up on the LRU list. This is good because 7849 // content providers are often expensive to start. 7850 updateLruProcessLocked(cpr.proc, false, null); 7851 } 7852 } 7853 7854 if (cpr.proc != null) { 7855 if (false) { 7856 if (cpr.name.flattenToShortString().equals( 7857 "com.android.providers.calendar/.CalendarProvider2")) { 7858 Slog.v(TAG, "****************** KILLING " 7859 + cpr.name.flattenToShortString()); 7860 Process.killProcess(cpr.proc.pid); 7861 } 7862 } 7863 boolean success = updateOomAdjLocked(cpr.proc); 7864 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7865 // NOTE: there is still a race here where a signal could be 7866 // pending on the process even though we managed to update its 7867 // adj level. Not sure what to do about this, but at least 7868 // the race is now smaller. 7869 if (!success) { 7870 // Uh oh... it looks like the provider's process 7871 // has been killed on us. We need to wait for a new 7872 // process to be started, and make sure its death 7873 // doesn't kill our process. 7874 Slog.i(TAG, 7875 "Existing provider " + cpr.name.flattenToShortString() 7876 + " is crashing; detaching " + r); 7877 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7878 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7879 if (!lastRef) { 7880 // This wasn't the last ref our process had on 7881 // the provider... we have now been killed, bail. 7882 return null; 7883 } 7884 providerRunning = false; 7885 conn = null; 7886 } 7887 } 7888 7889 Binder.restoreCallingIdentity(origId); 7890 } 7891 7892 boolean singleton; 7893 if (!providerRunning) { 7894 try { 7895 cpi = AppGlobals.getPackageManager(). 7896 resolveContentProvider(name, 7897 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7898 } catch (RemoteException ex) { 7899 } 7900 if (cpi == null) { 7901 return null; 7902 } 7903 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7904 cpi.name, cpi.flags); 7905 if (singleton) { 7906 userId = 0; 7907 } 7908 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7909 7910 String msg; 7911 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7912 throw new SecurityException(msg); 7913 } 7914 7915 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7916 && !cpi.processName.equals("system")) { 7917 // If this content provider does not run in the system 7918 // process, and the system is not yet ready to run other 7919 // processes, then fail fast instead of hanging. 7920 throw new IllegalArgumentException( 7921 "Attempt to launch content provider before system ready"); 7922 } 7923 7924 // Make sure that the user who owns this provider is started. If not, 7925 // we don't want to allow it to run. 7926 if (mStartedUsers.get(userId) == null) { 7927 Slog.w(TAG, "Unable to launch app " 7928 + cpi.applicationInfo.packageName + "/" 7929 + cpi.applicationInfo.uid + " for provider " 7930 + name + ": user " + userId + " is stopped"); 7931 return null; 7932 } 7933 7934 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7935 cpr = mProviderMap.getProviderByClass(comp, userId); 7936 final boolean firstClass = cpr == null; 7937 if (firstClass) { 7938 try { 7939 ApplicationInfo ai = 7940 AppGlobals.getPackageManager(). 7941 getApplicationInfo( 7942 cpi.applicationInfo.packageName, 7943 STOCK_PM_FLAGS, userId); 7944 if (ai == null) { 7945 Slog.w(TAG, "No package info for content provider " 7946 + cpi.name); 7947 return null; 7948 } 7949 ai = getAppInfoForUser(ai, userId); 7950 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7951 } catch (RemoteException ex) { 7952 // pm is in same process, this will never happen. 7953 } 7954 } 7955 7956 if (r != null && cpr.canRunHere(r)) { 7957 // If this is a multiprocess provider, then just return its 7958 // info and allow the caller to instantiate it. Only do 7959 // this if the provider is the same user as the caller's 7960 // process, or can run as root (so can be in any process). 7961 return cpr.newHolder(null); 7962 } 7963 7964 if (DEBUG_PROVIDER) { 7965 RuntimeException e = new RuntimeException("here"); 7966 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7967 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7968 } 7969 7970 // This is single process, and our app is now connecting to it. 7971 // See if we are already in the process of launching this 7972 // provider. 7973 final int N = mLaunchingProviders.size(); 7974 int i; 7975 for (i=0; i<N; i++) { 7976 if (mLaunchingProviders.get(i) == cpr) { 7977 break; 7978 } 7979 } 7980 7981 // If the provider is not already being launched, then get it 7982 // started. 7983 if (i >= N) { 7984 final long origId = Binder.clearCallingIdentity(); 7985 7986 try { 7987 // Content provider is now in use, its package can't be stopped. 7988 try { 7989 AppGlobals.getPackageManager().setPackageStoppedState( 7990 cpr.appInfo.packageName, false, userId); 7991 } catch (RemoteException e) { 7992 } catch (IllegalArgumentException e) { 7993 Slog.w(TAG, "Failed trying to unstop package " 7994 + cpr.appInfo.packageName + ": " + e); 7995 } 7996 7997 // Use existing process if already started 7998 ProcessRecord proc = getProcessRecordLocked( 7999 cpi.processName, cpr.appInfo.uid, false); 8000 if (proc != null && proc.thread != null) { 8001 if (DEBUG_PROVIDER) { 8002 Slog.d(TAG, "Installing in existing process " + proc); 8003 } 8004 proc.pubProviders.put(cpi.name, cpr); 8005 try { 8006 proc.thread.scheduleInstallProvider(cpi); 8007 } catch (RemoteException e) { 8008 } 8009 } else { 8010 proc = startProcessLocked(cpi.processName, 8011 cpr.appInfo, false, 0, "content provider", 8012 new ComponentName(cpi.applicationInfo.packageName, 8013 cpi.name), false, false, false); 8014 if (proc == null) { 8015 Slog.w(TAG, "Unable to launch app " 8016 + cpi.applicationInfo.packageName + "/" 8017 + cpi.applicationInfo.uid + " for provider " 8018 + name + ": process is bad"); 8019 return null; 8020 } 8021 } 8022 cpr.launchingApp = proc; 8023 mLaunchingProviders.add(cpr); 8024 } finally { 8025 Binder.restoreCallingIdentity(origId); 8026 } 8027 } 8028 8029 // Make sure the provider is published (the same provider class 8030 // may be published under multiple names). 8031 if (firstClass) { 8032 mProviderMap.putProviderByClass(comp, cpr); 8033 } 8034 8035 mProviderMap.putProviderByName(name, cpr); 8036 conn = incProviderCountLocked(r, cpr, token, stable); 8037 if (conn != null) { 8038 conn.waiting = true; 8039 } 8040 } 8041 } 8042 8043 // Wait for the provider to be published... 8044 synchronized (cpr) { 8045 while (cpr.provider == null) { 8046 if (cpr.launchingApp == null) { 8047 Slog.w(TAG, "Unable to launch app " 8048 + cpi.applicationInfo.packageName + "/" 8049 + cpi.applicationInfo.uid + " for provider " 8050 + name + ": launching app became null"); 8051 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8052 UserHandle.getUserId(cpi.applicationInfo.uid), 8053 cpi.applicationInfo.packageName, 8054 cpi.applicationInfo.uid, name); 8055 return null; 8056 } 8057 try { 8058 if (DEBUG_MU) { 8059 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8060 + cpr.launchingApp); 8061 } 8062 if (conn != null) { 8063 conn.waiting = true; 8064 } 8065 cpr.wait(); 8066 } catch (InterruptedException ex) { 8067 } finally { 8068 if (conn != null) { 8069 conn.waiting = false; 8070 } 8071 } 8072 } 8073 } 8074 return cpr != null ? cpr.newHolder(conn) : null; 8075 } 8076 8077 public final ContentProviderHolder getContentProvider( 8078 IApplicationThread caller, String name, int userId, boolean stable) { 8079 enforceNotIsolatedCaller("getContentProvider"); 8080 if (caller == null) { 8081 String msg = "null IApplicationThread when getting content provider " 8082 + name; 8083 Slog.w(TAG, msg); 8084 throw new SecurityException(msg); 8085 } 8086 8087 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8088 false, true, "getContentProvider", null); 8089 return getContentProviderImpl(caller, name, null, stable, userId); 8090 } 8091 8092 public ContentProviderHolder getContentProviderExternal( 8093 String name, int userId, IBinder token) { 8094 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8095 "Do not have permission in call getContentProviderExternal()"); 8096 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8097 false, true, "getContentProvider", null); 8098 return getContentProviderExternalUnchecked(name, token, userId); 8099 } 8100 8101 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8102 IBinder token, int userId) { 8103 return getContentProviderImpl(null, name, token, true, userId); 8104 } 8105 8106 /** 8107 * Drop a content provider from a ProcessRecord's bookkeeping 8108 */ 8109 public void removeContentProvider(IBinder connection, boolean stable) { 8110 enforceNotIsolatedCaller("removeContentProvider"); 8111 long ident = Binder.clearCallingIdentity(); 8112 try { 8113 synchronized (this) { 8114 ContentProviderConnection conn; 8115 try { 8116 conn = (ContentProviderConnection)connection; 8117 } catch (ClassCastException e) { 8118 String msg ="removeContentProvider: " + connection 8119 + " not a ContentProviderConnection"; 8120 Slog.w(TAG, msg); 8121 throw new IllegalArgumentException(msg); 8122 } 8123 if (conn == null) { 8124 throw new NullPointerException("connection is null"); 8125 } 8126 if (decProviderCountLocked(conn, null, null, stable)) { 8127 updateOomAdjLocked(); 8128 } 8129 } 8130 } finally { 8131 Binder.restoreCallingIdentity(ident); 8132 } 8133 } 8134 8135 public void removeContentProviderExternal(String name, IBinder token) { 8136 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8137 "Do not have permission in call removeContentProviderExternal()"); 8138 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8139 } 8140 8141 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8142 synchronized (this) { 8143 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8144 if(cpr == null) { 8145 //remove from mProvidersByClass 8146 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8147 return; 8148 } 8149 8150 //update content provider record entry info 8151 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8152 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8153 if (localCpr.hasExternalProcessHandles()) { 8154 if (localCpr.removeExternalProcessHandleLocked(token)) { 8155 updateOomAdjLocked(); 8156 } else { 8157 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8158 + " with no external reference for token: " 8159 + token + "."); 8160 } 8161 } else { 8162 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8163 + " with no external references."); 8164 } 8165 } 8166 } 8167 8168 public final void publishContentProviders(IApplicationThread caller, 8169 List<ContentProviderHolder> providers) { 8170 if (providers == null) { 8171 return; 8172 } 8173 8174 enforceNotIsolatedCaller("publishContentProviders"); 8175 synchronized (this) { 8176 final ProcessRecord r = getRecordForAppLocked(caller); 8177 if (DEBUG_MU) 8178 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8179 if (r == null) { 8180 throw new SecurityException( 8181 "Unable to find app for caller " + caller 8182 + " (pid=" + Binder.getCallingPid() 8183 + ") when publishing content providers"); 8184 } 8185 8186 final long origId = Binder.clearCallingIdentity(); 8187 8188 final int N = providers.size(); 8189 for (int i=0; i<N; i++) { 8190 ContentProviderHolder src = providers.get(i); 8191 if (src == null || src.info == null || src.provider == null) { 8192 continue; 8193 } 8194 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8195 if (DEBUG_MU) 8196 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8197 if (dst != null) { 8198 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8199 mProviderMap.putProviderByClass(comp, dst); 8200 String names[] = dst.info.authority.split(";"); 8201 for (int j = 0; j < names.length; j++) { 8202 mProviderMap.putProviderByName(names[j], dst); 8203 } 8204 8205 int NL = mLaunchingProviders.size(); 8206 int j; 8207 for (j=0; j<NL; j++) { 8208 if (mLaunchingProviders.get(j) == dst) { 8209 mLaunchingProviders.remove(j); 8210 j--; 8211 NL--; 8212 } 8213 } 8214 synchronized (dst) { 8215 dst.provider = src.provider; 8216 dst.proc = r; 8217 dst.notifyAll(); 8218 } 8219 updateOomAdjLocked(r); 8220 } 8221 } 8222 8223 Binder.restoreCallingIdentity(origId); 8224 } 8225 } 8226 8227 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8228 ContentProviderConnection conn; 8229 try { 8230 conn = (ContentProviderConnection)connection; 8231 } catch (ClassCastException e) { 8232 String msg ="refContentProvider: " + connection 8233 + " not a ContentProviderConnection"; 8234 Slog.w(TAG, msg); 8235 throw new IllegalArgumentException(msg); 8236 } 8237 if (conn == null) { 8238 throw new NullPointerException("connection is null"); 8239 } 8240 8241 synchronized (this) { 8242 if (stable > 0) { 8243 conn.numStableIncs += stable; 8244 } 8245 stable = conn.stableCount + stable; 8246 if (stable < 0) { 8247 throw new IllegalStateException("stableCount < 0: " + stable); 8248 } 8249 8250 if (unstable > 0) { 8251 conn.numUnstableIncs += unstable; 8252 } 8253 unstable = conn.unstableCount + unstable; 8254 if (unstable < 0) { 8255 throw new IllegalStateException("unstableCount < 0: " + unstable); 8256 } 8257 8258 if ((stable+unstable) <= 0) { 8259 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8260 + stable + " unstable=" + unstable); 8261 } 8262 conn.stableCount = stable; 8263 conn.unstableCount = unstable; 8264 return !conn.dead; 8265 } 8266 } 8267 8268 public void unstableProviderDied(IBinder connection) { 8269 ContentProviderConnection conn; 8270 try { 8271 conn = (ContentProviderConnection)connection; 8272 } catch (ClassCastException e) { 8273 String msg ="refContentProvider: " + connection 8274 + " not a ContentProviderConnection"; 8275 Slog.w(TAG, msg); 8276 throw new IllegalArgumentException(msg); 8277 } 8278 if (conn == null) { 8279 throw new NullPointerException("connection is null"); 8280 } 8281 8282 // Safely retrieve the content provider associated with the connection. 8283 IContentProvider provider; 8284 synchronized (this) { 8285 provider = conn.provider.provider; 8286 } 8287 8288 if (provider == null) { 8289 // Um, yeah, we're way ahead of you. 8290 return; 8291 } 8292 8293 // Make sure the caller is being honest with us. 8294 if (provider.asBinder().pingBinder()) { 8295 // Er, no, still looks good to us. 8296 synchronized (this) { 8297 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8298 + " says " + conn + " died, but we don't agree"); 8299 return; 8300 } 8301 } 8302 8303 // Well look at that! It's dead! 8304 synchronized (this) { 8305 if (conn.provider.provider != provider) { 8306 // But something changed... good enough. 8307 return; 8308 } 8309 8310 ProcessRecord proc = conn.provider.proc; 8311 if (proc == null || proc.thread == null) { 8312 // Seems like the process is already cleaned up. 8313 return; 8314 } 8315 8316 // As far as we're concerned, this is just like receiving a 8317 // death notification... just a bit prematurely. 8318 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8319 + ") early provider death"); 8320 final long ident = Binder.clearCallingIdentity(); 8321 try { 8322 appDiedLocked(proc, proc.pid, proc.thread); 8323 } finally { 8324 Binder.restoreCallingIdentity(ident); 8325 } 8326 } 8327 } 8328 8329 @Override 8330 public void appNotRespondingViaProvider(IBinder connection) { 8331 enforceCallingPermission( 8332 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8333 8334 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8335 if (conn == null) { 8336 Slog.w(TAG, "ContentProviderConnection is null"); 8337 return; 8338 } 8339 8340 final ProcessRecord host = conn.provider.proc; 8341 if (host == null) { 8342 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8343 return; 8344 } 8345 8346 final long token = Binder.clearCallingIdentity(); 8347 try { 8348 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8349 } finally { 8350 Binder.restoreCallingIdentity(token); 8351 } 8352 } 8353 8354 public final void installSystemProviders() { 8355 List<ProviderInfo> providers; 8356 synchronized (this) { 8357 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8358 providers = generateApplicationProvidersLocked(app); 8359 if (providers != null) { 8360 for (int i=providers.size()-1; i>=0; i--) { 8361 ProviderInfo pi = (ProviderInfo)providers.get(i); 8362 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8363 Slog.w(TAG, "Not installing system proc provider " + pi.name 8364 + ": not system .apk"); 8365 providers.remove(i); 8366 } 8367 } 8368 } 8369 } 8370 if (providers != null) { 8371 mSystemThread.installSystemProviders(providers); 8372 } 8373 8374 mCoreSettingsObserver = new CoreSettingsObserver(this); 8375 8376 mUsageStatsService.monitorPackages(); 8377 } 8378 8379 /** 8380 * Allows app to retrieve the MIME type of a URI without having permission 8381 * to access its content provider. 8382 * 8383 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8384 * 8385 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8386 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8387 */ 8388 public String getProviderMimeType(Uri uri, int userId) { 8389 enforceNotIsolatedCaller("getProviderMimeType"); 8390 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8391 userId, false, true, "getProviderMimeType", null); 8392 final String name = uri.getAuthority(); 8393 final long ident = Binder.clearCallingIdentity(); 8394 ContentProviderHolder holder = null; 8395 8396 try { 8397 holder = getContentProviderExternalUnchecked(name, null, userId); 8398 if (holder != null) { 8399 return holder.provider.getType(uri); 8400 } 8401 } catch (RemoteException e) { 8402 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8403 return null; 8404 } finally { 8405 if (holder != null) { 8406 removeContentProviderExternalUnchecked(name, null, userId); 8407 } 8408 Binder.restoreCallingIdentity(ident); 8409 } 8410 8411 return null; 8412 } 8413 8414 // ========================================================= 8415 // GLOBAL MANAGEMENT 8416 // ========================================================= 8417 8418 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8419 boolean isolated) { 8420 String proc = customProcess != null ? customProcess : info.processName; 8421 BatteryStatsImpl.Uid.Proc ps = null; 8422 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8423 int uid = info.uid; 8424 if (isolated) { 8425 int userId = UserHandle.getUserId(uid); 8426 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8427 while (true) { 8428 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8429 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8430 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8431 } 8432 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8433 mNextIsolatedProcessUid++; 8434 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8435 // No process for this uid, use it. 8436 break; 8437 } 8438 stepsLeft--; 8439 if (stepsLeft <= 0) { 8440 return null; 8441 } 8442 } 8443 } 8444 return new ProcessRecord(stats, info, proc, uid); 8445 } 8446 8447 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8448 ProcessRecord app; 8449 if (!isolated) { 8450 app = getProcessRecordLocked(info.processName, info.uid, true); 8451 } else { 8452 app = null; 8453 } 8454 8455 if (app == null) { 8456 app = newProcessRecordLocked(info, null, isolated); 8457 mProcessNames.put(info.processName, app.uid, app); 8458 if (isolated) { 8459 mIsolatedProcesses.put(app.uid, app); 8460 } 8461 updateLruProcessLocked(app, false, null); 8462 updateOomAdjLocked(); 8463 } 8464 8465 // This package really, really can not be stopped. 8466 try { 8467 AppGlobals.getPackageManager().setPackageStoppedState( 8468 info.packageName, false, UserHandle.getUserId(app.uid)); 8469 } catch (RemoteException e) { 8470 } catch (IllegalArgumentException e) { 8471 Slog.w(TAG, "Failed trying to unstop package " 8472 + info.packageName + ": " + e); 8473 } 8474 8475 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8476 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8477 app.persistent = true; 8478 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8479 } 8480 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8481 mPersistentStartingProcesses.add(app); 8482 startProcessLocked(app, "added application", app.processName); 8483 } 8484 8485 return app; 8486 } 8487 8488 public void unhandledBack() { 8489 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8490 "unhandledBack()"); 8491 8492 synchronized(this) { 8493 final long origId = Binder.clearCallingIdentity(); 8494 try { 8495 getFocusedStack().unhandledBackLocked(); 8496 } finally { 8497 Binder.restoreCallingIdentity(origId); 8498 } 8499 } 8500 } 8501 8502 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8503 enforceNotIsolatedCaller("openContentUri"); 8504 final int userId = UserHandle.getCallingUserId(); 8505 String name = uri.getAuthority(); 8506 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8507 ParcelFileDescriptor pfd = null; 8508 if (cph != null) { 8509 // We record the binder invoker's uid in thread-local storage before 8510 // going to the content provider to open the file. Later, in the code 8511 // that handles all permissions checks, we look for this uid and use 8512 // that rather than the Activity Manager's own uid. The effect is that 8513 // we do the check against the caller's permissions even though it looks 8514 // to the content provider like the Activity Manager itself is making 8515 // the request. 8516 sCallerIdentity.set(new Identity( 8517 Binder.getCallingPid(), Binder.getCallingUid())); 8518 try { 8519 pfd = cph.provider.openFile(null, uri, "r", null); 8520 } catch (FileNotFoundException e) { 8521 // do nothing; pfd will be returned null 8522 } finally { 8523 // Ensure that whatever happens, we clean up the identity state 8524 sCallerIdentity.remove(); 8525 } 8526 8527 // We've got the fd now, so we're done with the provider. 8528 removeContentProviderExternalUnchecked(name, null, userId); 8529 } else { 8530 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8531 } 8532 return pfd; 8533 } 8534 8535 // Actually is sleeping or shutting down or whatever else in the future 8536 // is an inactive state. 8537 public boolean isSleepingOrShuttingDown() { 8538 return mSleeping || mShuttingDown; 8539 } 8540 8541 public boolean isSleeping() { 8542 return mSleeping; 8543 } 8544 8545 void goingToSleep() { 8546 synchronized(this) { 8547 mWentToSleep = true; 8548 updateEventDispatchingLocked(); 8549 goToSleepIfNeededLocked(); 8550 } 8551 } 8552 8553 void finishRunningVoiceLocked() { 8554 if (mRunningVoice) { 8555 mRunningVoice = false; 8556 goToSleepIfNeededLocked(); 8557 } 8558 } 8559 8560 void goToSleepIfNeededLocked() { 8561 if (mWentToSleep && !mRunningVoice) { 8562 if (!mSleeping) { 8563 mSleeping = true; 8564 mStackSupervisor.goingToSleepLocked(); 8565 8566 // Initialize the wake times of all processes. 8567 checkExcessivePowerUsageLocked(false); 8568 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8569 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8570 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8571 } 8572 } 8573 } 8574 8575 @Override 8576 public boolean shutdown(int timeout) { 8577 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8578 != PackageManager.PERMISSION_GRANTED) { 8579 throw new SecurityException("Requires permission " 8580 + android.Manifest.permission.SHUTDOWN); 8581 } 8582 8583 boolean timedout = false; 8584 8585 synchronized(this) { 8586 mShuttingDown = true; 8587 updateEventDispatchingLocked(); 8588 timedout = mStackSupervisor.shutdownLocked(timeout); 8589 } 8590 8591 mAppOpsService.shutdown(); 8592 mUsageStatsService.shutdown(); 8593 mBatteryStatsService.shutdown(); 8594 synchronized (this) { 8595 mProcessStats.shutdownLocked(); 8596 } 8597 8598 return timedout; 8599 } 8600 8601 public final void activitySlept(IBinder token) { 8602 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8603 8604 final long origId = Binder.clearCallingIdentity(); 8605 8606 synchronized (this) { 8607 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8608 if (r != null) { 8609 mStackSupervisor.activitySleptLocked(r); 8610 } 8611 } 8612 8613 Binder.restoreCallingIdentity(origId); 8614 } 8615 8616 void logLockScreen(String msg) { 8617 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8618 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8619 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8620 mStackSupervisor.mDismissKeyguardOnNextActivity); 8621 } 8622 8623 private void comeOutOfSleepIfNeededLocked() { 8624 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8625 if (mSleeping) { 8626 mSleeping = false; 8627 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8628 } 8629 } 8630 } 8631 8632 void wakingUp() { 8633 synchronized(this) { 8634 mWentToSleep = false; 8635 updateEventDispatchingLocked(); 8636 comeOutOfSleepIfNeededLocked(); 8637 } 8638 } 8639 8640 void startRunningVoiceLocked() { 8641 if (!mRunningVoice) { 8642 mRunningVoice = true; 8643 comeOutOfSleepIfNeededLocked(); 8644 } 8645 } 8646 8647 private void updateEventDispatchingLocked() { 8648 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8649 } 8650 8651 public void setLockScreenShown(boolean shown) { 8652 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8653 != PackageManager.PERMISSION_GRANTED) { 8654 throw new SecurityException("Requires permission " 8655 + android.Manifest.permission.DEVICE_POWER); 8656 } 8657 8658 synchronized(this) { 8659 long ident = Binder.clearCallingIdentity(); 8660 try { 8661 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8662 mLockScreenShown = shown; 8663 comeOutOfSleepIfNeededLocked(); 8664 } finally { 8665 Binder.restoreCallingIdentity(ident); 8666 } 8667 } 8668 } 8669 8670 public void stopAppSwitches() { 8671 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8672 != PackageManager.PERMISSION_GRANTED) { 8673 throw new SecurityException("Requires permission " 8674 + android.Manifest.permission.STOP_APP_SWITCHES); 8675 } 8676 8677 synchronized(this) { 8678 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8679 + APP_SWITCH_DELAY_TIME; 8680 mDidAppSwitch = false; 8681 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8682 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8683 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8684 } 8685 } 8686 8687 public void resumeAppSwitches() { 8688 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8689 != PackageManager.PERMISSION_GRANTED) { 8690 throw new SecurityException("Requires permission " 8691 + android.Manifest.permission.STOP_APP_SWITCHES); 8692 } 8693 8694 synchronized(this) { 8695 // Note that we don't execute any pending app switches... we will 8696 // let those wait until either the timeout, or the next start 8697 // activity request. 8698 mAppSwitchesAllowedTime = 0; 8699 } 8700 } 8701 8702 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8703 String name) { 8704 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8705 return true; 8706 } 8707 8708 final int perm = checkComponentPermission( 8709 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8710 callingUid, -1, true); 8711 if (perm == PackageManager.PERMISSION_GRANTED) { 8712 return true; 8713 } 8714 8715 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8716 return false; 8717 } 8718 8719 public void setDebugApp(String packageName, boolean waitForDebugger, 8720 boolean persistent) { 8721 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8722 "setDebugApp()"); 8723 8724 long ident = Binder.clearCallingIdentity(); 8725 try { 8726 // Note that this is not really thread safe if there are multiple 8727 // callers into it at the same time, but that's not a situation we 8728 // care about. 8729 if (persistent) { 8730 final ContentResolver resolver = mContext.getContentResolver(); 8731 Settings.Global.putString( 8732 resolver, Settings.Global.DEBUG_APP, 8733 packageName); 8734 Settings.Global.putInt( 8735 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8736 waitForDebugger ? 1 : 0); 8737 } 8738 8739 synchronized (this) { 8740 if (!persistent) { 8741 mOrigDebugApp = mDebugApp; 8742 mOrigWaitForDebugger = mWaitForDebugger; 8743 } 8744 mDebugApp = packageName; 8745 mWaitForDebugger = waitForDebugger; 8746 mDebugTransient = !persistent; 8747 if (packageName != null) { 8748 forceStopPackageLocked(packageName, -1, false, false, true, true, 8749 false, UserHandle.USER_ALL, "set debug app"); 8750 } 8751 } 8752 } finally { 8753 Binder.restoreCallingIdentity(ident); 8754 } 8755 } 8756 8757 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8758 synchronized (this) { 8759 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8760 if (!isDebuggable) { 8761 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8762 throw new SecurityException("Process not debuggable: " + app.packageName); 8763 } 8764 } 8765 8766 mOpenGlTraceApp = processName; 8767 } 8768 } 8769 8770 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8771 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8772 synchronized (this) { 8773 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8774 if (!isDebuggable) { 8775 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8776 throw new SecurityException("Process not debuggable: " + app.packageName); 8777 } 8778 } 8779 mProfileApp = processName; 8780 mProfileFile = profileFile; 8781 if (mProfileFd != null) { 8782 try { 8783 mProfileFd.close(); 8784 } catch (IOException e) { 8785 } 8786 mProfileFd = null; 8787 } 8788 mProfileFd = profileFd; 8789 mProfileType = 0; 8790 mAutoStopProfiler = autoStopProfiler; 8791 } 8792 } 8793 8794 @Override 8795 public void setAlwaysFinish(boolean enabled) { 8796 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8797 "setAlwaysFinish()"); 8798 8799 Settings.Global.putInt( 8800 mContext.getContentResolver(), 8801 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8802 8803 synchronized (this) { 8804 mAlwaysFinishActivities = enabled; 8805 } 8806 } 8807 8808 @Override 8809 public void setActivityController(IActivityController controller) { 8810 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8811 "setActivityController()"); 8812 synchronized (this) { 8813 mController = controller; 8814 Watchdog.getInstance().setActivityController(controller); 8815 } 8816 } 8817 8818 @Override 8819 public void setUserIsMonkey(boolean userIsMonkey) { 8820 synchronized (this) { 8821 synchronized (mPidsSelfLocked) { 8822 final int callingPid = Binder.getCallingPid(); 8823 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8824 if (precessRecord == null) { 8825 throw new SecurityException("Unknown process: " + callingPid); 8826 } 8827 if (precessRecord.instrumentationUiAutomationConnection == null) { 8828 throw new SecurityException("Only an instrumentation process " 8829 + "with a UiAutomation can call setUserIsMonkey"); 8830 } 8831 } 8832 mUserIsMonkey = userIsMonkey; 8833 } 8834 } 8835 8836 @Override 8837 public boolean isUserAMonkey() { 8838 synchronized (this) { 8839 // If there is a controller also implies the user is a monkey. 8840 return (mUserIsMonkey || mController != null); 8841 } 8842 } 8843 8844 public void requestBugReport() { 8845 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8846 SystemProperties.set("ctl.start", "bugreport"); 8847 } 8848 8849 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8850 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8851 } 8852 8853 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8854 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8855 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8856 } 8857 return KEY_DISPATCHING_TIMEOUT; 8858 } 8859 8860 @Override 8861 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8862 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8863 != PackageManager.PERMISSION_GRANTED) { 8864 throw new SecurityException("Requires permission " 8865 + android.Manifest.permission.FILTER_EVENTS); 8866 } 8867 ProcessRecord proc; 8868 long timeout; 8869 synchronized (this) { 8870 synchronized (mPidsSelfLocked) { 8871 proc = mPidsSelfLocked.get(pid); 8872 } 8873 timeout = getInputDispatchingTimeoutLocked(proc); 8874 } 8875 8876 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8877 return -1; 8878 } 8879 8880 return timeout; 8881 } 8882 8883 /** 8884 * Handle input dispatching timeouts. 8885 * Returns whether input dispatching should be aborted or not. 8886 */ 8887 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8888 final ActivityRecord activity, final ActivityRecord parent, 8889 final boolean aboveSystem, String reason) { 8890 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8891 != PackageManager.PERMISSION_GRANTED) { 8892 throw new SecurityException("Requires permission " 8893 + android.Manifest.permission.FILTER_EVENTS); 8894 } 8895 8896 final String annotation; 8897 if (reason == null) { 8898 annotation = "Input dispatching timed out"; 8899 } else { 8900 annotation = "Input dispatching timed out (" + reason + ")"; 8901 } 8902 8903 if (proc != null) { 8904 synchronized (this) { 8905 if (proc.debugging) { 8906 return false; 8907 } 8908 8909 if (mDidDexOpt) { 8910 // Give more time since we were dexopting. 8911 mDidDexOpt = false; 8912 return false; 8913 } 8914 8915 if (proc.instrumentationClass != null) { 8916 Bundle info = new Bundle(); 8917 info.putString("shortMsg", "keyDispatchingTimedOut"); 8918 info.putString("longMsg", annotation); 8919 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8920 return true; 8921 } 8922 } 8923 mHandler.post(new Runnable() { 8924 @Override 8925 public void run() { 8926 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8927 } 8928 }); 8929 } 8930 8931 return true; 8932 } 8933 8934 public Bundle getAssistContextExtras(int requestType) { 8935 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8936 "getAssistContextExtras()"); 8937 PendingAssistExtras pae; 8938 Bundle extras = new Bundle(); 8939 synchronized (this) { 8940 ActivityRecord activity = getFocusedStack().mResumedActivity; 8941 if (activity == null) { 8942 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8943 return null; 8944 } 8945 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8946 if (activity.app == null || activity.app.thread == null) { 8947 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8948 return extras; 8949 } 8950 if (activity.app.pid == Binder.getCallingPid()) { 8951 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8952 return extras; 8953 } 8954 pae = new PendingAssistExtras(activity); 8955 try { 8956 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8957 requestType); 8958 mPendingAssistExtras.add(pae); 8959 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8960 } catch (RemoteException e) { 8961 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8962 return extras; 8963 } 8964 } 8965 synchronized (pae) { 8966 while (!pae.haveResult) { 8967 try { 8968 pae.wait(); 8969 } catch (InterruptedException e) { 8970 } 8971 } 8972 if (pae.result != null) { 8973 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8974 } 8975 } 8976 synchronized (this) { 8977 mPendingAssistExtras.remove(pae); 8978 mHandler.removeCallbacks(pae); 8979 } 8980 return extras; 8981 } 8982 8983 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8984 PendingAssistExtras pae = (PendingAssistExtras)token; 8985 synchronized (pae) { 8986 pae.result = extras; 8987 pae.haveResult = true; 8988 pae.notifyAll(); 8989 } 8990 } 8991 8992 public void registerProcessObserver(IProcessObserver observer) { 8993 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8994 "registerProcessObserver()"); 8995 synchronized (this) { 8996 mProcessObservers.register(observer); 8997 } 8998 } 8999 9000 @Override 9001 public void unregisterProcessObserver(IProcessObserver observer) { 9002 synchronized (this) { 9003 mProcessObservers.unregister(observer); 9004 } 9005 } 9006 9007 @Override 9008 public boolean convertFromTranslucent(IBinder token) { 9009 final long origId = Binder.clearCallingIdentity(); 9010 try { 9011 synchronized (this) { 9012 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9013 if (r == null) { 9014 return false; 9015 } 9016 if (r.changeWindowTranslucency(true)) { 9017 mWindowManager.setAppFullscreen(token, true); 9018 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9019 return true; 9020 } 9021 return false; 9022 } 9023 } finally { 9024 Binder.restoreCallingIdentity(origId); 9025 } 9026 } 9027 9028 @Override 9029 public boolean convertToTranslucent(IBinder token) { 9030 final long origId = Binder.clearCallingIdentity(); 9031 try { 9032 synchronized (this) { 9033 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9034 if (r == null) { 9035 return false; 9036 } 9037 if (r.changeWindowTranslucency(false)) { 9038 r.task.stack.convertToTranslucent(r); 9039 mWindowManager.setAppFullscreen(token, false); 9040 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9041 return true; 9042 } 9043 return false; 9044 } 9045 } finally { 9046 Binder.restoreCallingIdentity(origId); 9047 } 9048 } 9049 9050 @Override 9051 public void setImmersive(IBinder token, boolean immersive) { 9052 synchronized(this) { 9053 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9054 if (r == null) { 9055 throw new IllegalArgumentException(); 9056 } 9057 r.immersive = immersive; 9058 9059 // update associated state if we're frontmost 9060 if (r == mFocusedActivity) { 9061 if (DEBUG_IMMERSIVE) { 9062 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9063 } 9064 applyUpdateLockStateLocked(r); 9065 } 9066 } 9067 } 9068 9069 @Override 9070 public boolean isImmersive(IBinder token) { 9071 synchronized (this) { 9072 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9073 if (r == null) { 9074 throw new IllegalArgumentException(); 9075 } 9076 return r.immersive; 9077 } 9078 } 9079 9080 public boolean isTopActivityImmersive() { 9081 enforceNotIsolatedCaller("startActivity"); 9082 synchronized (this) { 9083 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9084 return (r != null) ? r.immersive : false; 9085 } 9086 } 9087 9088 public final void enterSafeMode() { 9089 synchronized(this) { 9090 // It only makes sense to do this before the system is ready 9091 // and started launching other packages. 9092 if (!mSystemReady) { 9093 try { 9094 AppGlobals.getPackageManager().enterSafeMode(); 9095 } catch (RemoteException e) { 9096 } 9097 } 9098 9099 mSafeMode = true; 9100 } 9101 } 9102 9103 public final void showSafeModeOverlay() { 9104 View v = LayoutInflater.from(mContext).inflate( 9105 com.android.internal.R.layout.safe_mode, null); 9106 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9107 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9108 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9109 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9110 lp.gravity = Gravity.BOTTOM | Gravity.START; 9111 lp.format = v.getBackground().getOpacity(); 9112 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9113 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9114 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9115 ((WindowManager)mContext.getSystemService( 9116 Context.WINDOW_SERVICE)).addView(v, lp); 9117 } 9118 9119 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9120 if (!(sender instanceof PendingIntentRecord)) { 9121 return; 9122 } 9123 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9124 synchronized (stats) { 9125 if (mBatteryStatsService.isOnBattery()) { 9126 mBatteryStatsService.enforceCallingPermission(); 9127 PendingIntentRecord rec = (PendingIntentRecord)sender; 9128 int MY_UID = Binder.getCallingUid(); 9129 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9130 BatteryStatsImpl.Uid.Pkg pkg = 9131 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9132 sourcePkg != null ? sourcePkg : rec.key.packageName); 9133 pkg.incWakeupsLocked(); 9134 } 9135 } 9136 } 9137 9138 public boolean killPids(int[] pids, String pReason, boolean secure) { 9139 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9140 throw new SecurityException("killPids only available to the system"); 9141 } 9142 String reason = (pReason == null) ? "Unknown" : pReason; 9143 // XXX Note: don't acquire main activity lock here, because the window 9144 // manager calls in with its locks held. 9145 9146 boolean killed = false; 9147 synchronized (mPidsSelfLocked) { 9148 int[] types = new int[pids.length]; 9149 int worstType = 0; 9150 for (int i=0; i<pids.length; i++) { 9151 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9152 if (proc != null) { 9153 int type = proc.setAdj; 9154 types[i] = type; 9155 if (type > worstType) { 9156 worstType = type; 9157 } 9158 } 9159 } 9160 9161 // If the worst oom_adj is somewhere in the cached proc LRU range, 9162 // then constrain it so we will kill all cached procs. 9163 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9164 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9165 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9166 } 9167 9168 // If this is not a secure call, don't let it kill processes that 9169 // are important. 9170 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9171 worstType = ProcessList.SERVICE_ADJ; 9172 } 9173 9174 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9175 for (int i=0; i<pids.length; i++) { 9176 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9177 if (proc == null) { 9178 continue; 9179 } 9180 int adj = proc.setAdj; 9181 if (adj >= worstType && !proc.killedByAm) { 9182 killUnneededProcessLocked(proc, reason); 9183 killed = true; 9184 } 9185 } 9186 } 9187 return killed; 9188 } 9189 9190 @Override 9191 public void killUid(int uid, String reason) { 9192 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9193 throw new SecurityException("killUid only available to the system"); 9194 } 9195 synchronized (this) { 9196 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9197 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9198 reason != null ? reason : "kill uid"); 9199 } 9200 } 9201 9202 @Override 9203 public boolean killProcessesBelowForeground(String reason) { 9204 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9205 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9206 } 9207 9208 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9209 } 9210 9211 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9212 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9213 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9214 } 9215 9216 boolean killed = false; 9217 synchronized (mPidsSelfLocked) { 9218 final int size = mPidsSelfLocked.size(); 9219 for (int i = 0; i < size; i++) { 9220 final int pid = mPidsSelfLocked.keyAt(i); 9221 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9222 if (proc == null) continue; 9223 9224 final int adj = proc.setAdj; 9225 if (adj > belowAdj && !proc.killedByAm) { 9226 killUnneededProcessLocked(proc, reason); 9227 killed = true; 9228 } 9229 } 9230 } 9231 return killed; 9232 } 9233 9234 @Override 9235 public void hang(final IBinder who, boolean allowRestart) { 9236 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9237 != PackageManager.PERMISSION_GRANTED) { 9238 throw new SecurityException("Requires permission " 9239 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9240 } 9241 9242 final IBinder.DeathRecipient death = new DeathRecipient() { 9243 @Override 9244 public void binderDied() { 9245 synchronized (this) { 9246 notifyAll(); 9247 } 9248 } 9249 }; 9250 9251 try { 9252 who.linkToDeath(death, 0); 9253 } catch (RemoteException e) { 9254 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9255 return; 9256 } 9257 9258 synchronized (this) { 9259 Watchdog.getInstance().setAllowRestart(allowRestart); 9260 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9261 synchronized (death) { 9262 while (who.isBinderAlive()) { 9263 try { 9264 death.wait(); 9265 } catch (InterruptedException e) { 9266 } 9267 } 9268 } 9269 Watchdog.getInstance().setAllowRestart(true); 9270 } 9271 } 9272 9273 @Override 9274 public void restart() { 9275 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9276 != PackageManager.PERMISSION_GRANTED) { 9277 throw new SecurityException("Requires permission " 9278 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9279 } 9280 9281 Log.i(TAG, "Sending shutdown broadcast..."); 9282 9283 BroadcastReceiver br = new BroadcastReceiver() { 9284 @Override public void onReceive(Context context, Intent intent) { 9285 // Now the broadcast is done, finish up the low-level shutdown. 9286 Log.i(TAG, "Shutting down activity manager..."); 9287 shutdown(10000); 9288 Log.i(TAG, "Shutdown complete, restarting!"); 9289 Process.killProcess(Process.myPid()); 9290 System.exit(10); 9291 } 9292 }; 9293 9294 // First send the high-level shut down broadcast. 9295 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9296 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9297 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9298 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9299 mContext.sendOrderedBroadcastAsUser(intent, 9300 UserHandle.ALL, null, br, mHandler, 0, null, null); 9301 */ 9302 br.onReceive(mContext, intent); 9303 } 9304 9305 private long getLowRamTimeSinceIdle(long now) { 9306 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9307 } 9308 9309 @Override 9310 public void performIdleMaintenance() { 9311 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9312 != PackageManager.PERMISSION_GRANTED) { 9313 throw new SecurityException("Requires permission " 9314 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9315 } 9316 9317 synchronized (this) { 9318 final long now = SystemClock.uptimeMillis(); 9319 final long timeSinceLastIdle = now - mLastIdleTime; 9320 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9321 mLastIdleTime = now; 9322 mLowRamTimeSinceLastIdle = 0; 9323 if (mLowRamStartTime != 0) { 9324 mLowRamStartTime = now; 9325 } 9326 9327 StringBuilder sb = new StringBuilder(128); 9328 sb.append("Idle maintenance over "); 9329 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9330 sb.append(" low RAM for "); 9331 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9332 Slog.i(TAG, sb.toString()); 9333 9334 // If at least 1/3 of our time since the last idle period has been spent 9335 // with RAM low, then we want to kill processes. 9336 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9337 9338 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9339 ProcessRecord proc = mLruProcesses.get(i); 9340 if (proc.notCachedSinceIdle) { 9341 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9342 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9343 if (doKilling && proc.initialIdlePss != 0 9344 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9345 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9346 + " from " + proc.initialIdlePss + ")"); 9347 } 9348 } 9349 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9350 proc.notCachedSinceIdle = true; 9351 proc.initialIdlePss = 0; 9352 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9353 isSleeping(), now); 9354 } 9355 } 9356 9357 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9358 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9359 } 9360 } 9361 9362 private void retrieveSettings() { 9363 final ContentResolver resolver = mContext.getContentResolver(); 9364 String debugApp = Settings.Global.getString( 9365 resolver, Settings.Global.DEBUG_APP); 9366 boolean waitForDebugger = Settings.Global.getInt( 9367 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9368 boolean alwaysFinishActivities = Settings.Global.getInt( 9369 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9370 boolean forceRtl = Settings.Global.getInt( 9371 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9372 // Transfer any global setting for forcing RTL layout, into a System Property 9373 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9374 9375 Configuration configuration = new Configuration(); 9376 Settings.System.getConfiguration(resolver, configuration); 9377 if (forceRtl) { 9378 // This will take care of setting the correct layout direction flags 9379 configuration.setLayoutDirection(configuration.locale); 9380 } 9381 9382 synchronized (this) { 9383 mDebugApp = mOrigDebugApp = debugApp; 9384 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9385 mAlwaysFinishActivities = alwaysFinishActivities; 9386 // This happens before any activities are started, so we can 9387 // change mConfiguration in-place. 9388 updateConfigurationLocked(configuration, null, false, true); 9389 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9390 } 9391 } 9392 9393 public boolean testIsSystemReady() { 9394 // no need to synchronize(this) just to read & return the value 9395 return mSystemReady; 9396 } 9397 9398 private static File getCalledPreBootReceiversFile() { 9399 File dataDir = Environment.getDataDirectory(); 9400 File systemDir = new File(dataDir, "system"); 9401 File fname = new File(systemDir, "called_pre_boots.dat"); 9402 return fname; 9403 } 9404 9405 static final int LAST_DONE_VERSION = 10000; 9406 9407 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9408 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9409 File file = getCalledPreBootReceiversFile(); 9410 FileInputStream fis = null; 9411 try { 9412 fis = new FileInputStream(file); 9413 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9414 int fvers = dis.readInt(); 9415 if (fvers == LAST_DONE_VERSION) { 9416 String vers = dis.readUTF(); 9417 String codename = dis.readUTF(); 9418 String build = dis.readUTF(); 9419 if (android.os.Build.VERSION.RELEASE.equals(vers) 9420 && android.os.Build.VERSION.CODENAME.equals(codename) 9421 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9422 int num = dis.readInt(); 9423 while (num > 0) { 9424 num--; 9425 String pkg = dis.readUTF(); 9426 String cls = dis.readUTF(); 9427 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9428 } 9429 } 9430 } 9431 } catch (FileNotFoundException e) { 9432 } catch (IOException e) { 9433 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9434 } finally { 9435 if (fis != null) { 9436 try { 9437 fis.close(); 9438 } catch (IOException e) { 9439 } 9440 } 9441 } 9442 return lastDoneReceivers; 9443 } 9444 9445 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9446 File file = getCalledPreBootReceiversFile(); 9447 FileOutputStream fos = null; 9448 DataOutputStream dos = null; 9449 try { 9450 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9451 fos = new FileOutputStream(file); 9452 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9453 dos.writeInt(LAST_DONE_VERSION); 9454 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9455 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9456 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9457 dos.writeInt(list.size()); 9458 for (int i=0; i<list.size(); i++) { 9459 dos.writeUTF(list.get(i).getPackageName()); 9460 dos.writeUTF(list.get(i).getClassName()); 9461 } 9462 } catch (IOException e) { 9463 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9464 file.delete(); 9465 } finally { 9466 FileUtils.sync(fos); 9467 if (dos != null) { 9468 try { 9469 dos.close(); 9470 } catch (IOException e) { 9471 // TODO Auto-generated catch block 9472 e.printStackTrace(); 9473 } 9474 } 9475 } 9476 } 9477 9478 public void systemReady(final Runnable goingCallback) { 9479 synchronized(this) { 9480 if (mSystemReady) { 9481 if (goingCallback != null) goingCallback.run(); 9482 return; 9483 } 9484 9485 // Check to see if there are any update receivers to run. 9486 if (!mDidUpdate) { 9487 if (mWaitingUpdate) { 9488 return; 9489 } 9490 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9491 List<ResolveInfo> ris = null; 9492 try { 9493 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9494 intent, null, 0, 0); 9495 } catch (RemoteException e) { 9496 } 9497 if (ris != null) { 9498 for (int i=ris.size()-1; i>=0; i--) { 9499 if ((ris.get(i).activityInfo.applicationInfo.flags 9500 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9501 ris.remove(i); 9502 } 9503 } 9504 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9505 9506 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9507 9508 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9509 for (int i=0; i<ris.size(); i++) { 9510 ActivityInfo ai = ris.get(i).activityInfo; 9511 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9512 if (lastDoneReceivers.contains(comp)) { 9513 // We already did the pre boot receiver for this app with the current 9514 // platform version, so don't do it again... 9515 ris.remove(i); 9516 i--; 9517 // ...however, do keep it as one that has been done, so we don't 9518 // forget about it when rewriting the file of last done receivers. 9519 doneReceivers.add(comp); 9520 } 9521 } 9522 9523 final int[] users = getUsersLocked(); 9524 for (int i=0; i<ris.size(); i++) { 9525 ActivityInfo ai = ris.get(i).activityInfo; 9526 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9527 doneReceivers.add(comp); 9528 intent.setComponent(comp); 9529 for (int j=0; j<users.length; j++) { 9530 IIntentReceiver finisher = null; 9531 if (i == ris.size()-1 && j == users.length-1) { 9532 finisher = new IIntentReceiver.Stub() { 9533 public void performReceive(Intent intent, int resultCode, 9534 String data, Bundle extras, boolean ordered, 9535 boolean sticky, int sendingUser) { 9536 // The raw IIntentReceiver interface is called 9537 // with the AM lock held, so redispatch to 9538 // execute our code without the lock. 9539 mHandler.post(new Runnable() { 9540 public void run() { 9541 synchronized (ActivityManagerService.this) { 9542 mDidUpdate = true; 9543 } 9544 writeLastDonePreBootReceivers(doneReceivers); 9545 showBootMessage(mContext.getText( 9546 R.string.android_upgrading_complete), 9547 false); 9548 systemReady(goingCallback); 9549 } 9550 }); 9551 } 9552 }; 9553 } 9554 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9555 + " for user " + users[j]); 9556 broadcastIntentLocked(null, null, intent, null, finisher, 9557 0, null, null, null, AppOpsManager.OP_NONE, 9558 true, false, MY_PID, Process.SYSTEM_UID, 9559 users[j]); 9560 if (finisher != null) { 9561 mWaitingUpdate = true; 9562 } 9563 } 9564 } 9565 } 9566 if (mWaitingUpdate) { 9567 return; 9568 } 9569 mDidUpdate = true; 9570 } 9571 9572 mAppOpsService.systemReady(); 9573 mSystemReady = true; 9574 } 9575 9576 ArrayList<ProcessRecord> procsToKill = null; 9577 synchronized(mPidsSelfLocked) { 9578 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9579 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9580 if (!isAllowedWhileBooting(proc.info)){ 9581 if (procsToKill == null) { 9582 procsToKill = new ArrayList<ProcessRecord>(); 9583 } 9584 procsToKill.add(proc); 9585 } 9586 } 9587 } 9588 9589 synchronized(this) { 9590 if (procsToKill != null) { 9591 for (int i=procsToKill.size()-1; i>=0; i--) { 9592 ProcessRecord proc = procsToKill.get(i); 9593 Slog.i(TAG, "Removing system update proc: " + proc); 9594 removeProcessLocked(proc, true, false, "system update done"); 9595 } 9596 } 9597 9598 // Now that we have cleaned up any update processes, we 9599 // are ready to start launching real processes and know that 9600 // we won't trample on them any more. 9601 mProcessesReady = true; 9602 } 9603 9604 Slog.i(TAG, "System now ready"); 9605 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9606 SystemClock.uptimeMillis()); 9607 9608 synchronized(this) { 9609 // Make sure we have no pre-ready processes sitting around. 9610 9611 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9612 ResolveInfo ri = mContext.getPackageManager() 9613 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9614 STOCK_PM_FLAGS); 9615 CharSequence errorMsg = null; 9616 if (ri != null) { 9617 ActivityInfo ai = ri.activityInfo; 9618 ApplicationInfo app = ai.applicationInfo; 9619 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9620 mTopAction = Intent.ACTION_FACTORY_TEST; 9621 mTopData = null; 9622 mTopComponent = new ComponentName(app.packageName, 9623 ai.name); 9624 } else { 9625 errorMsg = mContext.getResources().getText( 9626 com.android.internal.R.string.factorytest_not_system); 9627 } 9628 } else { 9629 errorMsg = mContext.getResources().getText( 9630 com.android.internal.R.string.factorytest_no_action); 9631 } 9632 if (errorMsg != null) { 9633 mTopAction = null; 9634 mTopData = null; 9635 mTopComponent = null; 9636 Message msg = Message.obtain(); 9637 msg.what = SHOW_FACTORY_ERROR_MSG; 9638 msg.getData().putCharSequence("msg", errorMsg); 9639 mHandler.sendMessage(msg); 9640 } 9641 } 9642 } 9643 9644 retrieveSettings(); 9645 9646 synchronized (this) { 9647 readGrantedUriPermissionsLocked(); 9648 } 9649 9650 if (goingCallback != null) goingCallback.run(); 9651 9652 mSystemServiceManager.startUser(mCurrentUserId); 9653 9654 synchronized (this) { 9655 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9656 try { 9657 List apps = AppGlobals.getPackageManager(). 9658 getPersistentApplications(STOCK_PM_FLAGS); 9659 if (apps != null) { 9660 int N = apps.size(); 9661 int i; 9662 for (i=0; i<N; i++) { 9663 ApplicationInfo info 9664 = (ApplicationInfo)apps.get(i); 9665 if (info != null && 9666 !info.packageName.equals("android")) { 9667 addAppLocked(info, false); 9668 } 9669 } 9670 } 9671 } catch (RemoteException ex) { 9672 // pm is in same process, this will never happen. 9673 } 9674 } 9675 9676 // Start up initial activity. 9677 mBooting = true; 9678 9679 try { 9680 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9681 Message msg = Message.obtain(); 9682 msg.what = SHOW_UID_ERROR_MSG; 9683 mHandler.sendMessage(msg); 9684 } 9685 } catch (RemoteException e) { 9686 } 9687 9688 long ident = Binder.clearCallingIdentity(); 9689 try { 9690 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9691 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9692 | Intent.FLAG_RECEIVER_FOREGROUND); 9693 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9694 broadcastIntentLocked(null, null, intent, 9695 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9696 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9697 intent = new Intent(Intent.ACTION_USER_STARTING); 9698 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9699 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9700 broadcastIntentLocked(null, null, intent, 9701 null, new IIntentReceiver.Stub() { 9702 @Override 9703 public void performReceive(Intent intent, int resultCode, String data, 9704 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9705 throws RemoteException { 9706 } 9707 }, 0, null, null, 9708 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9709 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9710 } catch (Throwable t) { 9711 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 9712 } finally { 9713 Binder.restoreCallingIdentity(ident); 9714 } 9715 mStackSupervisor.resumeTopActivitiesLocked(); 9716 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9717 } 9718 } 9719 9720 private boolean makeAppCrashingLocked(ProcessRecord app, 9721 String shortMsg, String longMsg, String stackTrace) { 9722 app.crashing = true; 9723 app.crashingReport = generateProcessError(app, 9724 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9725 startAppProblemLocked(app); 9726 app.stopFreezingAllLocked(); 9727 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9728 } 9729 9730 private void makeAppNotRespondingLocked(ProcessRecord app, 9731 String activity, String shortMsg, String longMsg) { 9732 app.notResponding = true; 9733 app.notRespondingReport = generateProcessError(app, 9734 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9735 activity, shortMsg, longMsg, null); 9736 startAppProblemLocked(app); 9737 app.stopFreezingAllLocked(); 9738 } 9739 9740 /** 9741 * Generate a process error record, suitable for attachment to a ProcessRecord. 9742 * 9743 * @param app The ProcessRecord in which the error occurred. 9744 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9745 * ActivityManager.AppErrorStateInfo 9746 * @param activity The activity associated with the crash, if known. 9747 * @param shortMsg Short message describing the crash. 9748 * @param longMsg Long message describing the crash. 9749 * @param stackTrace Full crash stack trace, may be null. 9750 * 9751 * @return Returns a fully-formed AppErrorStateInfo record. 9752 */ 9753 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9754 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9755 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9756 9757 report.condition = condition; 9758 report.processName = app.processName; 9759 report.pid = app.pid; 9760 report.uid = app.info.uid; 9761 report.tag = activity; 9762 report.shortMsg = shortMsg; 9763 report.longMsg = longMsg; 9764 report.stackTrace = stackTrace; 9765 9766 return report; 9767 } 9768 9769 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9770 synchronized (this) { 9771 app.crashing = false; 9772 app.crashingReport = null; 9773 app.notResponding = false; 9774 app.notRespondingReport = null; 9775 if (app.anrDialog == fromDialog) { 9776 app.anrDialog = null; 9777 } 9778 if (app.waitDialog == fromDialog) { 9779 app.waitDialog = null; 9780 } 9781 if (app.pid > 0 && app.pid != MY_PID) { 9782 handleAppCrashLocked(app, null, null, null); 9783 killUnneededProcessLocked(app, "user request after error"); 9784 } 9785 } 9786 } 9787 9788 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9789 String stackTrace) { 9790 long now = SystemClock.uptimeMillis(); 9791 9792 Long crashTime; 9793 if (!app.isolated) { 9794 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9795 } else { 9796 crashTime = null; 9797 } 9798 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9799 // This process loses! 9800 Slog.w(TAG, "Process " + app.info.processName 9801 + " has crashed too many times: killing!"); 9802 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9803 app.userId, app.info.processName, app.uid); 9804 mStackSupervisor.handleAppCrashLocked(app); 9805 if (!app.persistent) { 9806 // We don't want to start this process again until the user 9807 // explicitly does so... but for persistent process, we really 9808 // need to keep it running. If a persistent process is actually 9809 // repeatedly crashing, then badness for everyone. 9810 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9811 app.info.processName); 9812 if (!app.isolated) { 9813 // XXX We don't have a way to mark isolated processes 9814 // as bad, since they don't have a peristent identity. 9815 mBadProcesses.put(app.info.processName, app.uid, 9816 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9817 mProcessCrashTimes.remove(app.info.processName, app.uid); 9818 } 9819 app.bad = true; 9820 app.removed = true; 9821 // Don't let services in this process be restarted and potentially 9822 // annoy the user repeatedly. Unless it is persistent, since those 9823 // processes run critical code. 9824 removeProcessLocked(app, false, false, "crash"); 9825 mStackSupervisor.resumeTopActivitiesLocked(); 9826 return false; 9827 } 9828 mStackSupervisor.resumeTopActivitiesLocked(); 9829 } else { 9830 mStackSupervisor.finishTopRunningActivityLocked(app); 9831 } 9832 9833 // Bump up the crash count of any services currently running in the proc. 9834 for (int i=app.services.size()-1; i>=0; i--) { 9835 // Any services running in the application need to be placed 9836 // back in the pending list. 9837 ServiceRecord sr = app.services.valueAt(i); 9838 sr.crashCount++; 9839 } 9840 9841 // If the crashing process is what we consider to be the "home process" and it has been 9842 // replaced by a third-party app, clear the package preferred activities from packages 9843 // with a home activity running in the process to prevent a repeatedly crashing app 9844 // from blocking the user to manually clear the list. 9845 final ArrayList<ActivityRecord> activities = app.activities; 9846 if (app == mHomeProcess && activities.size() > 0 9847 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9848 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9849 final ActivityRecord r = activities.get(activityNdx); 9850 if (r.isHomeActivity()) { 9851 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9852 try { 9853 ActivityThread.getPackageManager() 9854 .clearPackagePreferredActivities(r.packageName); 9855 } catch (RemoteException c) { 9856 // pm is in same process, this will never happen. 9857 } 9858 } 9859 } 9860 } 9861 9862 if (!app.isolated) { 9863 // XXX Can't keep track of crash times for isolated processes, 9864 // because they don't have a perisistent identity. 9865 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9866 } 9867 9868 return true; 9869 } 9870 9871 void startAppProblemLocked(ProcessRecord app) { 9872 if (app.userId == mCurrentUserId) { 9873 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9874 mContext, app.info.packageName, app.info.flags); 9875 } else { 9876 // If this app is not running under the current user, then we 9877 // can't give it a report button because that would require 9878 // launching the report UI under a different user. 9879 app.errorReportReceiver = null; 9880 } 9881 skipCurrentReceiverLocked(app); 9882 } 9883 9884 void skipCurrentReceiverLocked(ProcessRecord app) { 9885 for (BroadcastQueue queue : mBroadcastQueues) { 9886 queue.skipCurrentReceiverLocked(app); 9887 } 9888 } 9889 9890 /** 9891 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9892 * The application process will exit immediately after this call returns. 9893 * @param app object of the crashing app, null for the system server 9894 * @param crashInfo describing the exception 9895 */ 9896 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9897 ProcessRecord r = findAppProcess(app, "Crash"); 9898 final String processName = app == null ? "system_server" 9899 : (r == null ? "unknown" : r.processName); 9900 9901 handleApplicationCrashInner("crash", r, processName, crashInfo); 9902 } 9903 9904 /* Native crash reporting uses this inner version because it needs to be somewhat 9905 * decoupled from the AM-managed cleanup lifecycle 9906 */ 9907 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9908 ApplicationErrorReport.CrashInfo crashInfo) { 9909 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9910 UserHandle.getUserId(Binder.getCallingUid()), processName, 9911 r == null ? -1 : r.info.flags, 9912 crashInfo.exceptionClassName, 9913 crashInfo.exceptionMessage, 9914 crashInfo.throwFileName, 9915 crashInfo.throwLineNumber); 9916 9917 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9918 9919 crashApplication(r, crashInfo); 9920 } 9921 9922 public void handleApplicationStrictModeViolation( 9923 IBinder app, 9924 int violationMask, 9925 StrictMode.ViolationInfo info) { 9926 ProcessRecord r = findAppProcess(app, "StrictMode"); 9927 if (r == null) { 9928 return; 9929 } 9930 9931 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9932 Integer stackFingerprint = info.hashCode(); 9933 boolean logIt = true; 9934 synchronized (mAlreadyLoggedViolatedStacks) { 9935 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9936 logIt = false; 9937 // TODO: sub-sample into EventLog for these, with 9938 // the info.durationMillis? Then we'd get 9939 // the relative pain numbers, without logging all 9940 // the stack traces repeatedly. We'd want to do 9941 // likewise in the client code, which also does 9942 // dup suppression, before the Binder call. 9943 } else { 9944 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9945 mAlreadyLoggedViolatedStacks.clear(); 9946 } 9947 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9948 } 9949 } 9950 if (logIt) { 9951 logStrictModeViolationToDropBox(r, info); 9952 } 9953 } 9954 9955 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9956 AppErrorResult result = new AppErrorResult(); 9957 synchronized (this) { 9958 final long origId = Binder.clearCallingIdentity(); 9959 9960 Message msg = Message.obtain(); 9961 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9962 HashMap<String, Object> data = new HashMap<String, Object>(); 9963 data.put("result", result); 9964 data.put("app", r); 9965 data.put("violationMask", violationMask); 9966 data.put("info", info); 9967 msg.obj = data; 9968 mHandler.sendMessage(msg); 9969 9970 Binder.restoreCallingIdentity(origId); 9971 } 9972 int res = result.get(); 9973 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9974 } 9975 } 9976 9977 // Depending on the policy in effect, there could be a bunch of 9978 // these in quick succession so we try to batch these together to 9979 // minimize disk writes, number of dropbox entries, and maximize 9980 // compression, by having more fewer, larger records. 9981 private void logStrictModeViolationToDropBox( 9982 ProcessRecord process, 9983 StrictMode.ViolationInfo info) { 9984 if (info == null) { 9985 return; 9986 } 9987 final boolean isSystemApp = process == null || 9988 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9989 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9990 final String processName = process == null ? "unknown" : process.processName; 9991 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9992 final DropBoxManager dbox = (DropBoxManager) 9993 mContext.getSystemService(Context.DROPBOX_SERVICE); 9994 9995 // Exit early if the dropbox isn't configured to accept this report type. 9996 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9997 9998 boolean bufferWasEmpty; 9999 boolean needsFlush; 10000 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10001 synchronized (sb) { 10002 bufferWasEmpty = sb.length() == 0; 10003 appendDropBoxProcessHeaders(process, processName, sb); 10004 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10005 sb.append("System-App: ").append(isSystemApp).append("\n"); 10006 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10007 if (info.violationNumThisLoop != 0) { 10008 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10009 } 10010 if (info.numAnimationsRunning != 0) { 10011 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10012 } 10013 if (info.broadcastIntentAction != null) { 10014 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10015 } 10016 if (info.durationMillis != -1) { 10017 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10018 } 10019 if (info.numInstances != -1) { 10020 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10021 } 10022 if (info.tags != null) { 10023 for (String tag : info.tags) { 10024 sb.append("Span-Tag: ").append(tag).append("\n"); 10025 } 10026 } 10027 sb.append("\n"); 10028 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10029 sb.append(info.crashInfo.stackTrace); 10030 } 10031 sb.append("\n"); 10032 10033 // Only buffer up to ~64k. Various logging bits truncate 10034 // things at 128k. 10035 needsFlush = (sb.length() > 64 * 1024); 10036 } 10037 10038 // Flush immediately if the buffer's grown too large, or this 10039 // is a non-system app. Non-system apps are isolated with a 10040 // different tag & policy and not batched. 10041 // 10042 // Batching is useful during internal testing with 10043 // StrictMode settings turned up high. Without batching, 10044 // thousands of separate files could be created on boot. 10045 if (!isSystemApp || needsFlush) { 10046 new Thread("Error dump: " + dropboxTag) { 10047 @Override 10048 public void run() { 10049 String report; 10050 synchronized (sb) { 10051 report = sb.toString(); 10052 sb.delete(0, sb.length()); 10053 sb.trimToSize(); 10054 } 10055 if (report.length() != 0) { 10056 dbox.addText(dropboxTag, report); 10057 } 10058 } 10059 }.start(); 10060 return; 10061 } 10062 10063 // System app batching: 10064 if (!bufferWasEmpty) { 10065 // An existing dropbox-writing thread is outstanding, so 10066 // we don't need to start it up. The existing thread will 10067 // catch the buffer appends we just did. 10068 return; 10069 } 10070 10071 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10072 // (After this point, we shouldn't access AMS internal data structures.) 10073 new Thread("Error dump: " + dropboxTag) { 10074 @Override 10075 public void run() { 10076 // 5 second sleep to let stacks arrive and be batched together 10077 try { 10078 Thread.sleep(5000); // 5 seconds 10079 } catch (InterruptedException e) {} 10080 10081 String errorReport; 10082 synchronized (mStrictModeBuffer) { 10083 errorReport = mStrictModeBuffer.toString(); 10084 if (errorReport.length() == 0) { 10085 return; 10086 } 10087 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10088 mStrictModeBuffer.trimToSize(); 10089 } 10090 dbox.addText(dropboxTag, errorReport); 10091 } 10092 }.start(); 10093 } 10094 10095 /** 10096 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10097 * @param app object of the crashing app, null for the system server 10098 * @param tag reported by the caller 10099 * @param crashInfo describing the context of the error 10100 * @return true if the process should exit immediately (WTF is fatal) 10101 */ 10102 public boolean handleApplicationWtf(IBinder app, String tag, 10103 ApplicationErrorReport.CrashInfo crashInfo) { 10104 ProcessRecord r = findAppProcess(app, "WTF"); 10105 final String processName = app == null ? "system_server" 10106 : (r == null ? "unknown" : r.processName); 10107 10108 EventLog.writeEvent(EventLogTags.AM_WTF, 10109 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10110 processName, 10111 r == null ? -1 : r.info.flags, 10112 tag, crashInfo.exceptionMessage); 10113 10114 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10115 10116 if (r != null && r.pid != Process.myPid() && 10117 Settings.Global.getInt(mContext.getContentResolver(), 10118 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10119 crashApplication(r, crashInfo); 10120 return true; 10121 } else { 10122 return false; 10123 } 10124 } 10125 10126 /** 10127 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10128 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10129 */ 10130 private ProcessRecord findAppProcess(IBinder app, String reason) { 10131 if (app == null) { 10132 return null; 10133 } 10134 10135 synchronized (this) { 10136 final int NP = mProcessNames.getMap().size(); 10137 for (int ip=0; ip<NP; ip++) { 10138 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10139 final int NA = apps.size(); 10140 for (int ia=0; ia<NA; ia++) { 10141 ProcessRecord p = apps.valueAt(ia); 10142 if (p.thread != null && p.thread.asBinder() == app) { 10143 return p; 10144 } 10145 } 10146 } 10147 10148 Slog.w(TAG, "Can't find mystery application for " + reason 10149 + " from pid=" + Binder.getCallingPid() 10150 + " uid=" + Binder.getCallingUid() + ": " + app); 10151 return null; 10152 } 10153 } 10154 10155 /** 10156 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10157 * to append various headers to the dropbox log text. 10158 */ 10159 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10160 StringBuilder sb) { 10161 // Watchdog thread ends up invoking this function (with 10162 // a null ProcessRecord) to add the stack file to dropbox. 10163 // Do not acquire a lock on this (am) in such cases, as it 10164 // could cause a potential deadlock, if and when watchdog 10165 // is invoked due to unavailability of lock on am and it 10166 // would prevent watchdog from killing system_server. 10167 if (process == null) { 10168 sb.append("Process: ").append(processName).append("\n"); 10169 return; 10170 } 10171 // Note: ProcessRecord 'process' is guarded by the service 10172 // instance. (notably process.pkgList, which could otherwise change 10173 // concurrently during execution of this method) 10174 synchronized (this) { 10175 sb.append("Process: ").append(processName).append("\n"); 10176 int flags = process.info.flags; 10177 IPackageManager pm = AppGlobals.getPackageManager(); 10178 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10179 for (int ip=0; ip<process.pkgList.size(); ip++) { 10180 String pkg = process.pkgList.keyAt(ip); 10181 sb.append("Package: ").append(pkg); 10182 try { 10183 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10184 if (pi != null) { 10185 sb.append(" v").append(pi.versionCode); 10186 if (pi.versionName != null) { 10187 sb.append(" (").append(pi.versionName).append(")"); 10188 } 10189 } 10190 } catch (RemoteException e) { 10191 Slog.e(TAG, "Error getting package info: " + pkg, e); 10192 } 10193 sb.append("\n"); 10194 } 10195 } 10196 } 10197 10198 private static String processClass(ProcessRecord process) { 10199 if (process == null || process.pid == MY_PID) { 10200 return "system_server"; 10201 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10202 return "system_app"; 10203 } else { 10204 return "data_app"; 10205 } 10206 } 10207 10208 /** 10209 * Write a description of an error (crash, WTF, ANR) to the drop box. 10210 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10211 * @param process which caused the error, null means the system server 10212 * @param activity which triggered the error, null if unknown 10213 * @param parent activity related to the error, null if unknown 10214 * @param subject line related to the error, null if absent 10215 * @param report in long form describing the error, null if absent 10216 * @param logFile to include in the report, null if none 10217 * @param crashInfo giving an application stack trace, null if absent 10218 */ 10219 public void addErrorToDropBox(String eventType, 10220 ProcessRecord process, String processName, ActivityRecord activity, 10221 ActivityRecord parent, String subject, 10222 final String report, final File logFile, 10223 final ApplicationErrorReport.CrashInfo crashInfo) { 10224 // NOTE -- this must never acquire the ActivityManagerService lock, 10225 // otherwise the watchdog may be prevented from resetting the system. 10226 10227 final String dropboxTag = processClass(process) + "_" + eventType; 10228 final DropBoxManager dbox = (DropBoxManager) 10229 mContext.getSystemService(Context.DROPBOX_SERVICE); 10230 10231 // Exit early if the dropbox isn't configured to accept this report type. 10232 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10233 10234 final StringBuilder sb = new StringBuilder(1024); 10235 appendDropBoxProcessHeaders(process, processName, sb); 10236 if (activity != null) { 10237 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10238 } 10239 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10240 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10241 } 10242 if (parent != null && parent != activity) { 10243 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10244 } 10245 if (subject != null) { 10246 sb.append("Subject: ").append(subject).append("\n"); 10247 } 10248 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10249 if (Debug.isDebuggerConnected()) { 10250 sb.append("Debugger: Connected\n"); 10251 } 10252 sb.append("\n"); 10253 10254 // Do the rest in a worker thread to avoid blocking the caller on I/O 10255 // (After this point, we shouldn't access AMS internal data structures.) 10256 Thread worker = new Thread("Error dump: " + dropboxTag) { 10257 @Override 10258 public void run() { 10259 if (report != null) { 10260 sb.append(report); 10261 } 10262 if (logFile != null) { 10263 try { 10264 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10265 "\n\n[[TRUNCATED]]")); 10266 } catch (IOException e) { 10267 Slog.e(TAG, "Error reading " + logFile, e); 10268 } 10269 } 10270 if (crashInfo != null && crashInfo.stackTrace != null) { 10271 sb.append(crashInfo.stackTrace); 10272 } 10273 10274 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10275 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10276 if (lines > 0) { 10277 sb.append("\n"); 10278 10279 // Merge several logcat streams, and take the last N lines 10280 InputStreamReader input = null; 10281 try { 10282 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10283 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10284 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10285 10286 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10287 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10288 input = new InputStreamReader(logcat.getInputStream()); 10289 10290 int num; 10291 char[] buf = new char[8192]; 10292 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10293 } catch (IOException e) { 10294 Slog.e(TAG, "Error running logcat", e); 10295 } finally { 10296 if (input != null) try { input.close(); } catch (IOException e) {} 10297 } 10298 } 10299 10300 dbox.addText(dropboxTag, sb.toString()); 10301 } 10302 }; 10303 10304 if (process == null) { 10305 // If process is null, we are being called from some internal code 10306 // and may be about to die -- run this synchronously. 10307 worker.run(); 10308 } else { 10309 worker.start(); 10310 } 10311 } 10312 10313 /** 10314 * Bring up the "unexpected error" dialog box for a crashing app. 10315 * Deal with edge cases (intercepts from instrumented applications, 10316 * ActivityController, error intent receivers, that sort of thing). 10317 * @param r the application crashing 10318 * @param crashInfo describing the failure 10319 */ 10320 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10321 long timeMillis = System.currentTimeMillis(); 10322 String shortMsg = crashInfo.exceptionClassName; 10323 String longMsg = crashInfo.exceptionMessage; 10324 String stackTrace = crashInfo.stackTrace; 10325 if (shortMsg != null && longMsg != null) { 10326 longMsg = shortMsg + ": " + longMsg; 10327 } else if (shortMsg != null) { 10328 longMsg = shortMsg; 10329 } 10330 10331 AppErrorResult result = new AppErrorResult(); 10332 synchronized (this) { 10333 if (mController != null) { 10334 try { 10335 String name = r != null ? r.processName : null; 10336 int pid = r != null ? r.pid : Binder.getCallingPid(); 10337 if (!mController.appCrashed(name, pid, 10338 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10339 Slog.w(TAG, "Force-killing crashed app " + name 10340 + " at watcher's request"); 10341 Process.killProcess(pid); 10342 return; 10343 } 10344 } catch (RemoteException e) { 10345 mController = null; 10346 Watchdog.getInstance().setActivityController(null); 10347 } 10348 } 10349 10350 final long origId = Binder.clearCallingIdentity(); 10351 10352 // If this process is running instrumentation, finish it. 10353 if (r != null && r.instrumentationClass != null) { 10354 Slog.w(TAG, "Error in app " + r.processName 10355 + " running instrumentation " + r.instrumentationClass + ":"); 10356 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10357 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10358 Bundle info = new Bundle(); 10359 info.putString("shortMsg", shortMsg); 10360 info.putString("longMsg", longMsg); 10361 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10362 Binder.restoreCallingIdentity(origId); 10363 return; 10364 } 10365 10366 // If we can't identify the process or it's already exceeded its crash quota, 10367 // quit right away without showing a crash dialog. 10368 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10369 Binder.restoreCallingIdentity(origId); 10370 return; 10371 } 10372 10373 Message msg = Message.obtain(); 10374 msg.what = SHOW_ERROR_MSG; 10375 HashMap data = new HashMap(); 10376 data.put("result", result); 10377 data.put("app", r); 10378 msg.obj = data; 10379 mHandler.sendMessage(msg); 10380 10381 Binder.restoreCallingIdentity(origId); 10382 } 10383 10384 int res = result.get(); 10385 10386 Intent appErrorIntent = null; 10387 synchronized (this) { 10388 if (r != null && !r.isolated) { 10389 // XXX Can't keep track of crash time for isolated processes, 10390 // since they don't have a persistent identity. 10391 mProcessCrashTimes.put(r.info.processName, r.uid, 10392 SystemClock.uptimeMillis()); 10393 } 10394 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10395 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10396 } 10397 } 10398 10399 if (appErrorIntent != null) { 10400 try { 10401 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10402 } catch (ActivityNotFoundException e) { 10403 Slog.w(TAG, "bug report receiver dissappeared", e); 10404 } 10405 } 10406 } 10407 10408 Intent createAppErrorIntentLocked(ProcessRecord r, 10409 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10410 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10411 if (report == null) { 10412 return null; 10413 } 10414 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10415 result.setComponent(r.errorReportReceiver); 10416 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10417 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10418 return result; 10419 } 10420 10421 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10422 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10423 if (r.errorReportReceiver == null) { 10424 return null; 10425 } 10426 10427 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10428 return null; 10429 } 10430 10431 ApplicationErrorReport report = new ApplicationErrorReport(); 10432 report.packageName = r.info.packageName; 10433 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10434 report.processName = r.processName; 10435 report.time = timeMillis; 10436 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10437 10438 if (r.crashing || r.forceCrashReport) { 10439 report.type = ApplicationErrorReport.TYPE_CRASH; 10440 report.crashInfo = crashInfo; 10441 } else if (r.notResponding) { 10442 report.type = ApplicationErrorReport.TYPE_ANR; 10443 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10444 10445 report.anrInfo.activity = r.notRespondingReport.tag; 10446 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10447 report.anrInfo.info = r.notRespondingReport.longMsg; 10448 } 10449 10450 return report; 10451 } 10452 10453 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10454 enforceNotIsolatedCaller("getProcessesInErrorState"); 10455 // assume our apps are happy - lazy create the list 10456 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10457 10458 final boolean allUsers = ActivityManager.checkUidPermission( 10459 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10460 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10461 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10462 10463 synchronized (this) { 10464 10465 // iterate across all processes 10466 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10467 ProcessRecord app = mLruProcesses.get(i); 10468 if (!allUsers && app.userId != userId) { 10469 continue; 10470 } 10471 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10472 // This one's in trouble, so we'll generate a report for it 10473 // crashes are higher priority (in case there's a crash *and* an anr) 10474 ActivityManager.ProcessErrorStateInfo report = null; 10475 if (app.crashing) { 10476 report = app.crashingReport; 10477 } else if (app.notResponding) { 10478 report = app.notRespondingReport; 10479 } 10480 10481 if (report != null) { 10482 if (errList == null) { 10483 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10484 } 10485 errList.add(report); 10486 } else { 10487 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10488 " crashing = " + app.crashing + 10489 " notResponding = " + app.notResponding); 10490 } 10491 } 10492 } 10493 } 10494 10495 return errList; 10496 } 10497 10498 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10499 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10500 if (currApp != null) { 10501 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10502 } 10503 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10504 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10505 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10506 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10507 if (currApp != null) { 10508 currApp.lru = 0; 10509 } 10510 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10511 } else if (adj >= ProcessList.SERVICE_ADJ) { 10512 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10513 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10514 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10515 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10516 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10517 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10518 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10519 } else { 10520 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10521 } 10522 } 10523 10524 private void fillInProcMemInfo(ProcessRecord app, 10525 ActivityManager.RunningAppProcessInfo outInfo) { 10526 outInfo.pid = app.pid; 10527 outInfo.uid = app.info.uid; 10528 if (mHeavyWeightProcess == app) { 10529 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10530 } 10531 if (app.persistent) { 10532 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10533 } 10534 if (app.activities.size() > 0) { 10535 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10536 } 10537 outInfo.lastTrimLevel = app.trimMemoryLevel; 10538 int adj = app.curAdj; 10539 outInfo.importance = oomAdjToImportance(adj, outInfo); 10540 outInfo.importanceReasonCode = app.adjTypeCode; 10541 outInfo.processState = app.curProcState; 10542 } 10543 10544 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10545 enforceNotIsolatedCaller("getRunningAppProcesses"); 10546 // Lazy instantiation of list 10547 List<ActivityManager.RunningAppProcessInfo> runList = null; 10548 final boolean allUsers = ActivityManager.checkUidPermission( 10549 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10550 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10551 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10552 synchronized (this) { 10553 // Iterate across all processes 10554 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10555 ProcessRecord app = mLruProcesses.get(i); 10556 if (!allUsers && app.userId != userId) { 10557 continue; 10558 } 10559 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10560 // Generate process state info for running application 10561 ActivityManager.RunningAppProcessInfo currApp = 10562 new ActivityManager.RunningAppProcessInfo(app.processName, 10563 app.pid, app.getPackageList()); 10564 fillInProcMemInfo(app, currApp); 10565 if (app.adjSource instanceof ProcessRecord) { 10566 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10567 currApp.importanceReasonImportance = oomAdjToImportance( 10568 app.adjSourceOom, null); 10569 } else if (app.adjSource instanceof ActivityRecord) { 10570 ActivityRecord r = (ActivityRecord)app.adjSource; 10571 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10572 } 10573 if (app.adjTarget instanceof ComponentName) { 10574 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10575 } 10576 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10577 // + " lru=" + currApp.lru); 10578 if (runList == null) { 10579 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10580 } 10581 runList.add(currApp); 10582 } 10583 } 10584 } 10585 return runList; 10586 } 10587 10588 public List<ApplicationInfo> getRunningExternalApplications() { 10589 enforceNotIsolatedCaller("getRunningExternalApplications"); 10590 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10591 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10592 if (runningApps != null && runningApps.size() > 0) { 10593 Set<String> extList = new HashSet<String>(); 10594 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10595 if (app.pkgList != null) { 10596 for (String pkg : app.pkgList) { 10597 extList.add(pkg); 10598 } 10599 } 10600 } 10601 IPackageManager pm = AppGlobals.getPackageManager(); 10602 for (String pkg : extList) { 10603 try { 10604 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10605 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10606 retList.add(info); 10607 } 10608 } catch (RemoteException e) { 10609 } 10610 } 10611 } 10612 return retList; 10613 } 10614 10615 @Override 10616 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10617 enforceNotIsolatedCaller("getMyMemoryState"); 10618 synchronized (this) { 10619 ProcessRecord proc; 10620 synchronized (mPidsSelfLocked) { 10621 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10622 } 10623 fillInProcMemInfo(proc, outInfo); 10624 } 10625 } 10626 10627 @Override 10628 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10629 if (checkCallingPermission(android.Manifest.permission.DUMP) 10630 != PackageManager.PERMISSION_GRANTED) { 10631 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10632 + Binder.getCallingPid() 10633 + ", uid=" + Binder.getCallingUid() 10634 + " without permission " 10635 + android.Manifest.permission.DUMP); 10636 return; 10637 } 10638 10639 boolean dumpAll = false; 10640 boolean dumpClient = false; 10641 String dumpPackage = null; 10642 10643 int opti = 0; 10644 while (opti < args.length) { 10645 String opt = args[opti]; 10646 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10647 break; 10648 } 10649 opti++; 10650 if ("-a".equals(opt)) { 10651 dumpAll = true; 10652 } else if ("-c".equals(opt)) { 10653 dumpClient = true; 10654 } else if ("-h".equals(opt)) { 10655 pw.println("Activity manager dump options:"); 10656 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10657 pw.println(" cmd may be one of:"); 10658 pw.println(" a[ctivities]: activity stack state"); 10659 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10660 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10661 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10662 pw.println(" o[om]: out of memory management"); 10663 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10664 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10665 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10666 pw.println(" service [COMP_SPEC]: service client-side state"); 10667 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10668 pw.println(" all: dump all activities"); 10669 pw.println(" top: dump the top activity"); 10670 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10671 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10672 pw.println(" a partial substring in a component name, a"); 10673 pw.println(" hex object identifier."); 10674 pw.println(" -a: include all available server state."); 10675 pw.println(" -c: include client state."); 10676 return; 10677 } else { 10678 pw.println("Unknown argument: " + opt + "; use -h for help"); 10679 } 10680 } 10681 10682 long origId = Binder.clearCallingIdentity(); 10683 boolean more = false; 10684 // Is the caller requesting to dump a particular piece of data? 10685 if (opti < args.length) { 10686 String cmd = args[opti]; 10687 opti++; 10688 if ("activities".equals(cmd) || "a".equals(cmd)) { 10689 synchronized (this) { 10690 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10691 } 10692 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10693 String[] newArgs; 10694 String name; 10695 if (opti >= args.length) { 10696 name = null; 10697 newArgs = EMPTY_STRING_ARRAY; 10698 } else { 10699 name = args[opti]; 10700 opti++; 10701 newArgs = new String[args.length - opti]; 10702 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10703 args.length - opti); 10704 } 10705 synchronized (this) { 10706 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10707 } 10708 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10709 String[] newArgs; 10710 String name; 10711 if (opti >= args.length) { 10712 name = null; 10713 newArgs = EMPTY_STRING_ARRAY; 10714 } else { 10715 name = args[opti]; 10716 opti++; 10717 newArgs = new String[args.length - opti]; 10718 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10719 args.length - opti); 10720 } 10721 synchronized (this) { 10722 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10723 } 10724 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10725 String[] newArgs; 10726 String name; 10727 if (opti >= args.length) { 10728 name = null; 10729 newArgs = EMPTY_STRING_ARRAY; 10730 } else { 10731 name = args[opti]; 10732 opti++; 10733 newArgs = new String[args.length - opti]; 10734 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10735 args.length - opti); 10736 } 10737 synchronized (this) { 10738 dumpProcessesLocked(fd, pw, args, opti, true, name); 10739 } 10740 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10741 synchronized (this) { 10742 dumpOomLocked(fd, pw, args, opti, true); 10743 } 10744 } else if ("provider".equals(cmd)) { 10745 String[] newArgs; 10746 String name; 10747 if (opti >= args.length) { 10748 name = null; 10749 newArgs = EMPTY_STRING_ARRAY; 10750 } else { 10751 name = args[opti]; 10752 opti++; 10753 newArgs = new String[args.length - opti]; 10754 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10755 } 10756 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10757 pw.println("No providers match: " + name); 10758 pw.println("Use -h for help."); 10759 } 10760 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10761 synchronized (this) { 10762 dumpProvidersLocked(fd, pw, args, opti, true, null); 10763 } 10764 } else if ("service".equals(cmd)) { 10765 String[] newArgs; 10766 String name; 10767 if (opti >= args.length) { 10768 name = null; 10769 newArgs = EMPTY_STRING_ARRAY; 10770 } else { 10771 name = args[opti]; 10772 opti++; 10773 newArgs = new String[args.length - opti]; 10774 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10775 args.length - opti); 10776 } 10777 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10778 pw.println("No services match: " + name); 10779 pw.println("Use -h for help."); 10780 } 10781 } else if ("package".equals(cmd)) { 10782 String[] newArgs; 10783 if (opti >= args.length) { 10784 pw.println("package: no package name specified"); 10785 pw.println("Use -h for help."); 10786 } else { 10787 dumpPackage = args[opti]; 10788 opti++; 10789 newArgs = new String[args.length - opti]; 10790 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10791 args.length - opti); 10792 args = newArgs; 10793 opti = 0; 10794 more = true; 10795 } 10796 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10797 synchronized (this) { 10798 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10799 } 10800 } else { 10801 // Dumping a single activity? 10802 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10803 pw.println("Bad activity command, or no activities match: " + cmd); 10804 pw.println("Use -h for help."); 10805 } 10806 } 10807 if (!more) { 10808 Binder.restoreCallingIdentity(origId); 10809 return; 10810 } 10811 } 10812 10813 // No piece of data specified, dump everything. 10814 synchronized (this) { 10815 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10816 pw.println(); 10817 if (dumpAll) { 10818 pw.println("-------------------------------------------------------------------------------"); 10819 } 10820 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10821 pw.println(); 10822 if (dumpAll) { 10823 pw.println("-------------------------------------------------------------------------------"); 10824 } 10825 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10826 pw.println(); 10827 if (dumpAll) { 10828 pw.println("-------------------------------------------------------------------------------"); 10829 } 10830 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10831 pw.println(); 10832 if (dumpAll) { 10833 pw.println("-------------------------------------------------------------------------------"); 10834 } 10835 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10836 pw.println(); 10837 if (dumpAll) { 10838 pw.println("-------------------------------------------------------------------------------"); 10839 } 10840 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10841 } 10842 Binder.restoreCallingIdentity(origId); 10843 } 10844 10845 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10846 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10847 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10848 10849 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10850 dumpPackage); 10851 boolean needSep = printedAnything; 10852 10853 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10854 dumpPackage, needSep, " mFocusedActivity: "); 10855 if (printed) { 10856 printedAnything = true; 10857 needSep = false; 10858 } 10859 10860 if (dumpPackage == null) { 10861 if (needSep) { 10862 pw.println(); 10863 } 10864 needSep = true; 10865 printedAnything = true; 10866 mStackSupervisor.dump(pw, " "); 10867 } 10868 10869 if (mRecentTasks.size() > 0) { 10870 boolean printedHeader = false; 10871 10872 final int N = mRecentTasks.size(); 10873 for (int i=0; i<N; i++) { 10874 TaskRecord tr = mRecentTasks.get(i); 10875 if (dumpPackage != null) { 10876 if (tr.realActivity == null || 10877 !dumpPackage.equals(tr.realActivity)) { 10878 continue; 10879 } 10880 } 10881 if (!printedHeader) { 10882 if (needSep) { 10883 pw.println(); 10884 } 10885 pw.println(" Recent tasks:"); 10886 printedHeader = true; 10887 printedAnything = true; 10888 } 10889 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10890 pw.println(tr); 10891 if (dumpAll) { 10892 mRecentTasks.get(i).dump(pw, " "); 10893 } 10894 } 10895 } 10896 10897 if (!printedAnything) { 10898 pw.println(" (nothing)"); 10899 } 10900 } 10901 10902 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10903 int opti, boolean dumpAll, String dumpPackage) { 10904 boolean needSep = false; 10905 boolean printedAnything = false; 10906 int numPers = 0; 10907 10908 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10909 10910 if (dumpAll) { 10911 final int NP = mProcessNames.getMap().size(); 10912 for (int ip=0; ip<NP; ip++) { 10913 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10914 final int NA = procs.size(); 10915 for (int ia=0; ia<NA; ia++) { 10916 ProcessRecord r = procs.valueAt(ia); 10917 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10918 continue; 10919 } 10920 if (!needSep) { 10921 pw.println(" All known processes:"); 10922 needSep = true; 10923 printedAnything = true; 10924 } 10925 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10926 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10927 pw.print(" "); pw.println(r); 10928 r.dump(pw, " "); 10929 if (r.persistent) { 10930 numPers++; 10931 } 10932 } 10933 } 10934 } 10935 10936 if (mIsolatedProcesses.size() > 0) { 10937 boolean printed = false; 10938 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10939 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10940 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10941 continue; 10942 } 10943 if (!printed) { 10944 if (needSep) { 10945 pw.println(); 10946 } 10947 pw.println(" Isolated process list (sorted by uid):"); 10948 printedAnything = true; 10949 printed = true; 10950 needSep = true; 10951 } 10952 pw.println(String.format("%sIsolated #%2d: %s", 10953 " ", i, r.toString())); 10954 } 10955 } 10956 10957 if (mLruProcesses.size() > 0) { 10958 if (needSep) { 10959 pw.println(); 10960 } 10961 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10962 pw.print(" total, non-act at "); 10963 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10964 pw.print(", non-svc at "); 10965 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10966 pw.println("):"); 10967 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10968 needSep = true; 10969 printedAnything = true; 10970 } 10971 10972 if (dumpAll || dumpPackage != null) { 10973 synchronized (mPidsSelfLocked) { 10974 boolean printed = false; 10975 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10976 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10977 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10978 continue; 10979 } 10980 if (!printed) { 10981 if (needSep) pw.println(); 10982 needSep = true; 10983 pw.println(" PID mappings:"); 10984 printed = true; 10985 printedAnything = true; 10986 } 10987 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10988 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10989 } 10990 } 10991 } 10992 10993 if (mForegroundProcesses.size() > 0) { 10994 synchronized (mPidsSelfLocked) { 10995 boolean printed = false; 10996 for (int i=0; i<mForegroundProcesses.size(); i++) { 10997 ProcessRecord r = mPidsSelfLocked.get( 10998 mForegroundProcesses.valueAt(i).pid); 10999 if (dumpPackage != null && (r == null 11000 || !r.pkgList.containsKey(dumpPackage))) { 11001 continue; 11002 } 11003 if (!printed) { 11004 if (needSep) pw.println(); 11005 needSep = true; 11006 pw.println(" Foreground Processes:"); 11007 printed = true; 11008 printedAnything = true; 11009 } 11010 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11011 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11012 } 11013 } 11014 } 11015 11016 if (mPersistentStartingProcesses.size() > 0) { 11017 if (needSep) pw.println(); 11018 needSep = true; 11019 printedAnything = true; 11020 pw.println(" Persisent processes that are starting:"); 11021 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11022 "Starting Norm", "Restarting PERS", dumpPackage); 11023 } 11024 11025 if (mRemovedProcesses.size() > 0) { 11026 if (needSep) pw.println(); 11027 needSep = true; 11028 printedAnything = true; 11029 pw.println(" Processes that are being removed:"); 11030 dumpProcessList(pw, this, mRemovedProcesses, " ", 11031 "Removed Norm", "Removed PERS", dumpPackage); 11032 } 11033 11034 if (mProcessesOnHold.size() > 0) { 11035 if (needSep) pw.println(); 11036 needSep = true; 11037 printedAnything = true; 11038 pw.println(" Processes that are on old until the system is ready:"); 11039 dumpProcessList(pw, this, mProcessesOnHold, " ", 11040 "OnHold Norm", "OnHold PERS", dumpPackage); 11041 } 11042 11043 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11044 11045 if (mProcessCrashTimes.getMap().size() > 0) { 11046 boolean printed = false; 11047 long now = SystemClock.uptimeMillis(); 11048 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11049 final int NP = pmap.size(); 11050 for (int ip=0; ip<NP; ip++) { 11051 String pname = pmap.keyAt(ip); 11052 SparseArray<Long> uids = pmap.valueAt(ip); 11053 final int N = uids.size(); 11054 for (int i=0; i<N; i++) { 11055 int puid = uids.keyAt(i); 11056 ProcessRecord r = mProcessNames.get(pname, puid); 11057 if (dumpPackage != null && (r == null 11058 || !r.pkgList.containsKey(dumpPackage))) { 11059 continue; 11060 } 11061 if (!printed) { 11062 if (needSep) pw.println(); 11063 needSep = true; 11064 pw.println(" Time since processes crashed:"); 11065 printed = true; 11066 printedAnything = true; 11067 } 11068 pw.print(" Process "); pw.print(pname); 11069 pw.print(" uid "); pw.print(puid); 11070 pw.print(": last crashed "); 11071 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11072 pw.println(" ago"); 11073 } 11074 } 11075 } 11076 11077 if (mBadProcesses.getMap().size() > 0) { 11078 boolean printed = false; 11079 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11080 final int NP = pmap.size(); 11081 for (int ip=0; ip<NP; ip++) { 11082 String pname = pmap.keyAt(ip); 11083 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11084 final int N = uids.size(); 11085 for (int i=0; i<N; i++) { 11086 int puid = uids.keyAt(i); 11087 ProcessRecord r = mProcessNames.get(pname, puid); 11088 if (dumpPackage != null && (r == null 11089 || !r.pkgList.containsKey(dumpPackage))) { 11090 continue; 11091 } 11092 if (!printed) { 11093 if (needSep) pw.println(); 11094 needSep = true; 11095 pw.println(" Bad processes:"); 11096 printedAnything = true; 11097 } 11098 BadProcessInfo info = uids.valueAt(i); 11099 pw.print(" Bad process "); pw.print(pname); 11100 pw.print(" uid "); pw.print(puid); 11101 pw.print(": crashed at time "); pw.println(info.time); 11102 if (info.shortMsg != null) { 11103 pw.print(" Short msg: "); pw.println(info.shortMsg); 11104 } 11105 if (info.longMsg != null) { 11106 pw.print(" Long msg: "); pw.println(info.longMsg); 11107 } 11108 if (info.stack != null) { 11109 pw.println(" Stack:"); 11110 int lastPos = 0; 11111 for (int pos=0; pos<info.stack.length(); pos++) { 11112 if (info.stack.charAt(pos) == '\n') { 11113 pw.print(" "); 11114 pw.write(info.stack, lastPos, pos-lastPos); 11115 pw.println(); 11116 lastPos = pos+1; 11117 } 11118 } 11119 if (lastPos < info.stack.length()) { 11120 pw.print(" "); 11121 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11122 pw.println(); 11123 } 11124 } 11125 } 11126 } 11127 } 11128 11129 if (dumpPackage == null) { 11130 pw.println(); 11131 needSep = false; 11132 pw.println(" mStartedUsers:"); 11133 for (int i=0; i<mStartedUsers.size(); i++) { 11134 UserStartedState uss = mStartedUsers.valueAt(i); 11135 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11136 pw.print(": "); uss.dump("", pw); 11137 } 11138 pw.print(" mStartedUserArray: ["); 11139 for (int i=0; i<mStartedUserArray.length; i++) { 11140 if (i > 0) pw.print(", "); 11141 pw.print(mStartedUserArray[i]); 11142 } 11143 pw.println("]"); 11144 pw.print(" mUserLru: ["); 11145 for (int i=0; i<mUserLru.size(); i++) { 11146 if (i > 0) pw.print(", "); 11147 pw.print(mUserLru.get(i)); 11148 } 11149 pw.println("]"); 11150 if (dumpAll) { 11151 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11152 } 11153 } 11154 if (mHomeProcess != null && (dumpPackage == null 11155 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11156 if (needSep) { 11157 pw.println(); 11158 needSep = false; 11159 } 11160 pw.println(" mHomeProcess: " + mHomeProcess); 11161 } 11162 if (mPreviousProcess != null && (dumpPackage == null 11163 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11164 if (needSep) { 11165 pw.println(); 11166 needSep = false; 11167 } 11168 pw.println(" mPreviousProcess: " + mPreviousProcess); 11169 } 11170 if (dumpAll) { 11171 StringBuilder sb = new StringBuilder(128); 11172 sb.append(" mPreviousProcessVisibleTime: "); 11173 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11174 pw.println(sb); 11175 } 11176 if (mHeavyWeightProcess != null && (dumpPackage == null 11177 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11178 if (needSep) { 11179 pw.println(); 11180 needSep = false; 11181 } 11182 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11183 } 11184 if (dumpPackage == null) { 11185 pw.println(" mConfiguration: " + mConfiguration); 11186 } 11187 if (dumpAll) { 11188 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11189 if (mCompatModePackages.getPackages().size() > 0) { 11190 boolean printed = false; 11191 for (Map.Entry<String, Integer> entry 11192 : mCompatModePackages.getPackages().entrySet()) { 11193 String pkg = entry.getKey(); 11194 int mode = entry.getValue(); 11195 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11196 continue; 11197 } 11198 if (!printed) { 11199 pw.println(" mScreenCompatPackages:"); 11200 printed = true; 11201 } 11202 pw.print(" "); pw.print(pkg); pw.print(": "); 11203 pw.print(mode); pw.println(); 11204 } 11205 } 11206 } 11207 if (dumpPackage == null) { 11208 if (mSleeping || mWentToSleep || mLockScreenShown) { 11209 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11210 + " mLockScreenShown " + mLockScreenShown); 11211 } 11212 if (mShuttingDown || mRunningVoice) { 11213 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11214 } 11215 } 11216 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11217 || mOrigWaitForDebugger) { 11218 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11219 || dumpPackage.equals(mOrigDebugApp)) { 11220 if (needSep) { 11221 pw.println(); 11222 needSep = false; 11223 } 11224 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11225 + " mDebugTransient=" + mDebugTransient 11226 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11227 } 11228 } 11229 if (mOpenGlTraceApp != null) { 11230 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11231 if (needSep) { 11232 pw.println(); 11233 needSep = false; 11234 } 11235 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11236 } 11237 } 11238 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11239 || mProfileFd != null) { 11240 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11241 if (needSep) { 11242 pw.println(); 11243 needSep = false; 11244 } 11245 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11246 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11247 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11248 + mAutoStopProfiler); 11249 } 11250 } 11251 if (dumpPackage == null) { 11252 if (mAlwaysFinishActivities || mController != null) { 11253 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11254 + " mController=" + mController); 11255 } 11256 if (dumpAll) { 11257 pw.println(" Total persistent processes: " + numPers); 11258 pw.println(" mProcessesReady=" + mProcessesReady 11259 + " mSystemReady=" + mSystemReady); 11260 pw.println(" mBooting=" + mBooting 11261 + " mBooted=" + mBooted 11262 + " mFactoryTest=" + mFactoryTest); 11263 pw.print(" mLastPowerCheckRealtime="); 11264 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11265 pw.println(""); 11266 pw.print(" mLastPowerCheckUptime="); 11267 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11268 pw.println(""); 11269 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11270 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11271 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11272 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11273 + " (" + mLruProcesses.size() + " total)" 11274 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11275 + " mNumServiceProcs=" + mNumServiceProcs 11276 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11277 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11278 + " mLastMemoryLevel" + mLastMemoryLevel 11279 + " mLastNumProcesses" + mLastNumProcesses); 11280 long now = SystemClock.uptimeMillis(); 11281 pw.print(" mLastIdleTime="); 11282 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11283 pw.print(" mLowRamSinceLastIdle="); 11284 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11285 pw.println(); 11286 } 11287 } 11288 11289 if (!printedAnything) { 11290 pw.println(" (nothing)"); 11291 } 11292 } 11293 11294 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11295 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11296 if (mProcessesToGc.size() > 0) { 11297 boolean printed = false; 11298 long now = SystemClock.uptimeMillis(); 11299 for (int i=0; i<mProcessesToGc.size(); i++) { 11300 ProcessRecord proc = mProcessesToGc.get(i); 11301 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11302 continue; 11303 } 11304 if (!printed) { 11305 if (needSep) pw.println(); 11306 needSep = true; 11307 pw.println(" Processes that are waiting to GC:"); 11308 printed = true; 11309 } 11310 pw.print(" Process "); pw.println(proc); 11311 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11312 pw.print(", last gced="); 11313 pw.print(now-proc.lastRequestedGc); 11314 pw.print(" ms ago, last lowMem="); 11315 pw.print(now-proc.lastLowMemory); 11316 pw.println(" ms ago"); 11317 11318 } 11319 } 11320 return needSep; 11321 } 11322 11323 void printOomLevel(PrintWriter pw, String name, int adj) { 11324 pw.print(" "); 11325 if (adj >= 0) { 11326 pw.print(' '); 11327 if (adj < 10) pw.print(' '); 11328 } else { 11329 if (adj > -10) pw.print(' '); 11330 } 11331 pw.print(adj); 11332 pw.print(": "); 11333 pw.print(name); 11334 pw.print(" ("); 11335 pw.print(mProcessList.getMemLevel(adj)/1024); 11336 pw.println(" kB)"); 11337 } 11338 11339 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11340 int opti, boolean dumpAll) { 11341 boolean needSep = false; 11342 11343 if (mLruProcesses.size() > 0) { 11344 if (needSep) pw.println(); 11345 needSep = true; 11346 pw.println(" OOM levels:"); 11347 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11348 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11349 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11350 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11351 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11352 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11353 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11354 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11355 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11356 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11357 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11358 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11359 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11360 11361 if (needSep) pw.println(); 11362 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11363 pw.print(" total, non-act at "); 11364 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11365 pw.print(", non-svc at "); 11366 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11367 pw.println("):"); 11368 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11369 needSep = true; 11370 } 11371 11372 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11373 11374 pw.println(); 11375 pw.println(" mHomeProcess: " + mHomeProcess); 11376 pw.println(" mPreviousProcess: " + mPreviousProcess); 11377 if (mHeavyWeightProcess != null) { 11378 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11379 } 11380 11381 return true; 11382 } 11383 11384 /** 11385 * There are three ways to call this: 11386 * - no provider specified: dump all the providers 11387 * - a flattened component name that matched an existing provider was specified as the 11388 * first arg: dump that one provider 11389 * - the first arg isn't the flattened component name of an existing provider: 11390 * dump all providers whose component contains the first arg as a substring 11391 */ 11392 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11393 int opti, boolean dumpAll) { 11394 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11395 } 11396 11397 static class ItemMatcher { 11398 ArrayList<ComponentName> components; 11399 ArrayList<String> strings; 11400 ArrayList<Integer> objects; 11401 boolean all; 11402 11403 ItemMatcher() { 11404 all = true; 11405 } 11406 11407 void build(String name) { 11408 ComponentName componentName = ComponentName.unflattenFromString(name); 11409 if (componentName != null) { 11410 if (components == null) { 11411 components = new ArrayList<ComponentName>(); 11412 } 11413 components.add(componentName); 11414 all = false; 11415 } else { 11416 int objectId = 0; 11417 // Not a '/' separated full component name; maybe an object ID? 11418 try { 11419 objectId = Integer.parseInt(name, 16); 11420 if (objects == null) { 11421 objects = new ArrayList<Integer>(); 11422 } 11423 objects.add(objectId); 11424 all = false; 11425 } catch (RuntimeException e) { 11426 // Not an integer; just do string match. 11427 if (strings == null) { 11428 strings = new ArrayList<String>(); 11429 } 11430 strings.add(name); 11431 all = false; 11432 } 11433 } 11434 } 11435 11436 int build(String[] args, int opti) { 11437 for (; opti<args.length; opti++) { 11438 String name = args[opti]; 11439 if ("--".equals(name)) { 11440 return opti+1; 11441 } 11442 build(name); 11443 } 11444 return opti; 11445 } 11446 11447 boolean match(Object object, ComponentName comp) { 11448 if (all) { 11449 return true; 11450 } 11451 if (components != null) { 11452 for (int i=0; i<components.size(); i++) { 11453 if (components.get(i).equals(comp)) { 11454 return true; 11455 } 11456 } 11457 } 11458 if (objects != null) { 11459 for (int i=0; i<objects.size(); i++) { 11460 if (System.identityHashCode(object) == objects.get(i)) { 11461 return true; 11462 } 11463 } 11464 } 11465 if (strings != null) { 11466 String flat = comp.flattenToString(); 11467 for (int i=0; i<strings.size(); i++) { 11468 if (flat.contains(strings.get(i))) { 11469 return true; 11470 } 11471 } 11472 } 11473 return false; 11474 } 11475 } 11476 11477 /** 11478 * There are three things that cmd can be: 11479 * - a flattened component name that matches an existing activity 11480 * - the cmd arg isn't the flattened component name of an existing activity: 11481 * dump all activity whose component contains the cmd as a substring 11482 * - A hex number of the ActivityRecord object instance. 11483 */ 11484 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11485 int opti, boolean dumpAll) { 11486 ArrayList<ActivityRecord> activities; 11487 11488 synchronized (this) { 11489 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11490 } 11491 11492 if (activities.size() <= 0) { 11493 return false; 11494 } 11495 11496 String[] newArgs = new String[args.length - opti]; 11497 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11498 11499 TaskRecord lastTask = null; 11500 boolean needSep = false; 11501 for (int i=activities.size()-1; i>=0; i--) { 11502 ActivityRecord r = activities.get(i); 11503 if (needSep) { 11504 pw.println(); 11505 } 11506 needSep = true; 11507 synchronized (this) { 11508 if (lastTask != r.task) { 11509 lastTask = r.task; 11510 pw.print("TASK "); pw.print(lastTask.affinity); 11511 pw.print(" id="); pw.println(lastTask.taskId); 11512 if (dumpAll) { 11513 lastTask.dump(pw, " "); 11514 } 11515 } 11516 } 11517 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11518 } 11519 return true; 11520 } 11521 11522 /** 11523 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11524 * there is a thread associated with the activity. 11525 */ 11526 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11527 final ActivityRecord r, String[] args, boolean dumpAll) { 11528 String innerPrefix = prefix + " "; 11529 synchronized (this) { 11530 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11531 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11532 pw.print(" pid="); 11533 if (r.app != null) pw.println(r.app.pid); 11534 else pw.println("(not running)"); 11535 if (dumpAll) { 11536 r.dump(pw, innerPrefix); 11537 } 11538 } 11539 if (r.app != null && r.app.thread != null) { 11540 // flush anything that is already in the PrintWriter since the thread is going 11541 // to write to the file descriptor directly 11542 pw.flush(); 11543 try { 11544 TransferPipe tp = new TransferPipe(); 11545 try { 11546 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11547 r.appToken, innerPrefix, args); 11548 tp.go(fd); 11549 } finally { 11550 tp.kill(); 11551 } 11552 } catch (IOException e) { 11553 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11554 } catch (RemoteException e) { 11555 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11556 } 11557 } 11558 } 11559 11560 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11561 int opti, boolean dumpAll, String dumpPackage) { 11562 boolean needSep = false; 11563 boolean onlyHistory = false; 11564 boolean printedAnything = false; 11565 11566 if ("history".equals(dumpPackage)) { 11567 if (opti < args.length && "-s".equals(args[opti])) { 11568 dumpAll = false; 11569 } 11570 onlyHistory = true; 11571 dumpPackage = null; 11572 } 11573 11574 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11575 if (!onlyHistory && dumpAll) { 11576 if (mRegisteredReceivers.size() > 0) { 11577 boolean printed = false; 11578 Iterator it = mRegisteredReceivers.values().iterator(); 11579 while (it.hasNext()) { 11580 ReceiverList r = (ReceiverList)it.next(); 11581 if (dumpPackage != null && (r.app == null || 11582 !dumpPackage.equals(r.app.info.packageName))) { 11583 continue; 11584 } 11585 if (!printed) { 11586 pw.println(" Registered Receivers:"); 11587 needSep = true; 11588 printed = true; 11589 printedAnything = true; 11590 } 11591 pw.print(" * "); pw.println(r); 11592 r.dump(pw, " "); 11593 } 11594 } 11595 11596 if (mReceiverResolver.dump(pw, needSep ? 11597 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11598 " ", dumpPackage, false)) { 11599 needSep = true; 11600 printedAnything = true; 11601 } 11602 } 11603 11604 for (BroadcastQueue q : mBroadcastQueues) { 11605 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11606 printedAnything |= needSep; 11607 } 11608 11609 needSep = true; 11610 11611 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11612 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11613 if (needSep) { 11614 pw.println(); 11615 } 11616 needSep = true; 11617 printedAnything = true; 11618 pw.print(" Sticky broadcasts for user "); 11619 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11620 StringBuilder sb = new StringBuilder(128); 11621 for (Map.Entry<String, ArrayList<Intent>> ent 11622 : mStickyBroadcasts.valueAt(user).entrySet()) { 11623 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11624 if (dumpAll) { 11625 pw.println(":"); 11626 ArrayList<Intent> intents = ent.getValue(); 11627 final int N = intents.size(); 11628 for (int i=0; i<N; i++) { 11629 sb.setLength(0); 11630 sb.append(" Intent: "); 11631 intents.get(i).toShortString(sb, false, true, false, false); 11632 pw.println(sb.toString()); 11633 Bundle bundle = intents.get(i).getExtras(); 11634 if (bundle != null) { 11635 pw.print(" "); 11636 pw.println(bundle.toString()); 11637 } 11638 } 11639 } else { 11640 pw.println(""); 11641 } 11642 } 11643 } 11644 } 11645 11646 if (!onlyHistory && dumpAll) { 11647 pw.println(); 11648 for (BroadcastQueue queue : mBroadcastQueues) { 11649 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11650 + queue.mBroadcastsScheduled); 11651 } 11652 pw.println(" mHandler:"); 11653 mHandler.dump(new PrintWriterPrinter(pw), " "); 11654 needSep = true; 11655 printedAnything = true; 11656 } 11657 11658 if (!printedAnything) { 11659 pw.println(" (nothing)"); 11660 } 11661 } 11662 11663 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11664 int opti, boolean dumpAll, String dumpPackage) { 11665 boolean needSep; 11666 boolean printedAnything = false; 11667 11668 ItemMatcher matcher = new ItemMatcher(); 11669 matcher.build(args, opti); 11670 11671 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11672 11673 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11674 printedAnything |= needSep; 11675 11676 if (mLaunchingProviders.size() > 0) { 11677 boolean printed = false; 11678 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11679 ContentProviderRecord r = mLaunchingProviders.get(i); 11680 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11681 continue; 11682 } 11683 if (!printed) { 11684 if (needSep) pw.println(); 11685 needSep = true; 11686 pw.println(" Launching content providers:"); 11687 printed = true; 11688 printedAnything = true; 11689 } 11690 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11691 pw.println(r); 11692 } 11693 } 11694 11695 if (mGrantedUriPermissions.size() > 0) { 11696 boolean printed = false; 11697 int dumpUid = -2; 11698 if (dumpPackage != null) { 11699 try { 11700 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11701 } catch (NameNotFoundException e) { 11702 dumpUid = -1; 11703 } 11704 } 11705 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11706 int uid = mGrantedUriPermissions.keyAt(i); 11707 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11708 continue; 11709 } 11710 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11711 if (!printed) { 11712 if (needSep) pw.println(); 11713 needSep = true; 11714 pw.println(" Granted Uri Permissions:"); 11715 printed = true; 11716 printedAnything = true; 11717 } 11718 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11719 for (UriPermission perm : perms.values()) { 11720 pw.print(" "); pw.println(perm); 11721 if (dumpAll) { 11722 perm.dump(pw, " "); 11723 } 11724 } 11725 } 11726 } 11727 11728 if (!printedAnything) { 11729 pw.println(" (nothing)"); 11730 } 11731 } 11732 11733 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11734 int opti, boolean dumpAll, String dumpPackage) { 11735 boolean printed = false; 11736 11737 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11738 11739 if (mIntentSenderRecords.size() > 0) { 11740 Iterator<WeakReference<PendingIntentRecord>> it 11741 = mIntentSenderRecords.values().iterator(); 11742 while (it.hasNext()) { 11743 WeakReference<PendingIntentRecord> ref = it.next(); 11744 PendingIntentRecord rec = ref != null ? ref.get(): null; 11745 if (dumpPackage != null && (rec == null 11746 || !dumpPackage.equals(rec.key.packageName))) { 11747 continue; 11748 } 11749 printed = true; 11750 if (rec != null) { 11751 pw.print(" * "); pw.println(rec); 11752 if (dumpAll) { 11753 rec.dump(pw, " "); 11754 } 11755 } else { 11756 pw.print(" * "); pw.println(ref); 11757 } 11758 } 11759 } 11760 11761 if (!printed) { 11762 pw.println(" (nothing)"); 11763 } 11764 } 11765 11766 private static final int dumpProcessList(PrintWriter pw, 11767 ActivityManagerService service, List list, 11768 String prefix, String normalLabel, String persistentLabel, 11769 String dumpPackage) { 11770 int numPers = 0; 11771 final int N = list.size()-1; 11772 for (int i=N; i>=0; i--) { 11773 ProcessRecord r = (ProcessRecord)list.get(i); 11774 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11775 continue; 11776 } 11777 pw.println(String.format("%s%s #%2d: %s", 11778 prefix, (r.persistent ? persistentLabel : normalLabel), 11779 i, r.toString())); 11780 if (r.persistent) { 11781 numPers++; 11782 } 11783 } 11784 return numPers; 11785 } 11786 11787 private static final boolean dumpProcessOomList(PrintWriter pw, 11788 ActivityManagerService service, List<ProcessRecord> origList, 11789 String prefix, String normalLabel, String persistentLabel, 11790 boolean inclDetails, String dumpPackage) { 11791 11792 ArrayList<Pair<ProcessRecord, Integer>> list 11793 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11794 for (int i=0; i<origList.size(); i++) { 11795 ProcessRecord r = origList.get(i); 11796 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11797 continue; 11798 } 11799 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11800 } 11801 11802 if (list.size() <= 0) { 11803 return false; 11804 } 11805 11806 Comparator<Pair<ProcessRecord, Integer>> comparator 11807 = new Comparator<Pair<ProcessRecord, Integer>>() { 11808 @Override 11809 public int compare(Pair<ProcessRecord, Integer> object1, 11810 Pair<ProcessRecord, Integer> object2) { 11811 if (object1.first.setAdj != object2.first.setAdj) { 11812 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11813 } 11814 if (object1.second.intValue() != object2.second.intValue()) { 11815 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11816 } 11817 return 0; 11818 } 11819 }; 11820 11821 Collections.sort(list, comparator); 11822 11823 final long curRealtime = SystemClock.elapsedRealtime(); 11824 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11825 final long curUptime = SystemClock.uptimeMillis(); 11826 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11827 11828 for (int i=list.size()-1; i>=0; i--) { 11829 ProcessRecord r = list.get(i).first; 11830 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11831 char schedGroup; 11832 switch (r.setSchedGroup) { 11833 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11834 schedGroup = 'B'; 11835 break; 11836 case Process.THREAD_GROUP_DEFAULT: 11837 schedGroup = 'F'; 11838 break; 11839 default: 11840 schedGroup = '?'; 11841 break; 11842 } 11843 char foreground; 11844 if (r.foregroundActivities) { 11845 foreground = 'A'; 11846 } else if (r.foregroundServices) { 11847 foreground = 'S'; 11848 } else { 11849 foreground = ' '; 11850 } 11851 String procState = ProcessList.makeProcStateString(r.curProcState); 11852 pw.print(prefix); 11853 pw.print(r.persistent ? persistentLabel : normalLabel); 11854 pw.print(" #"); 11855 int num = (origList.size()-1)-list.get(i).second; 11856 if (num < 10) pw.print(' '); 11857 pw.print(num); 11858 pw.print(": "); 11859 pw.print(oomAdj); 11860 pw.print(' '); 11861 pw.print(schedGroup); 11862 pw.print('/'); 11863 pw.print(foreground); 11864 pw.print('/'); 11865 pw.print(procState); 11866 pw.print(" trm:"); 11867 if (r.trimMemoryLevel < 10) pw.print(' '); 11868 pw.print(r.trimMemoryLevel); 11869 pw.print(' '); 11870 pw.print(r.toShortString()); 11871 pw.print(" ("); 11872 pw.print(r.adjType); 11873 pw.println(')'); 11874 if (r.adjSource != null || r.adjTarget != null) { 11875 pw.print(prefix); 11876 pw.print(" "); 11877 if (r.adjTarget instanceof ComponentName) { 11878 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11879 } else if (r.adjTarget != null) { 11880 pw.print(r.adjTarget.toString()); 11881 } else { 11882 pw.print("{null}"); 11883 } 11884 pw.print("<="); 11885 if (r.adjSource instanceof ProcessRecord) { 11886 pw.print("Proc{"); 11887 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11888 pw.println("}"); 11889 } else if (r.adjSource != null) { 11890 pw.println(r.adjSource.toString()); 11891 } else { 11892 pw.println("{null}"); 11893 } 11894 } 11895 if (inclDetails) { 11896 pw.print(prefix); 11897 pw.print(" "); 11898 pw.print("oom: max="); pw.print(r.maxAdj); 11899 pw.print(" curRaw="); pw.print(r.curRawAdj); 11900 pw.print(" setRaw="); pw.print(r.setRawAdj); 11901 pw.print(" cur="); pw.print(r.curAdj); 11902 pw.print(" set="); pw.println(r.setAdj); 11903 pw.print(prefix); 11904 pw.print(" "); 11905 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11906 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11907 pw.print(" lastPss="); pw.print(r.lastPss); 11908 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11909 pw.print(prefix); 11910 pw.print(" "); 11911 pw.print("keeping="); pw.print(r.keeping); 11912 pw.print(" cached="); pw.print(r.cached); 11913 pw.print(" empty="); pw.print(r.empty); 11914 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11915 11916 if (!r.keeping) { 11917 if (r.lastWakeTime != 0) { 11918 long wtime; 11919 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11920 synchronized (stats) { 11921 wtime = stats.getProcessWakeTime(r.info.uid, 11922 r.pid, curRealtime); 11923 } 11924 long timeUsed = wtime - r.lastWakeTime; 11925 pw.print(prefix); 11926 pw.print(" "); 11927 pw.print("keep awake over "); 11928 TimeUtils.formatDuration(realtimeSince, pw); 11929 pw.print(" used "); 11930 TimeUtils.formatDuration(timeUsed, pw); 11931 pw.print(" ("); 11932 pw.print((timeUsed*100)/realtimeSince); 11933 pw.println("%)"); 11934 } 11935 if (r.lastCpuTime != 0) { 11936 long timeUsed = r.curCpuTime - r.lastCpuTime; 11937 pw.print(prefix); 11938 pw.print(" "); 11939 pw.print("run cpu over "); 11940 TimeUtils.formatDuration(uptimeSince, pw); 11941 pw.print(" used "); 11942 TimeUtils.formatDuration(timeUsed, pw); 11943 pw.print(" ("); 11944 pw.print((timeUsed*100)/uptimeSince); 11945 pw.println("%)"); 11946 } 11947 } 11948 } 11949 } 11950 return true; 11951 } 11952 11953 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11954 ArrayList<ProcessRecord> procs; 11955 synchronized (this) { 11956 if (args != null && args.length > start 11957 && args[start].charAt(0) != '-') { 11958 procs = new ArrayList<ProcessRecord>(); 11959 int pid = -1; 11960 try { 11961 pid = Integer.parseInt(args[start]); 11962 } catch (NumberFormatException e) { 11963 } 11964 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11965 ProcessRecord proc = mLruProcesses.get(i); 11966 if (proc.pid == pid) { 11967 procs.add(proc); 11968 } else if (proc.processName.equals(args[start])) { 11969 procs.add(proc); 11970 } 11971 } 11972 if (procs.size() <= 0) { 11973 return null; 11974 } 11975 } else { 11976 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11977 } 11978 } 11979 return procs; 11980 } 11981 11982 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11983 PrintWriter pw, String[] args) { 11984 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11985 if (procs == null) { 11986 pw.println("No process found for: " + args[0]); 11987 return; 11988 } 11989 11990 long uptime = SystemClock.uptimeMillis(); 11991 long realtime = SystemClock.elapsedRealtime(); 11992 pw.println("Applications Graphics Acceleration Info:"); 11993 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11994 11995 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11996 ProcessRecord r = procs.get(i); 11997 if (r.thread != null) { 11998 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11999 pw.flush(); 12000 try { 12001 TransferPipe tp = new TransferPipe(); 12002 try { 12003 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12004 tp.go(fd); 12005 } finally { 12006 tp.kill(); 12007 } 12008 } catch (IOException e) { 12009 pw.println("Failure while dumping the app: " + r); 12010 pw.flush(); 12011 } catch (RemoteException e) { 12012 pw.println("Got a RemoteException while dumping the app " + r); 12013 pw.flush(); 12014 } 12015 } 12016 } 12017 } 12018 12019 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12020 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12021 if (procs == null) { 12022 pw.println("No process found for: " + args[0]); 12023 return; 12024 } 12025 12026 pw.println("Applications Database Info:"); 12027 12028 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12029 ProcessRecord r = procs.get(i); 12030 if (r.thread != null) { 12031 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12032 pw.flush(); 12033 try { 12034 TransferPipe tp = new TransferPipe(); 12035 try { 12036 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12037 tp.go(fd); 12038 } finally { 12039 tp.kill(); 12040 } 12041 } catch (IOException e) { 12042 pw.println("Failure while dumping the app: " + r); 12043 pw.flush(); 12044 } catch (RemoteException e) { 12045 pw.println("Got a RemoteException while dumping the app " + r); 12046 pw.flush(); 12047 } 12048 } 12049 } 12050 } 12051 12052 final static class MemItem { 12053 final boolean isProc; 12054 final String label; 12055 final String shortLabel; 12056 final long pss; 12057 final int id; 12058 final boolean hasActivities; 12059 ArrayList<MemItem> subitems; 12060 12061 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12062 boolean _hasActivities) { 12063 isProc = true; 12064 label = _label; 12065 shortLabel = _shortLabel; 12066 pss = _pss; 12067 id = _id; 12068 hasActivities = _hasActivities; 12069 } 12070 12071 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12072 isProc = false; 12073 label = _label; 12074 shortLabel = _shortLabel; 12075 pss = _pss; 12076 id = _id; 12077 hasActivities = false; 12078 } 12079 } 12080 12081 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12082 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12083 if (sort && !isCompact) { 12084 Collections.sort(items, new Comparator<MemItem>() { 12085 @Override 12086 public int compare(MemItem lhs, MemItem rhs) { 12087 if (lhs.pss < rhs.pss) { 12088 return 1; 12089 } else if (lhs.pss > rhs.pss) { 12090 return -1; 12091 } 12092 return 0; 12093 } 12094 }); 12095 } 12096 12097 for (int i=0; i<items.size(); i++) { 12098 MemItem mi = items.get(i); 12099 if (!isCompact) { 12100 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12101 } else if (mi.isProc) { 12102 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12103 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12104 pw.println(mi.hasActivities ? ",a" : ",e"); 12105 } else { 12106 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12107 pw.println(mi.pss); 12108 } 12109 if (mi.subitems != null) { 12110 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12111 true, isCompact); 12112 } 12113 } 12114 } 12115 12116 // These are in KB. 12117 static final long[] DUMP_MEM_BUCKETS = new long[] { 12118 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12119 120*1024, 160*1024, 200*1024, 12120 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12121 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12122 }; 12123 12124 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12125 boolean stackLike) { 12126 int start = label.lastIndexOf('.'); 12127 if (start >= 0) start++; 12128 else start = 0; 12129 int end = label.length(); 12130 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12131 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12132 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12133 out.append(bucket); 12134 out.append(stackLike ? "MB." : "MB "); 12135 out.append(label, start, end); 12136 return; 12137 } 12138 } 12139 out.append(memKB/1024); 12140 out.append(stackLike ? "MB." : "MB "); 12141 out.append(label, start, end); 12142 } 12143 12144 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12145 ProcessList.NATIVE_ADJ, 12146 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12147 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12148 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12149 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12150 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12151 }; 12152 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12153 "Native", 12154 "System", "Persistent", "Foreground", 12155 "Visible", "Perceptible", 12156 "Heavy Weight", "Backup", 12157 "A Services", "Home", 12158 "Previous", "B Services", "Cached" 12159 }; 12160 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12161 "native", 12162 "sys", "pers", "fore", 12163 "vis", "percept", 12164 "heavy", "backup", 12165 "servicea", "home", 12166 "prev", "serviceb", "cached" 12167 }; 12168 12169 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12170 long realtime, boolean isCheckinRequest, boolean isCompact) { 12171 if (isCheckinRequest || isCompact) { 12172 // short checkin version 12173 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12174 } else { 12175 pw.println("Applications Memory Usage (kB):"); 12176 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12177 } 12178 } 12179 12180 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12181 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12182 boolean dumpDetails = false; 12183 boolean dumpFullDetails = false; 12184 boolean dumpDalvik = false; 12185 boolean oomOnly = false; 12186 boolean isCompact = false; 12187 boolean localOnly = false; 12188 12189 int opti = 0; 12190 while (opti < args.length) { 12191 String opt = args[opti]; 12192 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12193 break; 12194 } 12195 opti++; 12196 if ("-a".equals(opt)) { 12197 dumpDetails = true; 12198 dumpFullDetails = true; 12199 dumpDalvik = true; 12200 } else if ("-d".equals(opt)) { 12201 dumpDalvik = true; 12202 } else if ("-c".equals(opt)) { 12203 isCompact = true; 12204 } else if ("--oom".equals(opt)) { 12205 oomOnly = true; 12206 } else if ("--local".equals(opt)) { 12207 localOnly = true; 12208 } else if ("-h".equals(opt)) { 12209 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12210 pw.println(" -a: include all available information for each process."); 12211 pw.println(" -d: include dalvik details when dumping process details."); 12212 pw.println(" -c: dump in a compact machine-parseable representation."); 12213 pw.println(" --oom: only show processes organized by oom adj."); 12214 pw.println(" --local: only collect details locally, don't call process."); 12215 pw.println("If [process] is specified it can be the name or "); 12216 pw.println("pid of a specific process to dump."); 12217 return; 12218 } else { 12219 pw.println("Unknown argument: " + opt + "; use -h for help"); 12220 } 12221 } 12222 12223 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12224 long uptime = SystemClock.uptimeMillis(); 12225 long realtime = SystemClock.elapsedRealtime(); 12226 final long[] tmpLong = new long[1]; 12227 12228 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12229 if (procs == null) { 12230 // No Java processes. Maybe they want to print a native process. 12231 if (args != null && args.length > opti 12232 && args[opti].charAt(0) != '-') { 12233 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12234 = new ArrayList<ProcessCpuTracker.Stats>(); 12235 updateCpuStatsNow(); 12236 int findPid = -1; 12237 try { 12238 findPid = Integer.parseInt(args[opti]); 12239 } catch (NumberFormatException e) { 12240 } 12241 synchronized (mProcessCpuThread) { 12242 final int N = mProcessCpuTracker.countStats(); 12243 for (int i=0; i<N; i++) { 12244 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12245 if (st.pid == findPid || (st.baseName != null 12246 && st.baseName.equals(args[opti]))) { 12247 nativeProcs.add(st); 12248 } 12249 } 12250 } 12251 if (nativeProcs.size() > 0) { 12252 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12253 isCompact); 12254 Debug.MemoryInfo mi = null; 12255 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12256 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12257 final int pid = r.pid; 12258 if (!isCheckinRequest && dumpDetails) { 12259 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12260 } 12261 if (mi == null) { 12262 mi = new Debug.MemoryInfo(); 12263 } 12264 if (dumpDetails || (!brief && !oomOnly)) { 12265 Debug.getMemoryInfo(pid, mi); 12266 } else { 12267 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12268 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12269 } 12270 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12271 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12272 if (isCheckinRequest) { 12273 pw.println(); 12274 } 12275 } 12276 return; 12277 } 12278 } 12279 pw.println("No process found for: " + args[opti]); 12280 return; 12281 } 12282 12283 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12284 dumpDetails = true; 12285 } 12286 12287 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12288 12289 String[] innerArgs = new String[args.length-opti]; 12290 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12291 12292 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12293 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12294 long nativePss=0, dalvikPss=0, otherPss=0; 12295 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12296 12297 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12298 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12299 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12300 12301 long totalPss = 0; 12302 long cachedPss = 0; 12303 12304 Debug.MemoryInfo mi = null; 12305 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12306 final ProcessRecord r = procs.get(i); 12307 final IApplicationThread thread; 12308 final int pid; 12309 final int oomAdj; 12310 final boolean hasActivities; 12311 synchronized (this) { 12312 thread = r.thread; 12313 pid = r.pid; 12314 oomAdj = r.getSetAdjWithServices(); 12315 hasActivities = r.activities.size() > 0; 12316 } 12317 if (thread != null) { 12318 if (!isCheckinRequest && dumpDetails) { 12319 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12320 } 12321 if (mi == null) { 12322 mi = new Debug.MemoryInfo(); 12323 } 12324 if (dumpDetails || (!brief && !oomOnly)) { 12325 Debug.getMemoryInfo(pid, mi); 12326 } else { 12327 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12328 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12329 } 12330 if (dumpDetails) { 12331 if (localOnly) { 12332 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12333 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12334 if (isCheckinRequest) { 12335 pw.println(); 12336 } 12337 } else { 12338 try { 12339 pw.flush(); 12340 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12341 dumpDalvik, innerArgs); 12342 } catch (RemoteException e) { 12343 if (!isCheckinRequest) { 12344 pw.println("Got RemoteException!"); 12345 pw.flush(); 12346 } 12347 } 12348 } 12349 } 12350 12351 final long myTotalPss = mi.getTotalPss(); 12352 final long myTotalUss = mi.getTotalUss(); 12353 12354 synchronized (this) { 12355 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12356 // Record this for posterity if the process has been stable. 12357 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12358 } 12359 } 12360 12361 if (!isCheckinRequest && mi != null) { 12362 totalPss += myTotalPss; 12363 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12364 (hasActivities ? " / activities)" : ")"), 12365 r.processName, myTotalPss, pid, hasActivities); 12366 procMems.add(pssItem); 12367 procMemsMap.put(pid, pssItem); 12368 12369 nativePss += mi.nativePss; 12370 dalvikPss += mi.dalvikPss; 12371 otherPss += mi.otherPss; 12372 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12373 long mem = mi.getOtherPss(j); 12374 miscPss[j] += mem; 12375 otherPss -= mem; 12376 } 12377 12378 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12379 cachedPss += myTotalPss; 12380 } 12381 12382 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12383 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12384 || oomIndex == (oomPss.length-1)) { 12385 oomPss[oomIndex] += myTotalPss; 12386 if (oomProcs[oomIndex] == null) { 12387 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12388 } 12389 oomProcs[oomIndex].add(pssItem); 12390 break; 12391 } 12392 } 12393 } 12394 } 12395 } 12396 12397 if (!isCheckinRequest && procs.size() > 1) { 12398 // If we are showing aggregations, also look for native processes to 12399 // include so that our aggregations are more accurate. 12400 updateCpuStatsNow(); 12401 synchronized (mProcessCpuThread) { 12402 final int N = mProcessCpuTracker.countStats(); 12403 for (int i=0; i<N; i++) { 12404 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12405 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12406 if (mi == null) { 12407 mi = new Debug.MemoryInfo(); 12408 } 12409 if (!brief && !oomOnly) { 12410 Debug.getMemoryInfo(st.pid, mi); 12411 } else { 12412 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12413 mi.nativePrivateDirty = (int)tmpLong[0]; 12414 } 12415 12416 final long myTotalPss = mi.getTotalPss(); 12417 totalPss += myTotalPss; 12418 12419 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12420 st.name, myTotalPss, st.pid, false); 12421 procMems.add(pssItem); 12422 12423 nativePss += mi.nativePss; 12424 dalvikPss += mi.dalvikPss; 12425 otherPss += mi.otherPss; 12426 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12427 long mem = mi.getOtherPss(j); 12428 miscPss[j] += mem; 12429 otherPss -= mem; 12430 } 12431 oomPss[0] += myTotalPss; 12432 if (oomProcs[0] == null) { 12433 oomProcs[0] = new ArrayList<MemItem>(); 12434 } 12435 oomProcs[0].add(pssItem); 12436 } 12437 } 12438 } 12439 12440 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12441 12442 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12443 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12444 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12445 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12446 String label = Debug.MemoryInfo.getOtherLabel(j); 12447 catMems.add(new MemItem(label, label, miscPss[j], j)); 12448 } 12449 12450 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12451 for (int j=0; j<oomPss.length; j++) { 12452 if (oomPss[j] != 0) { 12453 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12454 : DUMP_MEM_OOM_LABEL[j]; 12455 MemItem item = new MemItem(label, label, oomPss[j], 12456 DUMP_MEM_OOM_ADJ[j]); 12457 item.subitems = oomProcs[j]; 12458 oomMems.add(item); 12459 } 12460 } 12461 12462 if (!brief && !oomOnly && !isCompact) { 12463 pw.println(); 12464 pw.println("Total PSS by process:"); 12465 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12466 pw.println(); 12467 } 12468 if (!isCompact) { 12469 pw.println("Total PSS by OOM adjustment:"); 12470 } 12471 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12472 if (!brief && !oomOnly) { 12473 PrintWriter out = categoryPw != null ? categoryPw : pw; 12474 if (!isCompact) { 12475 out.println(); 12476 out.println("Total PSS by category:"); 12477 } 12478 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12479 } 12480 if (!isCompact) { 12481 pw.println(); 12482 } 12483 MemInfoReader memInfo = new MemInfoReader(); 12484 memInfo.readMemInfo(); 12485 if (!brief) { 12486 if (!isCompact) { 12487 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12488 pw.print(" kB (status "); 12489 switch (mLastMemoryLevel) { 12490 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12491 pw.println("normal)"); 12492 break; 12493 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12494 pw.println("moderate)"); 12495 break; 12496 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12497 pw.println("low)"); 12498 break; 12499 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12500 pw.println("critical)"); 12501 break; 12502 default: 12503 pw.print(mLastMemoryLevel); 12504 pw.println(")"); 12505 break; 12506 } 12507 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12508 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12509 pw.print(cachedPss); pw.print(" cached pss + "); 12510 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12511 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12512 } else { 12513 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12514 pw.print(cachedPss + memInfo.getCachedSizeKb() 12515 + memInfo.getFreeSizeKb()); pw.print(","); 12516 pw.println(totalPss - cachedPss); 12517 } 12518 } 12519 if (!isCompact) { 12520 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12521 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12522 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12523 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12524 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12525 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12526 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12527 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12528 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12529 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12530 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12531 } 12532 if (!brief) { 12533 if (memInfo.getZramTotalSizeKb() != 0) { 12534 if (!isCompact) { 12535 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12536 pw.print(" kB physical used for "); 12537 pw.print(memInfo.getSwapTotalSizeKb() 12538 - memInfo.getSwapFreeSizeKb()); 12539 pw.print(" kB in swap ("); 12540 pw.print(memInfo.getSwapTotalSizeKb()); 12541 pw.println(" kB total swap)"); 12542 } else { 12543 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12544 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12545 pw.println(memInfo.getSwapFreeSizeKb()); 12546 } 12547 } 12548 final int[] SINGLE_LONG_FORMAT = new int[] { 12549 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12550 }; 12551 long[] longOut = new long[1]; 12552 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12553 SINGLE_LONG_FORMAT, null, longOut, null); 12554 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12555 longOut[0] = 0; 12556 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12557 SINGLE_LONG_FORMAT, null, longOut, null); 12558 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12559 longOut[0] = 0; 12560 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12561 SINGLE_LONG_FORMAT, null, longOut, null); 12562 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12563 longOut[0] = 0; 12564 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12565 SINGLE_LONG_FORMAT, null, longOut, null); 12566 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12567 if (!isCompact) { 12568 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12569 pw.print(" KSM: "); pw.print(sharing); 12570 pw.print(" kB saved from shared "); 12571 pw.print(shared); pw.println(" kB"); 12572 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12573 pw.print(voltile); pw.println(" kB volatile"); 12574 } 12575 pw.print(" Tuning: "); 12576 pw.print(ActivityManager.staticGetMemoryClass()); 12577 pw.print(" (large "); 12578 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12579 pw.print("), oom "); 12580 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12581 pw.print(" kB"); 12582 pw.print(", restore limit "); 12583 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12584 pw.print(" kB"); 12585 if (ActivityManager.isLowRamDeviceStatic()) { 12586 pw.print(" (low-ram)"); 12587 } 12588 if (ActivityManager.isHighEndGfx()) { 12589 pw.print(" (high-end-gfx)"); 12590 } 12591 pw.println(); 12592 } else { 12593 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12594 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12595 pw.println(voltile); 12596 pw.print("tuning,"); 12597 pw.print(ActivityManager.staticGetMemoryClass()); 12598 pw.print(','); 12599 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12600 pw.print(','); 12601 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12602 if (ActivityManager.isLowRamDeviceStatic()) { 12603 pw.print(",low-ram"); 12604 } 12605 if (ActivityManager.isHighEndGfx()) { 12606 pw.print(",high-end-gfx"); 12607 } 12608 pw.println(); 12609 } 12610 } 12611 } 12612 } 12613 12614 /** 12615 * Searches array of arguments for the specified string 12616 * @param args array of argument strings 12617 * @param value value to search for 12618 * @return true if the value is contained in the array 12619 */ 12620 private static boolean scanArgs(String[] args, String value) { 12621 if (args != null) { 12622 for (String arg : args) { 12623 if (value.equals(arg)) { 12624 return true; 12625 } 12626 } 12627 } 12628 return false; 12629 } 12630 12631 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12632 ContentProviderRecord cpr, boolean always) { 12633 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12634 12635 if (!inLaunching || always) { 12636 synchronized (cpr) { 12637 cpr.launchingApp = null; 12638 cpr.notifyAll(); 12639 } 12640 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12641 String names[] = cpr.info.authority.split(";"); 12642 for (int j = 0; j < names.length; j++) { 12643 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12644 } 12645 } 12646 12647 for (int i=0; i<cpr.connections.size(); i++) { 12648 ContentProviderConnection conn = cpr.connections.get(i); 12649 if (conn.waiting) { 12650 // If this connection is waiting for the provider, then we don't 12651 // need to mess with its process unless we are always removing 12652 // or for some reason the provider is not currently launching. 12653 if (inLaunching && !always) { 12654 continue; 12655 } 12656 } 12657 ProcessRecord capp = conn.client; 12658 conn.dead = true; 12659 if (conn.stableCount > 0) { 12660 if (!capp.persistent && capp.thread != null 12661 && capp.pid != 0 12662 && capp.pid != MY_PID) { 12663 killUnneededProcessLocked(capp, "depends on provider " 12664 + cpr.name.flattenToShortString() 12665 + " in dying proc " + (proc != null ? proc.processName : "??")); 12666 } 12667 } else if (capp.thread != null && conn.provider.provider != null) { 12668 try { 12669 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12670 } catch (RemoteException e) { 12671 } 12672 // In the protocol here, we don't expect the client to correctly 12673 // clean up this connection, we'll just remove it. 12674 cpr.connections.remove(i); 12675 conn.client.conProviders.remove(conn); 12676 } 12677 } 12678 12679 if (inLaunching && always) { 12680 mLaunchingProviders.remove(cpr); 12681 } 12682 return inLaunching; 12683 } 12684 12685 /** 12686 * Main code for cleaning up a process when it has gone away. This is 12687 * called both as a result of the process dying, or directly when stopping 12688 * a process when running in single process mode. 12689 */ 12690 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12691 boolean restarting, boolean allowRestart, int index) { 12692 if (index >= 0) { 12693 removeLruProcessLocked(app); 12694 ProcessList.remove(app.pid); 12695 } 12696 12697 mProcessesToGc.remove(app); 12698 mPendingPssProcesses.remove(app); 12699 12700 // Dismiss any open dialogs. 12701 if (app.crashDialog != null && !app.forceCrashReport) { 12702 app.crashDialog.dismiss(); 12703 app.crashDialog = null; 12704 } 12705 if (app.anrDialog != null) { 12706 app.anrDialog.dismiss(); 12707 app.anrDialog = null; 12708 } 12709 if (app.waitDialog != null) { 12710 app.waitDialog.dismiss(); 12711 app.waitDialog = null; 12712 } 12713 12714 app.crashing = false; 12715 app.notResponding = false; 12716 12717 app.resetPackageList(mProcessStats); 12718 app.unlinkDeathRecipient(); 12719 app.makeInactive(mProcessStats); 12720 app.forcingToForeground = null; 12721 updateProcessForegroundLocked(app, false, false); 12722 app.foregroundActivities = false; 12723 app.hasShownUi = false; 12724 app.treatLikeActivity = false; 12725 app.hasAboveClient = false; 12726 app.hasClientActivities = false; 12727 12728 mServices.killServicesLocked(app, allowRestart); 12729 12730 boolean restart = false; 12731 12732 // Remove published content providers. 12733 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12734 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12735 final boolean always = app.bad || !allowRestart; 12736 if (removeDyingProviderLocked(app, cpr, always) || always) { 12737 // We left the provider in the launching list, need to 12738 // restart it. 12739 restart = true; 12740 } 12741 12742 cpr.provider = null; 12743 cpr.proc = null; 12744 } 12745 app.pubProviders.clear(); 12746 12747 // Take care of any launching providers waiting for this process. 12748 if (checkAppInLaunchingProvidersLocked(app, false)) { 12749 restart = true; 12750 } 12751 12752 // Unregister from connected content providers. 12753 if (!app.conProviders.isEmpty()) { 12754 for (int i=0; i<app.conProviders.size(); i++) { 12755 ContentProviderConnection conn = app.conProviders.get(i); 12756 conn.provider.connections.remove(conn); 12757 } 12758 app.conProviders.clear(); 12759 } 12760 12761 // At this point there may be remaining entries in mLaunchingProviders 12762 // where we were the only one waiting, so they are no longer of use. 12763 // Look for these and clean up if found. 12764 // XXX Commented out for now. Trying to figure out a way to reproduce 12765 // the actual situation to identify what is actually going on. 12766 if (false) { 12767 for (int i=0; i<mLaunchingProviders.size(); i++) { 12768 ContentProviderRecord cpr = (ContentProviderRecord) 12769 mLaunchingProviders.get(i); 12770 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12771 synchronized (cpr) { 12772 cpr.launchingApp = null; 12773 cpr.notifyAll(); 12774 } 12775 } 12776 } 12777 } 12778 12779 skipCurrentReceiverLocked(app); 12780 12781 // Unregister any receivers. 12782 for (int i=app.receivers.size()-1; i>=0; i--) { 12783 removeReceiverLocked(app.receivers.valueAt(i)); 12784 } 12785 app.receivers.clear(); 12786 12787 // If the app is undergoing backup, tell the backup manager about it 12788 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12789 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12790 + mBackupTarget.appInfo + " died during backup"); 12791 try { 12792 IBackupManager bm = IBackupManager.Stub.asInterface( 12793 ServiceManager.getService(Context.BACKUP_SERVICE)); 12794 bm.agentDisconnected(app.info.packageName); 12795 } catch (RemoteException e) { 12796 // can't happen; backup manager is local 12797 } 12798 } 12799 12800 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12801 ProcessChangeItem item = mPendingProcessChanges.get(i); 12802 if (item.pid == app.pid) { 12803 mPendingProcessChanges.remove(i); 12804 mAvailProcessChanges.add(item); 12805 } 12806 } 12807 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12808 12809 // If the caller is restarting this app, then leave it in its 12810 // current lists and let the caller take care of it. 12811 if (restarting) { 12812 return; 12813 } 12814 12815 if (!app.persistent || app.isolated) { 12816 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12817 "Removing non-persistent process during cleanup: " + app); 12818 mProcessNames.remove(app.processName, app.uid); 12819 mIsolatedProcesses.remove(app.uid); 12820 if (mHeavyWeightProcess == app) { 12821 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12822 mHeavyWeightProcess.userId, 0)); 12823 mHeavyWeightProcess = null; 12824 } 12825 } else if (!app.removed) { 12826 // This app is persistent, so we need to keep its record around. 12827 // If it is not already on the pending app list, add it there 12828 // and start a new process for it. 12829 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12830 mPersistentStartingProcesses.add(app); 12831 restart = true; 12832 } 12833 } 12834 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12835 "Clean-up removing on hold: " + app); 12836 mProcessesOnHold.remove(app); 12837 12838 if (app == mHomeProcess) { 12839 mHomeProcess = null; 12840 } 12841 if (app == mPreviousProcess) { 12842 mPreviousProcess = null; 12843 } 12844 12845 if (restart && !app.isolated) { 12846 // We have components that still need to be running in the 12847 // process, so re-launch it. 12848 mProcessNames.put(app.processName, app.uid, app); 12849 startProcessLocked(app, "restart", app.processName); 12850 } else if (app.pid > 0 && app.pid != MY_PID) { 12851 // Goodbye! 12852 boolean removed; 12853 synchronized (mPidsSelfLocked) { 12854 mPidsSelfLocked.remove(app.pid); 12855 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12856 } 12857 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12858 app.processName, app.info.uid); 12859 if (app.isolated) { 12860 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12861 } 12862 app.setPid(0); 12863 } 12864 } 12865 12866 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12867 // Look through the content providers we are waiting to have launched, 12868 // and if any run in this process then either schedule a restart of 12869 // the process or kill the client waiting for it if this process has 12870 // gone bad. 12871 int NL = mLaunchingProviders.size(); 12872 boolean restart = false; 12873 for (int i=0; i<NL; i++) { 12874 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12875 if (cpr.launchingApp == app) { 12876 if (!alwaysBad && !app.bad) { 12877 restart = true; 12878 } else { 12879 removeDyingProviderLocked(app, cpr, true); 12880 // cpr should have been removed from mLaunchingProviders 12881 NL = mLaunchingProviders.size(); 12882 i--; 12883 } 12884 } 12885 } 12886 return restart; 12887 } 12888 12889 // ========================================================= 12890 // SERVICES 12891 // ========================================================= 12892 12893 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12894 int flags) { 12895 enforceNotIsolatedCaller("getServices"); 12896 synchronized (this) { 12897 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12898 } 12899 } 12900 12901 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12902 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12903 synchronized (this) { 12904 return mServices.getRunningServiceControlPanelLocked(name); 12905 } 12906 } 12907 12908 public ComponentName startService(IApplicationThread caller, Intent service, 12909 String resolvedType, int userId) { 12910 enforceNotIsolatedCaller("startService"); 12911 // Refuse possible leaked file descriptors 12912 if (service != null && service.hasFileDescriptors() == true) { 12913 throw new IllegalArgumentException("File descriptors passed in Intent"); 12914 } 12915 12916 if (DEBUG_SERVICE) 12917 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12918 synchronized(this) { 12919 final int callingPid = Binder.getCallingPid(); 12920 final int callingUid = Binder.getCallingUid(); 12921 final long origId = Binder.clearCallingIdentity(); 12922 ComponentName res = mServices.startServiceLocked(caller, service, 12923 resolvedType, callingPid, callingUid, userId); 12924 Binder.restoreCallingIdentity(origId); 12925 return res; 12926 } 12927 } 12928 12929 ComponentName startServiceInPackage(int uid, 12930 Intent service, String resolvedType, int userId) { 12931 synchronized(this) { 12932 if (DEBUG_SERVICE) 12933 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12934 final long origId = Binder.clearCallingIdentity(); 12935 ComponentName res = mServices.startServiceLocked(null, service, 12936 resolvedType, -1, uid, userId); 12937 Binder.restoreCallingIdentity(origId); 12938 return res; 12939 } 12940 } 12941 12942 public int stopService(IApplicationThread caller, Intent service, 12943 String resolvedType, int userId) { 12944 enforceNotIsolatedCaller("stopService"); 12945 // Refuse possible leaked file descriptors 12946 if (service != null && service.hasFileDescriptors() == true) { 12947 throw new IllegalArgumentException("File descriptors passed in Intent"); 12948 } 12949 12950 synchronized(this) { 12951 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12952 } 12953 } 12954 12955 public IBinder peekService(Intent service, String resolvedType) { 12956 enforceNotIsolatedCaller("peekService"); 12957 // Refuse possible leaked file descriptors 12958 if (service != null && service.hasFileDescriptors() == true) { 12959 throw new IllegalArgumentException("File descriptors passed in Intent"); 12960 } 12961 synchronized(this) { 12962 return mServices.peekServiceLocked(service, resolvedType); 12963 } 12964 } 12965 12966 public boolean stopServiceToken(ComponentName className, IBinder token, 12967 int startId) { 12968 synchronized(this) { 12969 return mServices.stopServiceTokenLocked(className, token, startId); 12970 } 12971 } 12972 12973 public void setServiceForeground(ComponentName className, IBinder token, 12974 int id, Notification notification, boolean removeNotification) { 12975 synchronized(this) { 12976 mServices.setServiceForegroundLocked(className, token, id, notification, 12977 removeNotification); 12978 } 12979 } 12980 12981 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12982 boolean requireFull, String name, String callerPackage) { 12983 final int callingUserId = UserHandle.getUserId(callingUid); 12984 if (callingUserId != userId) { 12985 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12986 if ((requireFull || checkComponentPermission( 12987 android.Manifest.permission.INTERACT_ACROSS_USERS, 12988 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12989 && checkComponentPermission( 12990 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12991 callingPid, callingUid, -1, true) 12992 != PackageManager.PERMISSION_GRANTED) { 12993 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12994 // In this case, they would like to just execute as their 12995 // owner user instead of failing. 12996 userId = callingUserId; 12997 } else { 12998 StringBuilder builder = new StringBuilder(128); 12999 builder.append("Permission Denial: "); 13000 builder.append(name); 13001 if (callerPackage != null) { 13002 builder.append(" from "); 13003 builder.append(callerPackage); 13004 } 13005 builder.append(" asks to run as user "); 13006 builder.append(userId); 13007 builder.append(" but is calling from user "); 13008 builder.append(UserHandle.getUserId(callingUid)); 13009 builder.append("; this requires "); 13010 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 13011 if (!requireFull) { 13012 builder.append(" or "); 13013 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13014 } 13015 String msg = builder.toString(); 13016 Slog.w(TAG, msg); 13017 throw new SecurityException(msg); 13018 } 13019 } 13020 } 13021 if (userId == UserHandle.USER_CURRENT 13022 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13023 // Note that we may be accessing this outside of a lock... 13024 // shouldn't be a big deal, if this is being called outside 13025 // of a locked context there is intrinsically a race with 13026 // the value the caller will receive and someone else changing it. 13027 userId = mCurrentUserId; 13028 } 13029 if (!allowAll && userId < 0) { 13030 throw new IllegalArgumentException( 13031 "Call does not support special user #" + userId); 13032 } 13033 } 13034 return userId; 13035 } 13036 13037 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13038 String className, int flags) { 13039 boolean result = false; 13040 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13041 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 13042 if (ActivityManager.checkUidPermission( 13043 android.Manifest.permission.INTERACT_ACROSS_USERS, 13044 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13045 ComponentName comp = new ComponentName(aInfo.packageName, className); 13046 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13047 + " requests FLAG_SINGLE_USER, but app does not hold " 13048 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13049 Slog.w(TAG, msg); 13050 throw new SecurityException(msg); 13051 } 13052 result = true; 13053 } 13054 } else if (componentProcessName == aInfo.packageName) { 13055 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13056 } else if ("system".equals(componentProcessName)) { 13057 result = true; 13058 } 13059 if (DEBUG_MU) { 13060 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13061 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13062 } 13063 return result; 13064 } 13065 13066 public int bindService(IApplicationThread caller, IBinder token, 13067 Intent service, String resolvedType, 13068 IServiceConnection connection, int flags, int userId) { 13069 enforceNotIsolatedCaller("bindService"); 13070 // Refuse possible leaked file descriptors 13071 if (service != null && service.hasFileDescriptors() == true) { 13072 throw new IllegalArgumentException("File descriptors passed in Intent"); 13073 } 13074 13075 synchronized(this) { 13076 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13077 connection, flags, userId); 13078 } 13079 } 13080 13081 public boolean unbindService(IServiceConnection connection) { 13082 synchronized (this) { 13083 return mServices.unbindServiceLocked(connection); 13084 } 13085 } 13086 13087 public void publishService(IBinder token, Intent intent, IBinder service) { 13088 // Refuse possible leaked file descriptors 13089 if (intent != null && intent.hasFileDescriptors() == true) { 13090 throw new IllegalArgumentException("File descriptors passed in Intent"); 13091 } 13092 13093 synchronized(this) { 13094 if (!(token instanceof ServiceRecord)) { 13095 throw new IllegalArgumentException("Invalid service token"); 13096 } 13097 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13098 } 13099 } 13100 13101 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13102 // Refuse possible leaked file descriptors 13103 if (intent != null && intent.hasFileDescriptors() == true) { 13104 throw new IllegalArgumentException("File descriptors passed in Intent"); 13105 } 13106 13107 synchronized(this) { 13108 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13109 } 13110 } 13111 13112 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13113 synchronized(this) { 13114 if (!(token instanceof ServiceRecord)) { 13115 throw new IllegalArgumentException("Invalid service token"); 13116 } 13117 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13118 } 13119 } 13120 13121 // ========================================================= 13122 // BACKUP AND RESTORE 13123 // ========================================================= 13124 13125 // Cause the target app to be launched if necessary and its backup agent 13126 // instantiated. The backup agent will invoke backupAgentCreated() on the 13127 // activity manager to announce its creation. 13128 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13129 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13130 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13131 13132 synchronized(this) { 13133 // !!! TODO: currently no check here that we're already bound 13134 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13135 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13136 synchronized (stats) { 13137 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13138 } 13139 13140 // Backup agent is now in use, its package can't be stopped. 13141 try { 13142 AppGlobals.getPackageManager().setPackageStoppedState( 13143 app.packageName, false, UserHandle.getUserId(app.uid)); 13144 } catch (RemoteException e) { 13145 } catch (IllegalArgumentException e) { 13146 Slog.w(TAG, "Failed trying to unstop package " 13147 + app.packageName + ": " + e); 13148 } 13149 13150 BackupRecord r = new BackupRecord(ss, app, backupMode); 13151 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13152 ? new ComponentName(app.packageName, app.backupAgentName) 13153 : new ComponentName("android", "FullBackupAgent"); 13154 // startProcessLocked() returns existing proc's record if it's already running 13155 ProcessRecord proc = startProcessLocked(app.processName, app, 13156 false, 0, "backup", hostingName, false, false, false); 13157 if (proc == null) { 13158 Slog.e(TAG, "Unable to start backup agent process " + r); 13159 return false; 13160 } 13161 13162 r.app = proc; 13163 mBackupTarget = r; 13164 mBackupAppName = app.packageName; 13165 13166 // Try not to kill the process during backup 13167 updateOomAdjLocked(proc); 13168 13169 // If the process is already attached, schedule the creation of the backup agent now. 13170 // If it is not yet live, this will be done when it attaches to the framework. 13171 if (proc.thread != null) { 13172 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13173 try { 13174 proc.thread.scheduleCreateBackupAgent(app, 13175 compatibilityInfoForPackageLocked(app), backupMode); 13176 } catch (RemoteException e) { 13177 // Will time out on the backup manager side 13178 } 13179 } else { 13180 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13181 } 13182 // Invariants: at this point, the target app process exists and the application 13183 // is either already running or in the process of coming up. mBackupTarget and 13184 // mBackupAppName describe the app, so that when it binds back to the AM we 13185 // know that it's scheduled for a backup-agent operation. 13186 } 13187 13188 return true; 13189 } 13190 13191 @Override 13192 public void clearPendingBackup() { 13193 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13194 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13195 13196 synchronized (this) { 13197 mBackupTarget = null; 13198 mBackupAppName = null; 13199 } 13200 } 13201 13202 // A backup agent has just come up 13203 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13204 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13205 + " = " + agent); 13206 13207 synchronized(this) { 13208 if (!agentPackageName.equals(mBackupAppName)) { 13209 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13210 return; 13211 } 13212 } 13213 13214 long oldIdent = Binder.clearCallingIdentity(); 13215 try { 13216 IBackupManager bm = IBackupManager.Stub.asInterface( 13217 ServiceManager.getService(Context.BACKUP_SERVICE)); 13218 bm.agentConnected(agentPackageName, agent); 13219 } catch (RemoteException e) { 13220 // can't happen; the backup manager service is local 13221 } catch (Exception e) { 13222 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13223 e.printStackTrace(); 13224 } finally { 13225 Binder.restoreCallingIdentity(oldIdent); 13226 } 13227 } 13228 13229 // done with this agent 13230 public void unbindBackupAgent(ApplicationInfo appInfo) { 13231 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13232 if (appInfo == null) { 13233 Slog.w(TAG, "unbind backup agent for null app"); 13234 return; 13235 } 13236 13237 synchronized(this) { 13238 try { 13239 if (mBackupAppName == null) { 13240 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13241 return; 13242 } 13243 13244 if (!mBackupAppName.equals(appInfo.packageName)) { 13245 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13246 return; 13247 } 13248 13249 // Not backing this app up any more; reset its OOM adjustment 13250 final ProcessRecord proc = mBackupTarget.app; 13251 updateOomAdjLocked(proc); 13252 13253 // If the app crashed during backup, 'thread' will be null here 13254 if (proc.thread != null) { 13255 try { 13256 proc.thread.scheduleDestroyBackupAgent(appInfo, 13257 compatibilityInfoForPackageLocked(appInfo)); 13258 } catch (Exception e) { 13259 Slog.e(TAG, "Exception when unbinding backup agent:"); 13260 e.printStackTrace(); 13261 } 13262 } 13263 } finally { 13264 mBackupTarget = null; 13265 mBackupAppName = null; 13266 } 13267 } 13268 } 13269 // ========================================================= 13270 // BROADCASTS 13271 // ========================================================= 13272 13273 private final List getStickiesLocked(String action, IntentFilter filter, 13274 List cur, int userId) { 13275 final ContentResolver resolver = mContext.getContentResolver(); 13276 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13277 if (stickies == null) { 13278 return cur; 13279 } 13280 final ArrayList<Intent> list = stickies.get(action); 13281 if (list == null) { 13282 return cur; 13283 } 13284 int N = list.size(); 13285 for (int i=0; i<N; i++) { 13286 Intent intent = list.get(i); 13287 if (filter.match(resolver, intent, true, TAG) >= 0) { 13288 if (cur == null) { 13289 cur = new ArrayList<Intent>(); 13290 } 13291 cur.add(intent); 13292 } 13293 } 13294 return cur; 13295 } 13296 13297 boolean isPendingBroadcastProcessLocked(int pid) { 13298 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13299 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13300 } 13301 13302 void skipPendingBroadcastLocked(int pid) { 13303 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13304 for (BroadcastQueue queue : mBroadcastQueues) { 13305 queue.skipPendingBroadcastLocked(pid); 13306 } 13307 } 13308 13309 // The app just attached; send any pending broadcasts that it should receive 13310 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13311 boolean didSomething = false; 13312 for (BroadcastQueue queue : mBroadcastQueues) { 13313 didSomething |= queue.sendPendingBroadcastsLocked(app); 13314 } 13315 return didSomething; 13316 } 13317 13318 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13319 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13320 enforceNotIsolatedCaller("registerReceiver"); 13321 int callingUid; 13322 int callingPid; 13323 synchronized(this) { 13324 ProcessRecord callerApp = null; 13325 if (caller != null) { 13326 callerApp = getRecordForAppLocked(caller); 13327 if (callerApp == null) { 13328 throw new SecurityException( 13329 "Unable to find app for caller " + caller 13330 + " (pid=" + Binder.getCallingPid() 13331 + ") when registering receiver " + receiver); 13332 } 13333 if (callerApp.info.uid != Process.SYSTEM_UID && 13334 !callerApp.pkgList.containsKey(callerPackage) && 13335 !"android".equals(callerPackage)) { 13336 throw new SecurityException("Given caller package " + callerPackage 13337 + " is not running in process " + callerApp); 13338 } 13339 callingUid = callerApp.info.uid; 13340 callingPid = callerApp.pid; 13341 } else { 13342 callerPackage = null; 13343 callingUid = Binder.getCallingUid(); 13344 callingPid = Binder.getCallingPid(); 13345 } 13346 13347 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13348 true, true, "registerReceiver", callerPackage); 13349 13350 List allSticky = null; 13351 13352 // Look for any matching sticky broadcasts... 13353 Iterator actions = filter.actionsIterator(); 13354 if (actions != null) { 13355 while (actions.hasNext()) { 13356 String action = (String)actions.next(); 13357 allSticky = getStickiesLocked(action, filter, allSticky, 13358 UserHandle.USER_ALL); 13359 allSticky = getStickiesLocked(action, filter, allSticky, 13360 UserHandle.getUserId(callingUid)); 13361 } 13362 } else { 13363 allSticky = getStickiesLocked(null, filter, allSticky, 13364 UserHandle.USER_ALL); 13365 allSticky = getStickiesLocked(null, filter, allSticky, 13366 UserHandle.getUserId(callingUid)); 13367 } 13368 13369 // The first sticky in the list is returned directly back to 13370 // the client. 13371 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13372 13373 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13374 + ": " + sticky); 13375 13376 if (receiver == null) { 13377 return sticky; 13378 } 13379 13380 ReceiverList rl 13381 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13382 if (rl == null) { 13383 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13384 userId, receiver); 13385 if (rl.app != null) { 13386 rl.app.receivers.add(rl); 13387 } else { 13388 try { 13389 receiver.asBinder().linkToDeath(rl, 0); 13390 } catch (RemoteException e) { 13391 return sticky; 13392 } 13393 rl.linkedToDeath = true; 13394 } 13395 mRegisteredReceivers.put(receiver.asBinder(), rl); 13396 } else if (rl.uid != callingUid) { 13397 throw new IllegalArgumentException( 13398 "Receiver requested to register for uid " + callingUid 13399 + " was previously registered for uid " + rl.uid); 13400 } else if (rl.pid != callingPid) { 13401 throw new IllegalArgumentException( 13402 "Receiver requested to register for pid " + callingPid 13403 + " was previously registered for pid " + rl.pid); 13404 } else if (rl.userId != userId) { 13405 throw new IllegalArgumentException( 13406 "Receiver requested to register for user " + userId 13407 + " was previously registered for user " + rl.userId); 13408 } 13409 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13410 permission, callingUid, userId); 13411 rl.add(bf); 13412 if (!bf.debugCheck()) { 13413 Slog.w(TAG, "==> For Dynamic broadast"); 13414 } 13415 mReceiverResolver.addFilter(bf); 13416 13417 // Enqueue broadcasts for all existing stickies that match 13418 // this filter. 13419 if (allSticky != null) { 13420 ArrayList receivers = new ArrayList(); 13421 receivers.add(bf); 13422 13423 int N = allSticky.size(); 13424 for (int i=0; i<N; i++) { 13425 Intent intent = (Intent)allSticky.get(i); 13426 BroadcastQueue queue = broadcastQueueForIntent(intent); 13427 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13428 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13429 null, null, false, true, true, -1); 13430 queue.enqueueParallelBroadcastLocked(r); 13431 queue.scheduleBroadcastsLocked(); 13432 } 13433 } 13434 13435 return sticky; 13436 } 13437 } 13438 13439 public void unregisterReceiver(IIntentReceiver receiver) { 13440 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13441 13442 final long origId = Binder.clearCallingIdentity(); 13443 try { 13444 boolean doTrim = false; 13445 13446 synchronized(this) { 13447 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13448 if (rl != null) { 13449 if (rl.curBroadcast != null) { 13450 BroadcastRecord r = rl.curBroadcast; 13451 final boolean doNext = finishReceiverLocked( 13452 receiver.asBinder(), r.resultCode, r.resultData, 13453 r.resultExtras, r.resultAbort); 13454 if (doNext) { 13455 doTrim = true; 13456 r.queue.processNextBroadcast(false); 13457 } 13458 } 13459 13460 if (rl.app != null) { 13461 rl.app.receivers.remove(rl); 13462 } 13463 removeReceiverLocked(rl); 13464 if (rl.linkedToDeath) { 13465 rl.linkedToDeath = false; 13466 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13467 } 13468 } 13469 } 13470 13471 // If we actually concluded any broadcasts, we might now be able 13472 // to trim the recipients' apps from our working set 13473 if (doTrim) { 13474 trimApplications(); 13475 return; 13476 } 13477 13478 } finally { 13479 Binder.restoreCallingIdentity(origId); 13480 } 13481 } 13482 13483 void removeReceiverLocked(ReceiverList rl) { 13484 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13485 int N = rl.size(); 13486 for (int i=0; i<N; i++) { 13487 mReceiverResolver.removeFilter(rl.get(i)); 13488 } 13489 } 13490 13491 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13492 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13493 ProcessRecord r = mLruProcesses.get(i); 13494 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13495 try { 13496 r.thread.dispatchPackageBroadcast(cmd, packages); 13497 } catch (RemoteException ex) { 13498 } 13499 } 13500 } 13501 } 13502 13503 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13504 int[] users) { 13505 List<ResolveInfo> receivers = null; 13506 try { 13507 HashSet<ComponentName> singleUserReceivers = null; 13508 boolean scannedFirstReceivers = false; 13509 for (int user : users) { 13510 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13511 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13512 if (user != 0 && newReceivers != null) { 13513 // If this is not the primary user, we need to check for 13514 // any receivers that should be filtered out. 13515 for (int i=0; i<newReceivers.size(); i++) { 13516 ResolveInfo ri = newReceivers.get(i); 13517 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13518 newReceivers.remove(i); 13519 i--; 13520 } 13521 } 13522 } 13523 if (newReceivers != null && newReceivers.size() == 0) { 13524 newReceivers = null; 13525 } 13526 if (receivers == null) { 13527 receivers = newReceivers; 13528 } else if (newReceivers != null) { 13529 // We need to concatenate the additional receivers 13530 // found with what we have do far. This would be easy, 13531 // but we also need to de-dup any receivers that are 13532 // singleUser. 13533 if (!scannedFirstReceivers) { 13534 // Collect any single user receivers we had already retrieved. 13535 scannedFirstReceivers = true; 13536 for (int i=0; i<receivers.size(); i++) { 13537 ResolveInfo ri = receivers.get(i); 13538 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13539 ComponentName cn = new ComponentName( 13540 ri.activityInfo.packageName, ri.activityInfo.name); 13541 if (singleUserReceivers == null) { 13542 singleUserReceivers = new HashSet<ComponentName>(); 13543 } 13544 singleUserReceivers.add(cn); 13545 } 13546 } 13547 } 13548 // Add the new results to the existing results, tracking 13549 // and de-dupping single user receivers. 13550 for (int i=0; i<newReceivers.size(); i++) { 13551 ResolveInfo ri = newReceivers.get(i); 13552 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13553 ComponentName cn = new ComponentName( 13554 ri.activityInfo.packageName, ri.activityInfo.name); 13555 if (singleUserReceivers == null) { 13556 singleUserReceivers = new HashSet<ComponentName>(); 13557 } 13558 if (!singleUserReceivers.contains(cn)) { 13559 singleUserReceivers.add(cn); 13560 receivers.add(ri); 13561 } 13562 } else { 13563 receivers.add(ri); 13564 } 13565 } 13566 } 13567 } 13568 } catch (RemoteException ex) { 13569 // pm is in same process, this will never happen. 13570 } 13571 return receivers; 13572 } 13573 13574 private final int broadcastIntentLocked(ProcessRecord callerApp, 13575 String callerPackage, Intent intent, String resolvedType, 13576 IIntentReceiver resultTo, int resultCode, String resultData, 13577 Bundle map, String requiredPermission, int appOp, 13578 boolean ordered, boolean sticky, int callingPid, int callingUid, 13579 int userId) { 13580 intent = new Intent(intent); 13581 13582 // By default broadcasts do not go to stopped apps. 13583 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13584 13585 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13586 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13587 + " ordered=" + ordered + " userid=" + userId); 13588 if ((resultTo != null) && !ordered) { 13589 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13590 } 13591 13592 userId = handleIncomingUser(callingPid, callingUid, userId, 13593 true, false, "broadcast", callerPackage); 13594 13595 // Make sure that the user who is receiving this broadcast is started. 13596 // If not, we will just skip it. 13597 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13598 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13599 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13600 Slog.w(TAG, "Skipping broadcast of " + intent 13601 + ": user " + userId + " is stopped"); 13602 return ActivityManager.BROADCAST_SUCCESS; 13603 } 13604 } 13605 13606 /* 13607 * Prevent non-system code (defined here to be non-persistent 13608 * processes) from sending protected broadcasts. 13609 */ 13610 int callingAppId = UserHandle.getAppId(callingUid); 13611 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13612 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13613 callingUid == 0) { 13614 // Always okay. 13615 } else if (callerApp == null || !callerApp.persistent) { 13616 try { 13617 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13618 intent.getAction())) { 13619 String msg = "Permission Denial: not allowed to send broadcast " 13620 + intent.getAction() + " from pid=" 13621 + callingPid + ", uid=" + callingUid; 13622 Slog.w(TAG, msg); 13623 throw new SecurityException(msg); 13624 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13625 // Special case for compatibility: we don't want apps to send this, 13626 // but historically it has not been protected and apps may be using it 13627 // to poke their own app widget. So, instead of making it protected, 13628 // just limit it to the caller. 13629 if (callerApp == null) { 13630 String msg = "Permission Denial: not allowed to send broadcast " 13631 + intent.getAction() + " from unknown caller."; 13632 Slog.w(TAG, msg); 13633 throw new SecurityException(msg); 13634 } else if (intent.getComponent() != null) { 13635 // They are good enough to send to an explicit component... verify 13636 // it is being sent to the calling app. 13637 if (!intent.getComponent().getPackageName().equals( 13638 callerApp.info.packageName)) { 13639 String msg = "Permission Denial: not allowed to send broadcast " 13640 + intent.getAction() + " to " 13641 + intent.getComponent().getPackageName() + " from " 13642 + callerApp.info.packageName; 13643 Slog.w(TAG, msg); 13644 throw new SecurityException(msg); 13645 } 13646 } else { 13647 // Limit broadcast to their own package. 13648 intent.setPackage(callerApp.info.packageName); 13649 } 13650 } 13651 } catch (RemoteException e) { 13652 Slog.w(TAG, "Remote exception", e); 13653 return ActivityManager.BROADCAST_SUCCESS; 13654 } 13655 } 13656 13657 // Handle special intents: if this broadcast is from the package 13658 // manager about a package being removed, we need to remove all of 13659 // its activities from the history stack. 13660 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13661 intent.getAction()); 13662 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13663 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13664 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13665 || uidRemoved) { 13666 if (checkComponentPermission( 13667 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13668 callingPid, callingUid, -1, true) 13669 == PackageManager.PERMISSION_GRANTED) { 13670 if (uidRemoved) { 13671 final Bundle intentExtras = intent.getExtras(); 13672 final int uid = intentExtras != null 13673 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13674 if (uid >= 0) { 13675 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13676 synchronized (bs) { 13677 bs.removeUidStatsLocked(uid); 13678 } 13679 mAppOpsService.uidRemoved(uid); 13680 } 13681 } else { 13682 // If resources are unavailable just force stop all 13683 // those packages and flush the attribute cache as well. 13684 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13685 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13686 if (list != null && (list.length > 0)) { 13687 for (String pkg : list) { 13688 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13689 "storage unmount"); 13690 } 13691 sendPackageBroadcastLocked( 13692 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13693 } 13694 } else { 13695 Uri data = intent.getData(); 13696 String ssp; 13697 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13698 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13699 intent.getAction()); 13700 boolean fullUninstall = removed && 13701 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13702 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13703 forceStopPackageLocked(ssp, UserHandle.getAppId( 13704 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13705 false, fullUninstall, userId, 13706 removed ? "pkg removed" : "pkg changed"); 13707 } 13708 if (removed) { 13709 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13710 new String[] {ssp}, userId); 13711 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13712 mAppOpsService.packageRemoved( 13713 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13714 13715 // Remove all permissions granted from/to this package 13716 removeUriPermissionsForPackageLocked(ssp, userId, true); 13717 } 13718 } 13719 } 13720 } 13721 } 13722 } else { 13723 String msg = "Permission Denial: " + intent.getAction() 13724 + " broadcast from " + callerPackage + " (pid=" + callingPid 13725 + ", uid=" + callingUid + ")" 13726 + " requires " 13727 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13728 Slog.w(TAG, msg); 13729 throw new SecurityException(msg); 13730 } 13731 13732 // Special case for adding a package: by default turn on compatibility 13733 // mode. 13734 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13735 Uri data = intent.getData(); 13736 String ssp; 13737 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13738 mCompatModePackages.handlePackageAddedLocked(ssp, 13739 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13740 } 13741 } 13742 13743 /* 13744 * If this is the time zone changed action, queue up a message that will reset the timezone 13745 * of all currently running processes. This message will get queued up before the broadcast 13746 * happens. 13747 */ 13748 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13749 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13750 } 13751 13752 /* 13753 * If the user set the time, let all running processes know. 13754 */ 13755 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13756 final int is24Hour = intent.getBooleanExtra( 13757 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13758 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13759 } 13760 13761 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13762 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13763 } 13764 13765 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13766 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13767 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13768 } 13769 13770 // Add to the sticky list if requested. 13771 if (sticky) { 13772 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13773 callingPid, callingUid) 13774 != PackageManager.PERMISSION_GRANTED) { 13775 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13776 + callingPid + ", uid=" + callingUid 13777 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13778 Slog.w(TAG, msg); 13779 throw new SecurityException(msg); 13780 } 13781 if (requiredPermission != null) { 13782 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13783 + " and enforce permission " + requiredPermission); 13784 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13785 } 13786 if (intent.getComponent() != null) { 13787 throw new SecurityException( 13788 "Sticky broadcasts can't target a specific component"); 13789 } 13790 // We use userId directly here, since the "all" target is maintained 13791 // as a separate set of sticky broadcasts. 13792 if (userId != UserHandle.USER_ALL) { 13793 // But first, if this is not a broadcast to all users, then 13794 // make sure it doesn't conflict with an existing broadcast to 13795 // all users. 13796 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13797 UserHandle.USER_ALL); 13798 if (stickies != null) { 13799 ArrayList<Intent> list = stickies.get(intent.getAction()); 13800 if (list != null) { 13801 int N = list.size(); 13802 int i; 13803 for (i=0; i<N; i++) { 13804 if (intent.filterEquals(list.get(i))) { 13805 throw new IllegalArgumentException( 13806 "Sticky broadcast " + intent + " for user " 13807 + userId + " conflicts with existing global broadcast"); 13808 } 13809 } 13810 } 13811 } 13812 } 13813 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13814 if (stickies == null) { 13815 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13816 mStickyBroadcasts.put(userId, stickies); 13817 } 13818 ArrayList<Intent> list = stickies.get(intent.getAction()); 13819 if (list == null) { 13820 list = new ArrayList<Intent>(); 13821 stickies.put(intent.getAction(), list); 13822 } 13823 int N = list.size(); 13824 int i; 13825 for (i=0; i<N; i++) { 13826 if (intent.filterEquals(list.get(i))) { 13827 // This sticky already exists, replace it. 13828 list.set(i, new Intent(intent)); 13829 break; 13830 } 13831 } 13832 if (i >= N) { 13833 list.add(new Intent(intent)); 13834 } 13835 } 13836 13837 int[] users; 13838 if (userId == UserHandle.USER_ALL) { 13839 // Caller wants broadcast to go to all started users. 13840 users = mStartedUserArray; 13841 } else { 13842 // Caller wants broadcast to go to one specific user. 13843 users = new int[] {userId}; 13844 } 13845 13846 // Figure out who all will receive this broadcast. 13847 List receivers = null; 13848 List<BroadcastFilter> registeredReceivers = null; 13849 // Need to resolve the intent to interested receivers... 13850 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13851 == 0) { 13852 receivers = collectReceiverComponents(intent, resolvedType, users); 13853 } 13854 if (intent.getComponent() == null) { 13855 registeredReceivers = mReceiverResolver.queryIntent(intent, 13856 resolvedType, false, userId); 13857 } 13858 13859 final boolean replacePending = 13860 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13861 13862 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13863 + " replacePending=" + replacePending); 13864 13865 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13866 if (!ordered && NR > 0) { 13867 // If we are not serializing this broadcast, then send the 13868 // registered receivers separately so they don't wait for the 13869 // components to be launched. 13870 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13871 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13872 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13873 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13874 ordered, sticky, false, userId); 13875 if (DEBUG_BROADCAST) Slog.v( 13876 TAG, "Enqueueing parallel broadcast " + r); 13877 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13878 if (!replaced) { 13879 queue.enqueueParallelBroadcastLocked(r); 13880 queue.scheduleBroadcastsLocked(); 13881 } 13882 registeredReceivers = null; 13883 NR = 0; 13884 } 13885 13886 // Merge into one list. 13887 int ir = 0; 13888 if (receivers != null) { 13889 // A special case for PACKAGE_ADDED: do not allow the package 13890 // being added to see this broadcast. This prevents them from 13891 // using this as a back door to get run as soon as they are 13892 // installed. Maybe in the future we want to have a special install 13893 // broadcast or such for apps, but we'd like to deliberately make 13894 // this decision. 13895 String skipPackages[] = null; 13896 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13897 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13898 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13899 Uri data = intent.getData(); 13900 if (data != null) { 13901 String pkgName = data.getSchemeSpecificPart(); 13902 if (pkgName != null) { 13903 skipPackages = new String[] { pkgName }; 13904 } 13905 } 13906 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13907 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13908 } 13909 if (skipPackages != null && (skipPackages.length > 0)) { 13910 for (String skipPackage : skipPackages) { 13911 if (skipPackage != null) { 13912 int NT = receivers.size(); 13913 for (int it=0; it<NT; it++) { 13914 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13915 if (curt.activityInfo.packageName.equals(skipPackage)) { 13916 receivers.remove(it); 13917 it--; 13918 NT--; 13919 } 13920 } 13921 } 13922 } 13923 } 13924 13925 int NT = receivers != null ? receivers.size() : 0; 13926 int it = 0; 13927 ResolveInfo curt = null; 13928 BroadcastFilter curr = null; 13929 while (it < NT && ir < NR) { 13930 if (curt == null) { 13931 curt = (ResolveInfo)receivers.get(it); 13932 } 13933 if (curr == null) { 13934 curr = registeredReceivers.get(ir); 13935 } 13936 if (curr.getPriority() >= curt.priority) { 13937 // Insert this broadcast record into the final list. 13938 receivers.add(it, curr); 13939 ir++; 13940 curr = null; 13941 it++; 13942 NT++; 13943 } else { 13944 // Skip to the next ResolveInfo in the final list. 13945 it++; 13946 curt = null; 13947 } 13948 } 13949 } 13950 while (ir < NR) { 13951 if (receivers == null) { 13952 receivers = new ArrayList(); 13953 } 13954 receivers.add(registeredReceivers.get(ir)); 13955 ir++; 13956 } 13957 13958 if ((receivers != null && receivers.size() > 0) 13959 || resultTo != null) { 13960 BroadcastQueue queue = broadcastQueueForIntent(intent); 13961 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13962 callerPackage, callingPid, callingUid, resolvedType, 13963 requiredPermission, appOp, receivers, resultTo, resultCode, 13964 resultData, map, ordered, sticky, false, userId); 13965 if (DEBUG_BROADCAST) Slog.v( 13966 TAG, "Enqueueing ordered broadcast " + r 13967 + ": prev had " + queue.mOrderedBroadcasts.size()); 13968 if (DEBUG_BROADCAST) { 13969 int seq = r.intent.getIntExtra("seq", -1); 13970 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13971 } 13972 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13973 if (!replaced) { 13974 queue.enqueueOrderedBroadcastLocked(r); 13975 queue.scheduleBroadcastsLocked(); 13976 } 13977 } 13978 13979 return ActivityManager.BROADCAST_SUCCESS; 13980 } 13981 13982 final Intent verifyBroadcastLocked(Intent intent) { 13983 // Refuse possible leaked file descriptors 13984 if (intent != null && intent.hasFileDescriptors() == true) { 13985 throw new IllegalArgumentException("File descriptors passed in Intent"); 13986 } 13987 13988 int flags = intent.getFlags(); 13989 13990 if (!mProcessesReady) { 13991 // if the caller really truly claims to know what they're doing, go 13992 // ahead and allow the broadcast without launching any receivers 13993 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13994 intent = new Intent(intent); 13995 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13996 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13997 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13998 + " before boot completion"); 13999 throw new IllegalStateException("Cannot broadcast before boot completed"); 14000 } 14001 } 14002 14003 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14004 throw new IllegalArgumentException( 14005 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14006 } 14007 14008 return intent; 14009 } 14010 14011 public final int broadcastIntent(IApplicationThread caller, 14012 Intent intent, String resolvedType, IIntentReceiver resultTo, 14013 int resultCode, String resultData, Bundle map, 14014 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14015 enforceNotIsolatedCaller("broadcastIntent"); 14016 synchronized(this) { 14017 intent = verifyBroadcastLocked(intent); 14018 14019 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14020 final int callingPid = Binder.getCallingPid(); 14021 final int callingUid = Binder.getCallingUid(); 14022 final long origId = Binder.clearCallingIdentity(); 14023 int res = broadcastIntentLocked(callerApp, 14024 callerApp != null ? callerApp.info.packageName : null, 14025 intent, resolvedType, resultTo, 14026 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14027 callingPid, callingUid, userId); 14028 Binder.restoreCallingIdentity(origId); 14029 return res; 14030 } 14031 } 14032 14033 int broadcastIntentInPackage(String packageName, int uid, 14034 Intent intent, String resolvedType, IIntentReceiver resultTo, 14035 int resultCode, String resultData, Bundle map, 14036 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14037 synchronized(this) { 14038 intent = verifyBroadcastLocked(intent); 14039 14040 final long origId = Binder.clearCallingIdentity(); 14041 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14042 resultTo, resultCode, resultData, map, requiredPermission, 14043 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14044 Binder.restoreCallingIdentity(origId); 14045 return res; 14046 } 14047 } 14048 14049 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14050 // Refuse possible leaked file descriptors 14051 if (intent != null && intent.hasFileDescriptors() == true) { 14052 throw new IllegalArgumentException("File descriptors passed in Intent"); 14053 } 14054 14055 userId = handleIncomingUser(Binder.getCallingPid(), 14056 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14057 14058 synchronized(this) { 14059 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14060 != PackageManager.PERMISSION_GRANTED) { 14061 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14062 + Binder.getCallingPid() 14063 + ", uid=" + Binder.getCallingUid() 14064 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14065 Slog.w(TAG, msg); 14066 throw new SecurityException(msg); 14067 } 14068 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14069 if (stickies != null) { 14070 ArrayList<Intent> list = stickies.get(intent.getAction()); 14071 if (list != null) { 14072 int N = list.size(); 14073 int i; 14074 for (i=0; i<N; i++) { 14075 if (intent.filterEquals(list.get(i))) { 14076 list.remove(i); 14077 break; 14078 } 14079 } 14080 if (list.size() <= 0) { 14081 stickies.remove(intent.getAction()); 14082 } 14083 } 14084 if (stickies.size() <= 0) { 14085 mStickyBroadcasts.remove(userId); 14086 } 14087 } 14088 } 14089 } 14090 14091 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14092 String resultData, Bundle resultExtras, boolean resultAbort) { 14093 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14094 if (r == null) { 14095 Slog.w(TAG, "finishReceiver called but not found on queue"); 14096 return false; 14097 } 14098 14099 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14100 } 14101 14102 void backgroundServicesFinishedLocked(int userId) { 14103 for (BroadcastQueue queue : mBroadcastQueues) { 14104 queue.backgroundServicesFinishedLocked(userId); 14105 } 14106 } 14107 14108 public void finishReceiver(IBinder who, int resultCode, String resultData, 14109 Bundle resultExtras, boolean resultAbort) { 14110 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14111 14112 // Refuse possible leaked file descriptors 14113 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14114 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14115 } 14116 14117 final long origId = Binder.clearCallingIdentity(); 14118 try { 14119 boolean doNext = false; 14120 BroadcastRecord r; 14121 14122 synchronized(this) { 14123 r = broadcastRecordForReceiverLocked(who); 14124 if (r != null) { 14125 doNext = r.queue.finishReceiverLocked(r, resultCode, 14126 resultData, resultExtras, resultAbort, true); 14127 } 14128 } 14129 14130 if (doNext) { 14131 r.queue.processNextBroadcast(false); 14132 } 14133 trimApplications(); 14134 } finally { 14135 Binder.restoreCallingIdentity(origId); 14136 } 14137 } 14138 14139 // ========================================================= 14140 // INSTRUMENTATION 14141 // ========================================================= 14142 14143 public boolean startInstrumentation(ComponentName className, 14144 String profileFile, int flags, Bundle arguments, 14145 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14146 int userId) { 14147 enforceNotIsolatedCaller("startInstrumentation"); 14148 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14149 userId, false, true, "startInstrumentation", null); 14150 // Refuse possible leaked file descriptors 14151 if (arguments != null && arguments.hasFileDescriptors()) { 14152 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14153 } 14154 14155 synchronized(this) { 14156 InstrumentationInfo ii = null; 14157 ApplicationInfo ai = null; 14158 try { 14159 ii = mContext.getPackageManager().getInstrumentationInfo( 14160 className, STOCK_PM_FLAGS); 14161 ai = AppGlobals.getPackageManager().getApplicationInfo( 14162 ii.targetPackage, STOCK_PM_FLAGS, userId); 14163 } catch (PackageManager.NameNotFoundException e) { 14164 } catch (RemoteException e) { 14165 } 14166 if (ii == null) { 14167 reportStartInstrumentationFailure(watcher, className, 14168 "Unable to find instrumentation info for: " + className); 14169 return false; 14170 } 14171 if (ai == null) { 14172 reportStartInstrumentationFailure(watcher, className, 14173 "Unable to find instrumentation target package: " + ii.targetPackage); 14174 return false; 14175 } 14176 14177 int match = mContext.getPackageManager().checkSignatures( 14178 ii.targetPackage, ii.packageName); 14179 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14180 String msg = "Permission Denial: starting instrumentation " 14181 + className + " from pid=" 14182 + Binder.getCallingPid() 14183 + ", uid=" + Binder.getCallingPid() 14184 + " not allowed because package " + ii.packageName 14185 + " does not have a signature matching the target " 14186 + ii.targetPackage; 14187 reportStartInstrumentationFailure(watcher, className, msg); 14188 throw new SecurityException(msg); 14189 } 14190 14191 final long origId = Binder.clearCallingIdentity(); 14192 // Instrumentation can kill and relaunch even persistent processes 14193 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14194 "start instr"); 14195 ProcessRecord app = addAppLocked(ai, false); 14196 app.instrumentationClass = className; 14197 app.instrumentationInfo = ai; 14198 app.instrumentationProfileFile = profileFile; 14199 app.instrumentationArguments = arguments; 14200 app.instrumentationWatcher = watcher; 14201 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14202 app.instrumentationResultClass = className; 14203 Binder.restoreCallingIdentity(origId); 14204 } 14205 14206 return true; 14207 } 14208 14209 /** 14210 * Report errors that occur while attempting to start Instrumentation. Always writes the 14211 * error to the logs, but if somebody is watching, send the report there too. This enables 14212 * the "am" command to report errors with more information. 14213 * 14214 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14215 * @param cn The component name of the instrumentation. 14216 * @param report The error report. 14217 */ 14218 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14219 ComponentName cn, String report) { 14220 Slog.w(TAG, report); 14221 try { 14222 if (watcher != null) { 14223 Bundle results = new Bundle(); 14224 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14225 results.putString("Error", report); 14226 watcher.instrumentationStatus(cn, -1, results); 14227 } 14228 } catch (RemoteException e) { 14229 Slog.w(TAG, e); 14230 } 14231 } 14232 14233 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14234 if (app.instrumentationWatcher != null) { 14235 try { 14236 // NOTE: IInstrumentationWatcher *must* be oneway here 14237 app.instrumentationWatcher.instrumentationFinished( 14238 app.instrumentationClass, 14239 resultCode, 14240 results); 14241 } catch (RemoteException e) { 14242 } 14243 } 14244 if (app.instrumentationUiAutomationConnection != null) { 14245 try { 14246 app.instrumentationUiAutomationConnection.shutdown(); 14247 } catch (RemoteException re) { 14248 /* ignore */ 14249 } 14250 // Only a UiAutomation can set this flag and now that 14251 // it is finished we make sure it is reset to its default. 14252 mUserIsMonkey = false; 14253 } 14254 app.instrumentationWatcher = null; 14255 app.instrumentationUiAutomationConnection = null; 14256 app.instrumentationClass = null; 14257 app.instrumentationInfo = null; 14258 app.instrumentationProfileFile = null; 14259 app.instrumentationArguments = null; 14260 14261 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14262 "finished inst"); 14263 } 14264 14265 public void finishInstrumentation(IApplicationThread target, 14266 int resultCode, Bundle results) { 14267 int userId = UserHandle.getCallingUserId(); 14268 // Refuse possible leaked file descriptors 14269 if (results != null && results.hasFileDescriptors()) { 14270 throw new IllegalArgumentException("File descriptors passed in Intent"); 14271 } 14272 14273 synchronized(this) { 14274 ProcessRecord app = getRecordForAppLocked(target); 14275 if (app == null) { 14276 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14277 return; 14278 } 14279 final long origId = Binder.clearCallingIdentity(); 14280 finishInstrumentationLocked(app, resultCode, results); 14281 Binder.restoreCallingIdentity(origId); 14282 } 14283 } 14284 14285 // ========================================================= 14286 // CONFIGURATION 14287 // ========================================================= 14288 14289 public ConfigurationInfo getDeviceConfigurationInfo() { 14290 ConfigurationInfo config = new ConfigurationInfo(); 14291 synchronized (this) { 14292 config.reqTouchScreen = mConfiguration.touchscreen; 14293 config.reqKeyboardType = mConfiguration.keyboard; 14294 config.reqNavigation = mConfiguration.navigation; 14295 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14296 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14297 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14298 } 14299 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14300 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14301 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14302 } 14303 config.reqGlEsVersion = GL_ES_VERSION; 14304 } 14305 return config; 14306 } 14307 14308 ActivityStack getFocusedStack() { 14309 return mStackSupervisor.getFocusedStack(); 14310 } 14311 14312 public Configuration getConfiguration() { 14313 Configuration ci; 14314 synchronized(this) { 14315 ci = new Configuration(mConfiguration); 14316 } 14317 return ci; 14318 } 14319 14320 public void updatePersistentConfiguration(Configuration values) { 14321 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14322 "updateConfiguration()"); 14323 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14324 "updateConfiguration()"); 14325 if (values == null) { 14326 throw new NullPointerException("Configuration must not be null"); 14327 } 14328 14329 synchronized(this) { 14330 final long origId = Binder.clearCallingIdentity(); 14331 updateConfigurationLocked(values, null, true, false); 14332 Binder.restoreCallingIdentity(origId); 14333 } 14334 } 14335 14336 public void updateConfiguration(Configuration values) { 14337 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14338 "updateConfiguration()"); 14339 14340 synchronized(this) { 14341 if (values == null && mWindowManager != null) { 14342 // sentinel: fetch the current configuration from the window manager 14343 values = mWindowManager.computeNewConfiguration(); 14344 } 14345 14346 if (mWindowManager != null) { 14347 mProcessList.applyDisplaySize(mWindowManager); 14348 } 14349 14350 final long origId = Binder.clearCallingIdentity(); 14351 if (values != null) { 14352 Settings.System.clearConfiguration(values); 14353 } 14354 updateConfigurationLocked(values, null, false, false); 14355 Binder.restoreCallingIdentity(origId); 14356 } 14357 } 14358 14359 /** 14360 * Do either or both things: (1) change the current configuration, and (2) 14361 * make sure the given activity is running with the (now) current 14362 * configuration. Returns true if the activity has been left running, or 14363 * false if <var>starting</var> is being destroyed to match the new 14364 * configuration. 14365 * @param persistent TODO 14366 */ 14367 boolean updateConfigurationLocked(Configuration values, 14368 ActivityRecord starting, boolean persistent, boolean initLocale) { 14369 int changes = 0; 14370 14371 if (values != null) { 14372 Configuration newConfig = new Configuration(mConfiguration); 14373 changes = newConfig.updateFrom(values); 14374 if (changes != 0) { 14375 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14376 Slog.i(TAG, "Updating configuration to: " + values); 14377 } 14378 14379 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14380 14381 if (values.locale != null && !initLocale) { 14382 saveLocaleLocked(values.locale, 14383 !values.locale.equals(mConfiguration.locale), 14384 values.userSetLocale); 14385 } 14386 14387 mConfigurationSeq++; 14388 if (mConfigurationSeq <= 0) { 14389 mConfigurationSeq = 1; 14390 } 14391 newConfig.seq = mConfigurationSeq; 14392 mConfiguration = newConfig; 14393 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14394 14395 final Configuration configCopy = new Configuration(mConfiguration); 14396 14397 // TODO: If our config changes, should we auto dismiss any currently 14398 // showing dialogs? 14399 mShowDialogs = shouldShowDialogs(newConfig); 14400 14401 AttributeCache ac = AttributeCache.instance(); 14402 if (ac != null) { 14403 ac.updateConfiguration(configCopy); 14404 } 14405 14406 // Make sure all resources in our process are updated 14407 // right now, so that anyone who is going to retrieve 14408 // resource values after we return will be sure to get 14409 // the new ones. This is especially important during 14410 // boot, where the first config change needs to guarantee 14411 // all resources have that config before following boot 14412 // code is executed. 14413 mSystemThread.applyConfigurationToResources(configCopy); 14414 14415 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14416 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14417 msg.obj = new Configuration(configCopy); 14418 mHandler.sendMessage(msg); 14419 } 14420 14421 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14422 ProcessRecord app = mLruProcesses.get(i); 14423 try { 14424 if (app.thread != null) { 14425 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14426 + app.processName + " new config " + mConfiguration); 14427 app.thread.scheduleConfigurationChanged(configCopy); 14428 } 14429 } catch (Exception e) { 14430 } 14431 } 14432 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14433 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14434 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14435 | Intent.FLAG_RECEIVER_FOREGROUND); 14436 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14437 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14438 Process.SYSTEM_UID, UserHandle.USER_ALL); 14439 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14440 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14441 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14442 broadcastIntentLocked(null, null, intent, 14443 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14444 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14445 } 14446 } 14447 } 14448 14449 boolean kept = true; 14450 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14451 // mainStack is null during startup. 14452 if (mainStack != null) { 14453 if (changes != 0 && starting == null) { 14454 // If the configuration changed, and the caller is not already 14455 // in the process of starting an activity, then find the top 14456 // activity to check if its configuration needs to change. 14457 starting = mainStack.topRunningActivityLocked(null); 14458 } 14459 14460 if (starting != null) { 14461 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14462 // And we need to make sure at this point that all other activities 14463 // are made visible with the correct configuration. 14464 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14465 } 14466 } 14467 14468 if (values != null && mWindowManager != null) { 14469 mWindowManager.setNewConfiguration(mConfiguration); 14470 } 14471 14472 return kept; 14473 } 14474 14475 /** 14476 * Decide based on the configuration whether we should shouw the ANR, 14477 * crash, etc dialogs. The idea is that if there is no affordnace to 14478 * press the on-screen buttons, we shouldn't show the dialog. 14479 * 14480 * A thought: SystemUI might also want to get told about this, the Power 14481 * dialog / global actions also might want different behaviors. 14482 */ 14483 private static final boolean shouldShowDialogs(Configuration config) { 14484 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14485 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14486 } 14487 14488 /** 14489 * Save the locale. You must be inside a synchronized (this) block. 14490 */ 14491 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14492 if(isDiff) { 14493 SystemProperties.set("user.language", l.getLanguage()); 14494 SystemProperties.set("user.region", l.getCountry()); 14495 } 14496 14497 if(isPersist) { 14498 SystemProperties.set("persist.sys.language", l.getLanguage()); 14499 SystemProperties.set("persist.sys.country", l.getCountry()); 14500 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14501 } 14502 } 14503 14504 @Override 14505 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14506 ActivityRecord srec = ActivityRecord.forToken(token); 14507 return srec != null && srec.task.affinity != null && 14508 srec.task.affinity.equals(destAffinity); 14509 } 14510 14511 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14512 Intent resultData) { 14513 14514 synchronized (this) { 14515 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14516 if (stack != null) { 14517 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14518 } 14519 return false; 14520 } 14521 } 14522 14523 public int getLaunchedFromUid(IBinder activityToken) { 14524 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14525 if (srec == null) { 14526 return -1; 14527 } 14528 return srec.launchedFromUid; 14529 } 14530 14531 public String getLaunchedFromPackage(IBinder activityToken) { 14532 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14533 if (srec == null) { 14534 return null; 14535 } 14536 return srec.launchedFromPackage; 14537 } 14538 14539 // ========================================================= 14540 // LIFETIME MANAGEMENT 14541 // ========================================================= 14542 14543 // Returns which broadcast queue the app is the current [or imminent] receiver 14544 // on, or 'null' if the app is not an active broadcast recipient. 14545 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14546 BroadcastRecord r = app.curReceiver; 14547 if (r != null) { 14548 return r.queue; 14549 } 14550 14551 // It's not the current receiver, but it might be starting up to become one 14552 synchronized (this) { 14553 for (BroadcastQueue queue : mBroadcastQueues) { 14554 r = queue.mPendingBroadcast; 14555 if (r != null && r.curApp == app) { 14556 // found it; report which queue it's in 14557 return queue; 14558 } 14559 } 14560 } 14561 14562 return null; 14563 } 14564 14565 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14566 boolean doingAll, long now) { 14567 if (mAdjSeq == app.adjSeq) { 14568 // This adjustment has already been computed. 14569 return app.curRawAdj; 14570 } 14571 14572 if (app.thread == null) { 14573 app.adjSeq = mAdjSeq; 14574 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14575 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14576 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14577 } 14578 14579 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14580 app.adjSource = null; 14581 app.adjTarget = null; 14582 app.empty = false; 14583 app.cached = false; 14584 14585 final int activitiesSize = app.activities.size(); 14586 14587 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14588 // The max adjustment doesn't allow this app to be anything 14589 // below foreground, so it is not worth doing work for it. 14590 app.adjType = "fixed"; 14591 app.adjSeq = mAdjSeq; 14592 app.curRawAdj = app.maxAdj; 14593 app.foregroundActivities = false; 14594 app.keeping = true; 14595 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14596 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14597 // System processes can do UI, and when they do we want to have 14598 // them trim their memory after the user leaves the UI. To 14599 // facilitate this, here we need to determine whether or not it 14600 // is currently showing UI. 14601 app.systemNoUi = true; 14602 if (app == TOP_APP) { 14603 app.systemNoUi = false; 14604 } else if (activitiesSize > 0) { 14605 for (int j = 0; j < activitiesSize; j++) { 14606 final ActivityRecord r = app.activities.get(j); 14607 if (r.visible) { 14608 app.systemNoUi = false; 14609 } 14610 } 14611 } 14612 if (!app.systemNoUi) { 14613 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14614 } 14615 return (app.curAdj=app.maxAdj); 14616 } 14617 14618 app.keeping = false; 14619 app.systemNoUi = false; 14620 14621 // Determine the importance of the process, starting with most 14622 // important to least, and assign an appropriate OOM adjustment. 14623 int adj; 14624 int schedGroup; 14625 int procState; 14626 boolean foregroundActivities = false; 14627 boolean interesting = false; 14628 BroadcastQueue queue; 14629 if (app == TOP_APP) { 14630 // The last app on the list is the foreground app. 14631 adj = ProcessList.FOREGROUND_APP_ADJ; 14632 schedGroup = Process.THREAD_GROUP_DEFAULT; 14633 app.adjType = "top-activity"; 14634 foregroundActivities = true; 14635 interesting = true; 14636 procState = ActivityManager.PROCESS_STATE_TOP; 14637 } else if (app.instrumentationClass != null) { 14638 // Don't want to kill running instrumentation. 14639 adj = ProcessList.FOREGROUND_APP_ADJ; 14640 schedGroup = Process.THREAD_GROUP_DEFAULT; 14641 app.adjType = "instrumentation"; 14642 interesting = true; 14643 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14644 } else if ((queue = isReceivingBroadcast(app)) != null) { 14645 // An app that is currently receiving a broadcast also 14646 // counts as being in the foreground for OOM killer purposes. 14647 // It's placed in a sched group based on the nature of the 14648 // broadcast as reflected by which queue it's active in. 14649 adj = ProcessList.FOREGROUND_APP_ADJ; 14650 schedGroup = (queue == mFgBroadcastQueue) 14651 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14652 app.adjType = "broadcast"; 14653 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14654 } else if (app.executingServices.size() > 0) { 14655 // An app that is currently executing a service callback also 14656 // counts as being in the foreground. 14657 adj = ProcessList.FOREGROUND_APP_ADJ; 14658 schedGroup = app.execServicesFg ? 14659 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14660 app.adjType = "exec-service"; 14661 procState = ActivityManager.PROCESS_STATE_SERVICE; 14662 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14663 } else { 14664 // As far as we know the process is empty. We may change our mind later. 14665 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14666 // At this point we don't actually know the adjustment. Use the cached adj 14667 // value that the caller wants us to. 14668 adj = cachedAdj; 14669 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14670 app.cached = true; 14671 app.empty = true; 14672 app.adjType = "cch-empty"; 14673 } 14674 14675 // Examine all activities if not already foreground. 14676 if (!foregroundActivities && activitiesSize > 0) { 14677 for (int j = 0; j < activitiesSize; j++) { 14678 final ActivityRecord r = app.activities.get(j); 14679 if (r.app != app) { 14680 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14681 + app + "?!?"); 14682 continue; 14683 } 14684 if (r.visible) { 14685 // App has a visible activity; only upgrade adjustment. 14686 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14687 adj = ProcessList.VISIBLE_APP_ADJ; 14688 app.adjType = "visible"; 14689 } 14690 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14691 procState = ActivityManager.PROCESS_STATE_TOP; 14692 } 14693 schedGroup = Process.THREAD_GROUP_DEFAULT; 14694 app.cached = false; 14695 app.empty = false; 14696 foregroundActivities = true; 14697 break; 14698 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14699 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14700 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14701 app.adjType = "pausing"; 14702 } 14703 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14704 procState = ActivityManager.PROCESS_STATE_TOP; 14705 } 14706 schedGroup = Process.THREAD_GROUP_DEFAULT; 14707 app.cached = false; 14708 app.empty = false; 14709 foregroundActivities = true; 14710 } else if (r.state == ActivityState.STOPPING) { 14711 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14712 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14713 app.adjType = "stopping"; 14714 } 14715 // For the process state, we will at this point consider the 14716 // process to be cached. It will be cached either as an activity 14717 // or empty depending on whether the activity is finishing. We do 14718 // this so that we can treat the process as cached for purposes of 14719 // memory trimming (determing current memory level, trim command to 14720 // send to process) since there can be an arbitrary number of stopping 14721 // processes and they should soon all go into the cached state. 14722 if (!r.finishing) { 14723 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14724 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14725 } 14726 } 14727 app.cached = false; 14728 app.empty = false; 14729 foregroundActivities = true; 14730 } else { 14731 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14732 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14733 app.adjType = "cch-act"; 14734 } 14735 } 14736 } 14737 } 14738 14739 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14740 if (app.foregroundServices) { 14741 // The user is aware of this app, so make it visible. 14742 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14743 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14744 app.cached = false; 14745 app.adjType = "fg-service"; 14746 schedGroup = Process.THREAD_GROUP_DEFAULT; 14747 } else if (app.forcingToForeground != null) { 14748 // The user is aware of this app, so make it visible. 14749 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14750 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14751 app.cached = false; 14752 app.adjType = "force-fg"; 14753 app.adjSource = app.forcingToForeground; 14754 schedGroup = Process.THREAD_GROUP_DEFAULT; 14755 } 14756 } 14757 14758 if (app.foregroundServices) { 14759 interesting = true; 14760 } 14761 14762 if (app == mHeavyWeightProcess) { 14763 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14764 // We don't want to kill the current heavy-weight process. 14765 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14766 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14767 app.cached = false; 14768 app.adjType = "heavy"; 14769 } 14770 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14771 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14772 } 14773 } 14774 14775 if (app == mHomeProcess) { 14776 if (adj > ProcessList.HOME_APP_ADJ) { 14777 // This process is hosting what we currently consider to be the 14778 // home app, so we don't want to let it go into the background. 14779 adj = ProcessList.HOME_APP_ADJ; 14780 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14781 app.cached = false; 14782 app.adjType = "home"; 14783 } 14784 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14785 procState = ActivityManager.PROCESS_STATE_HOME; 14786 } 14787 } 14788 14789 if (app == mPreviousProcess && app.activities.size() > 0) { 14790 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14791 // This was the previous process that showed UI to the user. 14792 // We want to try to keep it around more aggressively, to give 14793 // a good experience around switching between two apps. 14794 adj = ProcessList.PREVIOUS_APP_ADJ; 14795 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14796 app.cached = false; 14797 app.adjType = "previous"; 14798 } 14799 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14800 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14801 } 14802 } 14803 14804 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14805 + " reason=" + app.adjType); 14806 14807 // By default, we use the computed adjustment. It may be changed if 14808 // there are applications dependent on our services or providers, but 14809 // this gives us a baseline and makes sure we don't get into an 14810 // infinite recursion. 14811 app.adjSeq = mAdjSeq; 14812 app.curRawAdj = adj; 14813 app.hasStartedServices = false; 14814 14815 if (mBackupTarget != null && app == mBackupTarget.app) { 14816 // If possible we want to avoid killing apps while they're being backed up 14817 if (adj > ProcessList.BACKUP_APP_ADJ) { 14818 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14819 adj = ProcessList.BACKUP_APP_ADJ; 14820 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14821 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14822 } 14823 app.adjType = "backup"; 14824 app.cached = false; 14825 } 14826 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14827 procState = ActivityManager.PROCESS_STATE_BACKUP; 14828 } 14829 } 14830 14831 boolean mayBeTop = false; 14832 14833 for (int is = app.services.size()-1; 14834 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14835 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14836 || procState > ActivityManager.PROCESS_STATE_TOP); 14837 is--) { 14838 ServiceRecord s = app.services.valueAt(is); 14839 if (s.startRequested) { 14840 app.hasStartedServices = true; 14841 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14842 procState = ActivityManager.PROCESS_STATE_SERVICE; 14843 } 14844 if (app.hasShownUi && app != mHomeProcess) { 14845 // If this process has shown some UI, let it immediately 14846 // go to the LRU list because it may be pretty heavy with 14847 // UI stuff. We'll tag it with a label just to help 14848 // debug and understand what is going on. 14849 if (adj > ProcessList.SERVICE_ADJ) { 14850 app.adjType = "cch-started-ui-services"; 14851 } 14852 } else { 14853 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14854 // This service has seen some activity within 14855 // recent memory, so we will keep its process ahead 14856 // of the background processes. 14857 if (adj > ProcessList.SERVICE_ADJ) { 14858 adj = ProcessList.SERVICE_ADJ; 14859 app.adjType = "started-services"; 14860 app.cached = false; 14861 } 14862 } 14863 // If we have let the service slide into the background 14864 // state, still have some text describing what it is doing 14865 // even though the service no longer has an impact. 14866 if (adj > ProcessList.SERVICE_ADJ) { 14867 app.adjType = "cch-started-services"; 14868 } 14869 } 14870 // Don't kill this process because it is doing work; it 14871 // has said it is doing work. 14872 app.keeping = true; 14873 } 14874 for (int conni = s.connections.size()-1; 14875 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14876 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14877 || procState > ActivityManager.PROCESS_STATE_TOP); 14878 conni--) { 14879 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14880 for (int i = 0; 14881 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14882 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14883 || procState > ActivityManager.PROCESS_STATE_TOP); 14884 i++) { 14885 // XXX should compute this based on the max of 14886 // all connected clients. 14887 ConnectionRecord cr = clist.get(i); 14888 if (cr.binding.client == app) { 14889 // Binding to ourself is not interesting. 14890 continue; 14891 } 14892 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14893 ProcessRecord client = cr.binding.client; 14894 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14895 TOP_APP, doingAll, now); 14896 int clientProcState = client.curProcState; 14897 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14898 // If the other app is cached for any reason, for purposes here 14899 // we are going to consider it empty. The specific cached state 14900 // doesn't propagate except under certain conditions. 14901 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14902 } 14903 String adjType = null; 14904 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14905 // Not doing bind OOM management, so treat 14906 // this guy more like a started service. 14907 if (app.hasShownUi && app != mHomeProcess) { 14908 // If this process has shown some UI, let it immediately 14909 // go to the LRU list because it may be pretty heavy with 14910 // UI stuff. We'll tag it with a label just to help 14911 // debug and understand what is going on. 14912 if (adj > clientAdj) { 14913 adjType = "cch-bound-ui-services"; 14914 } 14915 app.cached = false; 14916 clientAdj = adj; 14917 clientProcState = procState; 14918 } else { 14919 if (now >= (s.lastActivity 14920 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14921 // This service has not seen activity within 14922 // recent memory, so allow it to drop to the 14923 // LRU list if there is no other reason to keep 14924 // it around. We'll also tag it with a label just 14925 // to help debug and undertand what is going on. 14926 if (adj > clientAdj) { 14927 adjType = "cch-bound-services"; 14928 } 14929 clientAdj = adj; 14930 } 14931 } 14932 } 14933 if (adj > clientAdj) { 14934 // If this process has recently shown UI, and 14935 // the process that is binding to it is less 14936 // important than being visible, then we don't 14937 // care about the binding as much as we care 14938 // about letting this process get into the LRU 14939 // list to be killed and restarted if needed for 14940 // memory. 14941 if (app.hasShownUi && app != mHomeProcess 14942 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14943 adjType = "cch-bound-ui-services"; 14944 } else { 14945 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14946 |Context.BIND_IMPORTANT)) != 0) { 14947 adj = clientAdj; 14948 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14949 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14950 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14951 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14952 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14953 adj = clientAdj; 14954 } else { 14955 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14956 adj = ProcessList.VISIBLE_APP_ADJ; 14957 } 14958 } 14959 if (!client.cached) { 14960 app.cached = false; 14961 } 14962 if (client.keeping) { 14963 app.keeping = true; 14964 } 14965 adjType = "service"; 14966 } 14967 } 14968 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14969 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14970 schedGroup = Process.THREAD_GROUP_DEFAULT; 14971 } 14972 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14973 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14974 // Special handling of clients who are in the top state. 14975 // We *may* want to consider this process to be in the 14976 // top state as well, but only if there is not another 14977 // reason for it to be running. Being on the top is a 14978 // special state, meaning you are specifically running 14979 // for the current top app. If the process is already 14980 // running in the background for some other reason, it 14981 // is more important to continue considering it to be 14982 // in the background state. 14983 mayBeTop = true; 14984 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14985 } else { 14986 // Special handling for above-top states (persistent 14987 // processes). These should not bring the current process 14988 // into the top state, since they are not on top. Instead 14989 // give them the best state after that. 14990 clientProcState = 14991 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14992 } 14993 } 14994 } else { 14995 if (clientProcState < 14996 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14997 clientProcState = 14998 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14999 } 15000 } 15001 if (procState > clientProcState) { 15002 procState = clientProcState; 15003 } 15004 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15005 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15006 app.pendingUiClean = true; 15007 } 15008 if (adjType != null) { 15009 app.adjType = adjType; 15010 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15011 .REASON_SERVICE_IN_USE; 15012 app.adjSource = cr.binding.client; 15013 app.adjSourceOom = clientAdj; 15014 app.adjTarget = s.name; 15015 } 15016 } 15017 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15018 app.treatLikeActivity = true; 15019 } 15020 final ActivityRecord a = cr.activity; 15021 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15022 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15023 (a.visible || a.state == ActivityState.RESUMED 15024 || a.state == ActivityState.PAUSING)) { 15025 adj = ProcessList.FOREGROUND_APP_ADJ; 15026 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15027 schedGroup = Process.THREAD_GROUP_DEFAULT; 15028 } 15029 app.cached = false; 15030 app.adjType = "service"; 15031 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15032 .REASON_SERVICE_IN_USE; 15033 app.adjSource = a; 15034 app.adjSourceOom = adj; 15035 app.adjTarget = s.name; 15036 } 15037 } 15038 } 15039 } 15040 } 15041 15042 for (int provi = app.pubProviders.size()-1; 15043 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15044 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15045 || procState > ActivityManager.PROCESS_STATE_TOP); 15046 provi--) { 15047 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15048 for (int i = cpr.connections.size()-1; 15049 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15050 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15051 || procState > ActivityManager.PROCESS_STATE_TOP); 15052 i--) { 15053 ContentProviderConnection conn = cpr.connections.get(i); 15054 ProcessRecord client = conn.client; 15055 if (client == app) { 15056 // Being our own client is not interesting. 15057 continue; 15058 } 15059 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15060 int clientProcState = client.curProcState; 15061 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15062 // If the other app is cached for any reason, for purposes here 15063 // we are going to consider it empty. 15064 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15065 } 15066 if (adj > clientAdj) { 15067 if (app.hasShownUi && app != mHomeProcess 15068 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15069 app.adjType = "cch-ui-provider"; 15070 } else { 15071 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15072 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15073 app.adjType = "provider"; 15074 } 15075 app.cached &= client.cached; 15076 app.keeping |= client.keeping; 15077 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15078 .REASON_PROVIDER_IN_USE; 15079 app.adjSource = client; 15080 app.adjSourceOom = clientAdj; 15081 app.adjTarget = cpr.name; 15082 } 15083 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15084 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15085 // Special handling of clients who are in the top state. 15086 // We *may* want to consider this process to be in the 15087 // top state as well, but only if there is not another 15088 // reason for it to be running. Being on the top is a 15089 // special state, meaning you are specifically running 15090 // for the current top app. If the process is already 15091 // running in the background for some other reason, it 15092 // is more important to continue considering it to be 15093 // in the background state. 15094 mayBeTop = true; 15095 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15096 } else { 15097 // Special handling for above-top states (persistent 15098 // processes). These should not bring the current process 15099 // into the top state, since they are not on top. Instead 15100 // give them the best state after that. 15101 clientProcState = 15102 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15103 } 15104 } 15105 if (procState > clientProcState) { 15106 procState = clientProcState; 15107 } 15108 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15109 schedGroup = Process.THREAD_GROUP_DEFAULT; 15110 } 15111 } 15112 // If the provider has external (non-framework) process 15113 // dependencies, ensure that its adjustment is at least 15114 // FOREGROUND_APP_ADJ. 15115 if (cpr.hasExternalProcessHandles()) { 15116 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15117 adj = ProcessList.FOREGROUND_APP_ADJ; 15118 schedGroup = Process.THREAD_GROUP_DEFAULT; 15119 app.cached = false; 15120 app.keeping = true; 15121 app.adjType = "provider"; 15122 app.adjTarget = cpr.name; 15123 } 15124 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15125 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15126 } 15127 } 15128 } 15129 15130 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15131 // A client of one of our services or providers is in the top state. We 15132 // *may* want to be in the top state, but not if we are already running in 15133 // the background for some other reason. For the decision here, we are going 15134 // to pick out a few specific states that we want to remain in when a client 15135 // is top (states that tend to be longer-term) and otherwise allow it to go 15136 // to the top state. 15137 switch (procState) { 15138 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15139 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15140 case ActivityManager.PROCESS_STATE_SERVICE: 15141 // These all are longer-term states, so pull them up to the top 15142 // of the background states, but not all the way to the top state. 15143 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15144 break; 15145 default: 15146 // Otherwise, top is a better choice, so take it. 15147 procState = ActivityManager.PROCESS_STATE_TOP; 15148 break; 15149 } 15150 } 15151 15152 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15153 if (app.hasClientActivities) { 15154 // This is a cached process, but with client activities. Mark it so. 15155 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15156 app.adjType = "cch-client-act"; 15157 } else if (app.treatLikeActivity) { 15158 // This is a cached process, but somebody wants us to treat it like it has 15159 // an activity, okay! 15160 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15161 app.adjType = "cch-as-act"; 15162 } 15163 } 15164 15165 if (adj == ProcessList.SERVICE_ADJ) { 15166 if (doingAll) { 15167 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15168 mNewNumServiceProcs++; 15169 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15170 if (!app.serviceb) { 15171 // This service isn't far enough down on the LRU list to 15172 // normally be a B service, but if we are low on RAM and it 15173 // is large we want to force it down since we would prefer to 15174 // keep launcher over it. 15175 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15176 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15177 app.serviceHighRam = true; 15178 app.serviceb = true; 15179 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15180 } else { 15181 mNewNumAServiceProcs++; 15182 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15183 } 15184 } else { 15185 app.serviceHighRam = false; 15186 } 15187 } 15188 if (app.serviceb) { 15189 adj = ProcessList.SERVICE_B_ADJ; 15190 } 15191 } 15192 15193 app.curRawAdj = adj; 15194 15195 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15196 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15197 if (adj > app.maxAdj) { 15198 adj = app.maxAdj; 15199 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15200 schedGroup = Process.THREAD_GROUP_DEFAULT; 15201 } 15202 } 15203 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15204 app.keeping = true; 15205 } 15206 15207 // Do final modification to adj. Everything we do between here and applying 15208 // the final setAdj must be done in this function, because we will also use 15209 // it when computing the final cached adj later. Note that we don't need to 15210 // worry about this for max adj above, since max adj will always be used to 15211 // keep it out of the cached vaues. 15212 app.curAdj = app.modifyRawOomAdj(adj); 15213 app.curSchedGroup = schedGroup; 15214 app.curProcState = procState; 15215 app.foregroundActivities = foregroundActivities; 15216 15217 return app.curRawAdj; 15218 } 15219 15220 /** 15221 * Schedule PSS collection of a process. 15222 */ 15223 void requestPssLocked(ProcessRecord proc, int procState) { 15224 if (mPendingPssProcesses.contains(proc)) { 15225 return; 15226 } 15227 if (mPendingPssProcesses.size() == 0) { 15228 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15229 } 15230 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15231 proc.pssProcState = procState; 15232 mPendingPssProcesses.add(proc); 15233 } 15234 15235 /** 15236 * Schedule PSS collection of all processes. 15237 */ 15238 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15239 if (!always) { 15240 if (now < (mLastFullPssTime + 15241 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15242 return; 15243 } 15244 } 15245 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15246 mLastFullPssTime = now; 15247 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15248 mPendingPssProcesses.clear(); 15249 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15250 ProcessRecord app = mLruProcesses.get(i); 15251 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15252 app.pssProcState = app.setProcState; 15253 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15254 isSleeping(), now); 15255 mPendingPssProcesses.add(app); 15256 } 15257 } 15258 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15259 } 15260 15261 /** 15262 * Ask a given process to GC right now. 15263 */ 15264 final void performAppGcLocked(ProcessRecord app) { 15265 try { 15266 app.lastRequestedGc = SystemClock.uptimeMillis(); 15267 if (app.thread != null) { 15268 if (app.reportLowMemory) { 15269 app.reportLowMemory = false; 15270 app.thread.scheduleLowMemory(); 15271 } else { 15272 app.thread.processInBackground(); 15273 } 15274 } 15275 } catch (Exception e) { 15276 // whatever. 15277 } 15278 } 15279 15280 /** 15281 * Returns true if things are idle enough to perform GCs. 15282 */ 15283 private final boolean canGcNowLocked() { 15284 boolean processingBroadcasts = false; 15285 for (BroadcastQueue q : mBroadcastQueues) { 15286 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15287 processingBroadcasts = true; 15288 } 15289 } 15290 return !processingBroadcasts 15291 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15292 } 15293 15294 /** 15295 * Perform GCs on all processes that are waiting for it, but only 15296 * if things are idle. 15297 */ 15298 final void performAppGcsLocked() { 15299 final int N = mProcessesToGc.size(); 15300 if (N <= 0) { 15301 return; 15302 } 15303 if (canGcNowLocked()) { 15304 while (mProcessesToGc.size() > 0) { 15305 ProcessRecord proc = mProcessesToGc.remove(0); 15306 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15307 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15308 <= SystemClock.uptimeMillis()) { 15309 // To avoid spamming the system, we will GC processes one 15310 // at a time, waiting a few seconds between each. 15311 performAppGcLocked(proc); 15312 scheduleAppGcsLocked(); 15313 return; 15314 } else { 15315 // It hasn't been long enough since we last GCed this 15316 // process... put it in the list to wait for its time. 15317 addProcessToGcListLocked(proc); 15318 break; 15319 } 15320 } 15321 } 15322 15323 scheduleAppGcsLocked(); 15324 } 15325 } 15326 15327 /** 15328 * If all looks good, perform GCs on all processes waiting for them. 15329 */ 15330 final void performAppGcsIfAppropriateLocked() { 15331 if (canGcNowLocked()) { 15332 performAppGcsLocked(); 15333 return; 15334 } 15335 // Still not idle, wait some more. 15336 scheduleAppGcsLocked(); 15337 } 15338 15339 /** 15340 * Schedule the execution of all pending app GCs. 15341 */ 15342 final void scheduleAppGcsLocked() { 15343 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15344 15345 if (mProcessesToGc.size() > 0) { 15346 // Schedule a GC for the time to the next process. 15347 ProcessRecord proc = mProcessesToGc.get(0); 15348 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15349 15350 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15351 long now = SystemClock.uptimeMillis(); 15352 if (when < (now+GC_TIMEOUT)) { 15353 when = now + GC_TIMEOUT; 15354 } 15355 mHandler.sendMessageAtTime(msg, when); 15356 } 15357 } 15358 15359 /** 15360 * Add a process to the array of processes waiting to be GCed. Keeps the 15361 * list in sorted order by the last GC time. The process can't already be 15362 * on the list. 15363 */ 15364 final void addProcessToGcListLocked(ProcessRecord proc) { 15365 boolean added = false; 15366 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15367 if (mProcessesToGc.get(i).lastRequestedGc < 15368 proc.lastRequestedGc) { 15369 added = true; 15370 mProcessesToGc.add(i+1, proc); 15371 break; 15372 } 15373 } 15374 if (!added) { 15375 mProcessesToGc.add(0, proc); 15376 } 15377 } 15378 15379 /** 15380 * Set up to ask a process to GC itself. This will either do it 15381 * immediately, or put it on the list of processes to gc the next 15382 * time things are idle. 15383 */ 15384 final void scheduleAppGcLocked(ProcessRecord app) { 15385 long now = SystemClock.uptimeMillis(); 15386 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15387 return; 15388 } 15389 if (!mProcessesToGc.contains(app)) { 15390 addProcessToGcListLocked(app); 15391 scheduleAppGcsLocked(); 15392 } 15393 } 15394 15395 final void checkExcessivePowerUsageLocked(boolean doKills) { 15396 updateCpuStatsNow(); 15397 15398 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15399 boolean doWakeKills = doKills; 15400 boolean doCpuKills = doKills; 15401 if (mLastPowerCheckRealtime == 0) { 15402 doWakeKills = false; 15403 } 15404 if (mLastPowerCheckUptime == 0) { 15405 doCpuKills = false; 15406 } 15407 if (stats.isScreenOn()) { 15408 doWakeKills = false; 15409 } 15410 final long curRealtime = SystemClock.elapsedRealtime(); 15411 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15412 final long curUptime = SystemClock.uptimeMillis(); 15413 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15414 mLastPowerCheckRealtime = curRealtime; 15415 mLastPowerCheckUptime = curUptime; 15416 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15417 doWakeKills = false; 15418 } 15419 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15420 doCpuKills = false; 15421 } 15422 int i = mLruProcesses.size(); 15423 while (i > 0) { 15424 i--; 15425 ProcessRecord app = mLruProcesses.get(i); 15426 if (!app.keeping) { 15427 long wtime; 15428 synchronized (stats) { 15429 wtime = stats.getProcessWakeTime(app.info.uid, 15430 app.pid, curRealtime); 15431 } 15432 long wtimeUsed = wtime - app.lastWakeTime; 15433 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15434 if (DEBUG_POWER) { 15435 StringBuilder sb = new StringBuilder(128); 15436 sb.append("Wake for "); 15437 app.toShortString(sb); 15438 sb.append(": over "); 15439 TimeUtils.formatDuration(realtimeSince, sb); 15440 sb.append(" used "); 15441 TimeUtils.formatDuration(wtimeUsed, sb); 15442 sb.append(" ("); 15443 sb.append((wtimeUsed*100)/realtimeSince); 15444 sb.append("%)"); 15445 Slog.i(TAG, sb.toString()); 15446 sb.setLength(0); 15447 sb.append("CPU for "); 15448 app.toShortString(sb); 15449 sb.append(": over "); 15450 TimeUtils.formatDuration(uptimeSince, sb); 15451 sb.append(" used "); 15452 TimeUtils.formatDuration(cputimeUsed, sb); 15453 sb.append(" ("); 15454 sb.append((cputimeUsed*100)/uptimeSince); 15455 sb.append("%)"); 15456 Slog.i(TAG, sb.toString()); 15457 } 15458 // If a process has held a wake lock for more 15459 // than 50% of the time during this period, 15460 // that sounds bad. Kill! 15461 if (doWakeKills && realtimeSince > 0 15462 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15463 synchronized (stats) { 15464 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15465 realtimeSince, wtimeUsed); 15466 } 15467 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15468 + " during " + realtimeSince); 15469 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15470 } else if (doCpuKills && uptimeSince > 0 15471 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15472 synchronized (stats) { 15473 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15474 uptimeSince, cputimeUsed); 15475 } 15476 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15477 + " during " + uptimeSince); 15478 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15479 } else { 15480 app.lastWakeTime = wtime; 15481 app.lastCpuTime = app.curCpuTime; 15482 } 15483 } 15484 } 15485 } 15486 15487 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15488 ProcessRecord TOP_APP, boolean doingAll, long now) { 15489 boolean success = true; 15490 15491 if (app.curRawAdj != app.setRawAdj) { 15492 if (wasKeeping && !app.keeping) { 15493 // This app is no longer something we want to keep. Note 15494 // its current wake lock time to later know to kill it if 15495 // it is not behaving well. 15496 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15497 synchronized (stats) { 15498 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15499 app.pid, SystemClock.elapsedRealtime()); 15500 } 15501 app.lastCpuTime = app.curCpuTime; 15502 } 15503 15504 app.setRawAdj = app.curRawAdj; 15505 } 15506 15507 int changes = 0; 15508 15509 if (app.curAdj != app.setAdj) { 15510 ProcessList.setOomAdj(app.pid, app.curAdj); 15511 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15512 TAG, "Set " + app.pid + " " + app.processName + 15513 " adj " + app.curAdj + ": " + app.adjType); 15514 app.setAdj = app.curAdj; 15515 } 15516 15517 if (app.setSchedGroup != app.curSchedGroup) { 15518 app.setSchedGroup = app.curSchedGroup; 15519 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15520 "Setting process group of " + app.processName 15521 + " to " + app.curSchedGroup); 15522 if (app.waitingToKill != null && 15523 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15524 killUnneededProcessLocked(app, app.waitingToKill); 15525 success = false; 15526 } else { 15527 if (true) { 15528 long oldId = Binder.clearCallingIdentity(); 15529 try { 15530 Process.setProcessGroup(app.pid, app.curSchedGroup); 15531 } catch (Exception e) { 15532 Slog.w(TAG, "Failed setting process group of " + app.pid 15533 + " to " + app.curSchedGroup); 15534 e.printStackTrace(); 15535 } finally { 15536 Binder.restoreCallingIdentity(oldId); 15537 } 15538 } else { 15539 if (app.thread != null) { 15540 try { 15541 app.thread.setSchedulingGroup(app.curSchedGroup); 15542 } catch (RemoteException e) { 15543 } 15544 } 15545 } 15546 Process.setSwappiness(app.pid, 15547 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15548 } 15549 } 15550 if (app.repForegroundActivities != app.foregroundActivities) { 15551 app.repForegroundActivities = app.foregroundActivities; 15552 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15553 } 15554 if (app.repProcState != app.curProcState) { 15555 app.repProcState = app.curProcState; 15556 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15557 if (app.thread != null) { 15558 try { 15559 if (false) { 15560 //RuntimeException h = new RuntimeException("here"); 15561 Slog.i(TAG, "Sending new process state " + app.repProcState 15562 + " to " + app /*, h*/); 15563 } 15564 app.thread.setProcessState(app.repProcState); 15565 } catch (RemoteException e) { 15566 } 15567 } 15568 } 15569 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15570 app.setProcState)) { 15571 app.lastStateTime = now; 15572 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15573 isSleeping(), now); 15574 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15575 + ProcessList.makeProcStateString(app.setProcState) + " to " 15576 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15577 + (app.nextPssTime-now) + ": " + app); 15578 } else { 15579 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15580 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15581 requestPssLocked(app, app.setProcState); 15582 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15583 isSleeping(), now); 15584 } else if (false && DEBUG_PSS) { 15585 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15586 } 15587 } 15588 if (app.setProcState != app.curProcState) { 15589 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15590 "Proc state change of " + app.processName 15591 + " to " + app.curProcState); 15592 app.setProcState = app.curProcState; 15593 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15594 app.notCachedSinceIdle = false; 15595 } 15596 if (!doingAll) { 15597 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15598 } else { 15599 app.procStateChanged = true; 15600 } 15601 } 15602 15603 if (changes != 0) { 15604 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15605 int i = mPendingProcessChanges.size()-1; 15606 ProcessChangeItem item = null; 15607 while (i >= 0) { 15608 item = mPendingProcessChanges.get(i); 15609 if (item.pid == app.pid) { 15610 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15611 break; 15612 } 15613 i--; 15614 } 15615 if (i < 0) { 15616 // No existing item in pending changes; need a new one. 15617 final int NA = mAvailProcessChanges.size(); 15618 if (NA > 0) { 15619 item = mAvailProcessChanges.remove(NA-1); 15620 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15621 } else { 15622 item = new ProcessChangeItem(); 15623 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15624 } 15625 item.changes = 0; 15626 item.pid = app.pid; 15627 item.uid = app.info.uid; 15628 if (mPendingProcessChanges.size() == 0) { 15629 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15630 "*** Enqueueing dispatch processes changed!"); 15631 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15632 } 15633 mPendingProcessChanges.add(item); 15634 } 15635 item.changes |= changes; 15636 item.processState = app.repProcState; 15637 item.foregroundActivities = app.repForegroundActivities; 15638 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15639 + Integer.toHexString(System.identityHashCode(item)) 15640 + " " + app.toShortString() + ": changes=" + item.changes 15641 + " procState=" + item.processState 15642 + " foreground=" + item.foregroundActivities 15643 + " type=" + app.adjType + " source=" + app.adjSource 15644 + " target=" + app.adjTarget); 15645 } 15646 15647 return success; 15648 } 15649 15650 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15651 if (proc.thread != null && proc.baseProcessTracker != null) { 15652 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15653 } 15654 } 15655 15656 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15657 ProcessRecord TOP_APP, boolean doingAll, long now) { 15658 if (app.thread == null) { 15659 return false; 15660 } 15661 15662 final boolean wasKeeping = app.keeping; 15663 15664 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15665 15666 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 15667 } 15668 15669 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15670 boolean oomAdj) { 15671 if (isForeground != proc.foregroundServices) { 15672 proc.foregroundServices = isForeground; 15673 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15674 proc.info.uid); 15675 if (isForeground) { 15676 if (curProcs == null) { 15677 curProcs = new ArrayList<ProcessRecord>(); 15678 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15679 } 15680 if (!curProcs.contains(proc)) { 15681 curProcs.add(proc); 15682 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15683 proc.info.packageName, proc.info.uid); 15684 } 15685 } else { 15686 if (curProcs != null) { 15687 if (curProcs.remove(proc)) { 15688 mBatteryStatsService.noteEvent( 15689 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15690 proc.info.packageName, proc.info.uid); 15691 if (curProcs.size() <= 0) { 15692 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15693 } 15694 } 15695 } 15696 } 15697 if (oomAdj) { 15698 updateOomAdjLocked(); 15699 } 15700 } 15701 } 15702 15703 private final ActivityRecord resumedAppLocked() { 15704 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15705 String pkg; 15706 int uid; 15707 if (act != null && !act.sleeping) { 15708 pkg = act.packageName; 15709 uid = act.info.applicationInfo.uid; 15710 } else { 15711 pkg = null; 15712 uid = -1; 15713 } 15714 // Has the UID or resumed package name changed? 15715 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15716 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15717 if (mCurResumedPackage != null) { 15718 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15719 mCurResumedPackage, mCurResumedUid); 15720 } 15721 mCurResumedPackage = pkg; 15722 mCurResumedUid = uid; 15723 if (mCurResumedPackage != null) { 15724 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15725 mCurResumedPackage, mCurResumedUid); 15726 } 15727 } 15728 return act; 15729 } 15730 15731 final boolean updateOomAdjLocked(ProcessRecord app) { 15732 final ActivityRecord TOP_ACT = resumedAppLocked(); 15733 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15734 final boolean wasCached = app.cached; 15735 15736 mAdjSeq++; 15737 15738 // This is the desired cached adjusment we want to tell it to use. 15739 // If our app is currently cached, we know it, and that is it. Otherwise, 15740 // we don't know it yet, and it needs to now be cached we will then 15741 // need to do a complete oom adj. 15742 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15743 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15744 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 15745 SystemClock.uptimeMillis()); 15746 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15747 // Changed to/from cached state, so apps after it in the LRU 15748 // list may also be changed. 15749 updateOomAdjLocked(); 15750 } 15751 return success; 15752 } 15753 15754 final void updateOomAdjLocked() { 15755 final ActivityRecord TOP_ACT = resumedAppLocked(); 15756 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15757 final long now = SystemClock.uptimeMillis(); 15758 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15759 final int N = mLruProcesses.size(); 15760 15761 if (false) { 15762 RuntimeException e = new RuntimeException(); 15763 e.fillInStackTrace(); 15764 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15765 } 15766 15767 mAdjSeq++; 15768 mNewNumServiceProcs = 0; 15769 mNewNumAServiceProcs = 0; 15770 15771 final int emptyProcessLimit; 15772 final int cachedProcessLimit; 15773 if (mProcessLimit <= 0) { 15774 emptyProcessLimit = cachedProcessLimit = 0; 15775 } else if (mProcessLimit == 1) { 15776 emptyProcessLimit = 1; 15777 cachedProcessLimit = 0; 15778 } else { 15779 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15780 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15781 } 15782 15783 // Let's determine how many processes we have running vs. 15784 // how many slots we have for background processes; we may want 15785 // to put multiple processes in a slot of there are enough of 15786 // them. 15787 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15788 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15789 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15790 if (numEmptyProcs > cachedProcessLimit) { 15791 // If there are more empty processes than our limit on cached 15792 // processes, then use the cached process limit for the factor. 15793 // This ensures that the really old empty processes get pushed 15794 // down to the bottom, so if we are running low on memory we will 15795 // have a better chance at keeping around more cached processes 15796 // instead of a gazillion empty processes. 15797 numEmptyProcs = cachedProcessLimit; 15798 } 15799 int emptyFactor = numEmptyProcs/numSlots; 15800 if (emptyFactor < 1) emptyFactor = 1; 15801 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15802 if (cachedFactor < 1) cachedFactor = 1; 15803 int stepCached = 0; 15804 int stepEmpty = 0; 15805 int numCached = 0; 15806 int numEmpty = 0; 15807 int numTrimming = 0; 15808 15809 mNumNonCachedProcs = 0; 15810 mNumCachedHiddenProcs = 0; 15811 15812 // First update the OOM adjustment for each of the 15813 // application processes based on their current state. 15814 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15815 int nextCachedAdj = curCachedAdj+1; 15816 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15817 int nextEmptyAdj = curEmptyAdj+2; 15818 for (int i=N-1; i>=0; i--) { 15819 ProcessRecord app = mLruProcesses.get(i); 15820 if (!app.killedByAm && app.thread != null) { 15821 app.procStateChanged = false; 15822 final boolean wasKeeping = app.keeping; 15823 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15824 15825 // If we haven't yet assigned the final cached adj 15826 // to the process, do that now. 15827 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15828 switch (app.curProcState) { 15829 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15830 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15831 // This process is a cached process holding activities... 15832 // assign it the next cached value for that type, and then 15833 // step that cached level. 15834 app.curRawAdj = curCachedAdj; 15835 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15836 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15837 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15838 + ")"); 15839 if (curCachedAdj != nextCachedAdj) { 15840 stepCached++; 15841 if (stepCached >= cachedFactor) { 15842 stepCached = 0; 15843 curCachedAdj = nextCachedAdj; 15844 nextCachedAdj += 2; 15845 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15846 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15847 } 15848 } 15849 } 15850 break; 15851 default: 15852 // For everything else, assign next empty cached process 15853 // level and bump that up. Note that this means that 15854 // long-running services that have dropped down to the 15855 // cached level will be treated as empty (since their process 15856 // state is still as a service), which is what we want. 15857 app.curRawAdj = curEmptyAdj; 15858 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15859 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15860 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15861 + ")"); 15862 if (curEmptyAdj != nextEmptyAdj) { 15863 stepEmpty++; 15864 if (stepEmpty >= emptyFactor) { 15865 stepEmpty = 0; 15866 curEmptyAdj = nextEmptyAdj; 15867 nextEmptyAdj += 2; 15868 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15869 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15870 } 15871 } 15872 } 15873 break; 15874 } 15875 } 15876 15877 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 15878 15879 // Count the number of process types. 15880 switch (app.curProcState) { 15881 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15882 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15883 mNumCachedHiddenProcs++; 15884 numCached++; 15885 if (numCached > cachedProcessLimit) { 15886 killUnneededProcessLocked(app, "cached #" + numCached); 15887 } 15888 break; 15889 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15890 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15891 && app.lastActivityTime < oldTime) { 15892 killUnneededProcessLocked(app, "empty for " 15893 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15894 / 1000) + "s"); 15895 } else { 15896 numEmpty++; 15897 if (numEmpty > emptyProcessLimit) { 15898 killUnneededProcessLocked(app, "empty #" + numEmpty); 15899 } 15900 } 15901 break; 15902 default: 15903 mNumNonCachedProcs++; 15904 break; 15905 } 15906 15907 if (app.isolated && app.services.size() <= 0) { 15908 // If this is an isolated process, and there are no 15909 // services running in it, then the process is no longer 15910 // needed. We agressively kill these because we can by 15911 // definition not re-use the same process again, and it is 15912 // good to avoid having whatever code was running in them 15913 // left sitting around after no longer needed. 15914 killUnneededProcessLocked(app, "isolated not needed"); 15915 } 15916 15917 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15918 && !app.killedByAm) { 15919 numTrimming++; 15920 } 15921 } 15922 } 15923 15924 mNumServiceProcs = mNewNumServiceProcs; 15925 15926 // Now determine the memory trimming level of background processes. 15927 // Unfortunately we need to start at the back of the list to do this 15928 // properly. We only do this if the number of background apps we 15929 // are managing to keep around is less than half the maximum we desire; 15930 // if we are keeping a good number around, we'll let them use whatever 15931 // memory they want. 15932 final int numCachedAndEmpty = numCached + numEmpty; 15933 int memFactor; 15934 if (numCached <= ProcessList.TRIM_CACHED_APPS 15935 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15936 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15937 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15938 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15939 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15940 } else { 15941 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15942 } 15943 } else { 15944 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15945 } 15946 // We always allow the memory level to go up (better). We only allow it to go 15947 // down if we are in a state where that is allowed, *and* the total number of processes 15948 // has gone down since last time. 15949 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15950 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15951 + " last=" + mLastNumProcesses); 15952 if (memFactor > mLastMemoryLevel) { 15953 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15954 memFactor = mLastMemoryLevel; 15955 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15956 } 15957 } 15958 mLastMemoryLevel = memFactor; 15959 mLastNumProcesses = mLruProcesses.size(); 15960 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 15961 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15962 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15963 if (mLowRamStartTime == 0) { 15964 mLowRamStartTime = now; 15965 } 15966 int step = 0; 15967 int fgTrimLevel; 15968 switch (memFactor) { 15969 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15970 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15971 break; 15972 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15973 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15974 break; 15975 default: 15976 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15977 break; 15978 } 15979 int factor = numTrimming/3; 15980 int minFactor = 2; 15981 if (mHomeProcess != null) minFactor++; 15982 if (mPreviousProcess != null) minFactor++; 15983 if (factor < minFactor) factor = minFactor; 15984 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15985 for (int i=N-1; i>=0; i--) { 15986 ProcessRecord app = mLruProcesses.get(i); 15987 if (allChanged || app.procStateChanged) { 15988 setProcessTrackerState(app, trackerMemFactor, now); 15989 app.procStateChanged = false; 15990 } 15991 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15992 && !app.killedByAm) { 15993 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15994 try { 15995 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15996 "Trimming memory of " + app.processName 15997 + " to " + curLevel); 15998 app.thread.scheduleTrimMemory(curLevel); 15999 } catch (RemoteException e) { 16000 } 16001 if (false) { 16002 // For now we won't do this; our memory trimming seems 16003 // to be good enough at this point that destroying 16004 // activities causes more harm than good. 16005 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16006 && app != mHomeProcess && app != mPreviousProcess) { 16007 // Need to do this on its own message because the stack may not 16008 // be in a consistent state at this point. 16009 // For these apps we will also finish their activities 16010 // to help them free memory. 16011 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16012 } 16013 } 16014 } 16015 app.trimMemoryLevel = curLevel; 16016 step++; 16017 if (step >= factor) { 16018 step = 0; 16019 switch (curLevel) { 16020 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16021 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16022 break; 16023 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16024 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16025 break; 16026 } 16027 } 16028 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16029 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16030 && app.thread != null) { 16031 try { 16032 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16033 "Trimming memory of heavy-weight " + app.processName 16034 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16035 app.thread.scheduleTrimMemory( 16036 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16037 } catch (RemoteException e) { 16038 } 16039 } 16040 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16041 } else { 16042 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16043 || app.systemNoUi) && app.pendingUiClean) { 16044 // If this application is now in the background and it 16045 // had done UI, then give it the special trim level to 16046 // have it free UI resources. 16047 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16048 if (app.trimMemoryLevel < level && app.thread != null) { 16049 try { 16050 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16051 "Trimming memory of bg-ui " + app.processName 16052 + " to " + level); 16053 app.thread.scheduleTrimMemory(level); 16054 } catch (RemoteException e) { 16055 } 16056 } 16057 app.pendingUiClean = false; 16058 } 16059 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16060 try { 16061 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16062 "Trimming memory of fg " + app.processName 16063 + " to " + fgTrimLevel); 16064 app.thread.scheduleTrimMemory(fgTrimLevel); 16065 } catch (RemoteException e) { 16066 } 16067 } 16068 app.trimMemoryLevel = fgTrimLevel; 16069 } 16070 } 16071 } else { 16072 if (mLowRamStartTime != 0) { 16073 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16074 mLowRamStartTime = 0; 16075 } 16076 for (int i=N-1; i>=0; i--) { 16077 ProcessRecord app = mLruProcesses.get(i); 16078 if (allChanged || app.procStateChanged) { 16079 setProcessTrackerState(app, trackerMemFactor, now); 16080 app.procStateChanged = false; 16081 } 16082 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16083 || app.systemNoUi) && app.pendingUiClean) { 16084 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16085 && app.thread != null) { 16086 try { 16087 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16088 "Trimming memory of ui hidden " + app.processName 16089 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16090 app.thread.scheduleTrimMemory( 16091 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16092 } catch (RemoteException e) { 16093 } 16094 } 16095 app.pendingUiClean = false; 16096 } 16097 app.trimMemoryLevel = 0; 16098 } 16099 } 16100 16101 if (mAlwaysFinishActivities) { 16102 // Need to do this on its own message because the stack may not 16103 // be in a consistent state at this point. 16104 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16105 } 16106 16107 if (allChanged) { 16108 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16109 } 16110 16111 if (mProcessStats.shouldWriteNowLocked(now)) { 16112 mHandler.post(new Runnable() { 16113 @Override public void run() { 16114 synchronized (ActivityManagerService.this) { 16115 mProcessStats.writeStateAsyncLocked(); 16116 } 16117 } 16118 }); 16119 } 16120 16121 if (DEBUG_OOM_ADJ) { 16122 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16123 } 16124 } 16125 16126 final void trimApplications() { 16127 synchronized (this) { 16128 int i; 16129 16130 // First remove any unused application processes whose package 16131 // has been removed. 16132 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16133 final ProcessRecord app = mRemovedProcesses.get(i); 16134 if (app.activities.size() == 0 16135 && app.curReceiver == null && app.services.size() == 0) { 16136 Slog.i( 16137 TAG, "Exiting empty application process " 16138 + app.processName + " (" 16139 + (app.thread != null ? app.thread.asBinder() : null) 16140 + ")\n"); 16141 if (app.pid > 0 && app.pid != MY_PID) { 16142 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16143 app.processName, app.setAdj, "empty"); 16144 app.killedByAm = true; 16145 Process.killProcessQuiet(app.pid); 16146 } else { 16147 try { 16148 app.thread.scheduleExit(); 16149 } catch (Exception e) { 16150 // Ignore exceptions. 16151 } 16152 } 16153 cleanUpApplicationRecordLocked(app, false, true, -1); 16154 mRemovedProcesses.remove(i); 16155 16156 if (app.persistent) { 16157 if (app.persistent) { 16158 addAppLocked(app.info, false); 16159 } 16160 } 16161 } 16162 } 16163 16164 // Now update the oom adj for all processes. 16165 updateOomAdjLocked(); 16166 } 16167 } 16168 16169 /** This method sends the specified signal to each of the persistent apps */ 16170 public void signalPersistentProcesses(int sig) throws RemoteException { 16171 if (sig != Process.SIGNAL_USR1) { 16172 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16173 } 16174 16175 synchronized (this) { 16176 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16177 != PackageManager.PERMISSION_GRANTED) { 16178 throw new SecurityException("Requires permission " 16179 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16180 } 16181 16182 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16183 ProcessRecord r = mLruProcesses.get(i); 16184 if (r.thread != null && r.persistent) { 16185 Process.sendSignal(r.pid, sig); 16186 } 16187 } 16188 } 16189 } 16190 16191 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16192 if (proc == null || proc == mProfileProc) { 16193 proc = mProfileProc; 16194 path = mProfileFile; 16195 profileType = mProfileType; 16196 clearProfilerLocked(); 16197 } 16198 if (proc == null) { 16199 return; 16200 } 16201 try { 16202 proc.thread.profilerControl(false, path, null, profileType); 16203 } catch (RemoteException e) { 16204 throw new IllegalStateException("Process disappeared"); 16205 } 16206 } 16207 16208 private void clearProfilerLocked() { 16209 if (mProfileFd != null) { 16210 try { 16211 mProfileFd.close(); 16212 } catch (IOException e) { 16213 } 16214 } 16215 mProfileApp = null; 16216 mProfileProc = null; 16217 mProfileFile = null; 16218 mProfileType = 0; 16219 mAutoStopProfiler = false; 16220 } 16221 16222 public boolean profileControl(String process, int userId, boolean start, 16223 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16224 16225 try { 16226 synchronized (this) { 16227 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16228 // its own permission. 16229 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16230 != PackageManager.PERMISSION_GRANTED) { 16231 throw new SecurityException("Requires permission " 16232 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16233 } 16234 16235 if (start && fd == null) { 16236 throw new IllegalArgumentException("null fd"); 16237 } 16238 16239 ProcessRecord proc = null; 16240 if (process != null) { 16241 proc = findProcessLocked(process, userId, "profileControl"); 16242 } 16243 16244 if (start && (proc == null || proc.thread == null)) { 16245 throw new IllegalArgumentException("Unknown process: " + process); 16246 } 16247 16248 if (start) { 16249 stopProfilerLocked(null, null, 0); 16250 setProfileApp(proc.info, proc.processName, path, fd, false); 16251 mProfileProc = proc; 16252 mProfileType = profileType; 16253 try { 16254 fd = fd.dup(); 16255 } catch (IOException e) { 16256 fd = null; 16257 } 16258 proc.thread.profilerControl(start, path, fd, profileType); 16259 fd = null; 16260 mProfileFd = null; 16261 } else { 16262 stopProfilerLocked(proc, path, profileType); 16263 if (fd != null) { 16264 try { 16265 fd.close(); 16266 } catch (IOException e) { 16267 } 16268 } 16269 } 16270 16271 return true; 16272 } 16273 } catch (RemoteException e) { 16274 throw new IllegalStateException("Process disappeared"); 16275 } finally { 16276 if (fd != null) { 16277 try { 16278 fd.close(); 16279 } catch (IOException e) { 16280 } 16281 } 16282 } 16283 } 16284 16285 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16286 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16287 userId, true, true, callName, null); 16288 ProcessRecord proc = null; 16289 try { 16290 int pid = Integer.parseInt(process); 16291 synchronized (mPidsSelfLocked) { 16292 proc = mPidsSelfLocked.get(pid); 16293 } 16294 } catch (NumberFormatException e) { 16295 } 16296 16297 if (proc == null) { 16298 ArrayMap<String, SparseArray<ProcessRecord>> all 16299 = mProcessNames.getMap(); 16300 SparseArray<ProcessRecord> procs = all.get(process); 16301 if (procs != null && procs.size() > 0) { 16302 proc = procs.valueAt(0); 16303 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16304 for (int i=1; i<procs.size(); i++) { 16305 ProcessRecord thisProc = procs.valueAt(i); 16306 if (thisProc.userId == userId) { 16307 proc = thisProc; 16308 break; 16309 } 16310 } 16311 } 16312 } 16313 } 16314 16315 return proc; 16316 } 16317 16318 public boolean dumpHeap(String process, int userId, boolean managed, 16319 String path, ParcelFileDescriptor fd) throws RemoteException { 16320 16321 try { 16322 synchronized (this) { 16323 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16324 // its own permission (same as profileControl). 16325 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16326 != PackageManager.PERMISSION_GRANTED) { 16327 throw new SecurityException("Requires permission " 16328 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16329 } 16330 16331 if (fd == null) { 16332 throw new IllegalArgumentException("null fd"); 16333 } 16334 16335 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16336 if (proc == null || proc.thread == null) { 16337 throw new IllegalArgumentException("Unknown process: " + process); 16338 } 16339 16340 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16341 if (!isDebuggable) { 16342 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16343 throw new SecurityException("Process not debuggable: " + proc); 16344 } 16345 } 16346 16347 proc.thread.dumpHeap(managed, path, fd); 16348 fd = null; 16349 return true; 16350 } 16351 } catch (RemoteException e) { 16352 throw new IllegalStateException("Process disappeared"); 16353 } finally { 16354 if (fd != null) { 16355 try { 16356 fd.close(); 16357 } catch (IOException e) { 16358 } 16359 } 16360 } 16361 } 16362 16363 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16364 public void monitor() { 16365 synchronized (this) { } 16366 } 16367 16368 void onCoreSettingsChange(Bundle settings) { 16369 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16370 ProcessRecord processRecord = mLruProcesses.get(i); 16371 try { 16372 if (processRecord.thread != null) { 16373 processRecord.thread.setCoreSettings(settings); 16374 } 16375 } catch (RemoteException re) { 16376 /* ignore */ 16377 } 16378 } 16379 } 16380 16381 // Multi-user methods 16382 16383 /** 16384 * Start user, if its not already running, but don't bring it to foreground. 16385 */ 16386 @Override 16387 public boolean startUserInBackground(final int userId) { 16388 return startUser(userId, /* foreground */ false); 16389 } 16390 16391 /** 16392 * Refreshes the list of users related to the current user when either a 16393 * user switch happens or when a new related user is started in the 16394 * background. 16395 */ 16396 private void updateCurrentProfileIdsLocked() { 16397 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16398 mCurrentUserId, false /* enabledOnly */); 16399 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16400 for (int i = 0; i < currentProfileIds.length; i++) { 16401 currentProfileIds[i] = profiles.get(i).id; 16402 } 16403 mCurrentProfileIds = currentProfileIds; 16404 } 16405 16406 private Set getProfileIdsLocked(int userId) { 16407 Set userIds = new HashSet<Integer>(); 16408 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16409 userId, false /* enabledOnly */); 16410 for (UserInfo user : profiles) { 16411 userIds.add(Integer.valueOf(user.id)); 16412 } 16413 return userIds; 16414 } 16415 16416 @Override 16417 public boolean switchUser(final int userId) { 16418 return startUser(userId, /* foregound */ true); 16419 } 16420 16421 private boolean startUser(final int userId, boolean foreground) { 16422 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16423 != PackageManager.PERMISSION_GRANTED) { 16424 String msg = "Permission Denial: switchUser() from pid=" 16425 + Binder.getCallingPid() 16426 + ", uid=" + Binder.getCallingUid() 16427 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16428 Slog.w(TAG, msg); 16429 throw new SecurityException(msg); 16430 } 16431 16432 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16433 16434 final long ident = Binder.clearCallingIdentity(); 16435 try { 16436 synchronized (this) { 16437 final int oldUserId = mCurrentUserId; 16438 if (oldUserId == userId) { 16439 return true; 16440 } 16441 16442 mStackSupervisor.setLockTaskModeLocked(null); 16443 16444 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16445 if (userInfo == null) { 16446 Slog.w(TAG, "No user info for user #" + userId); 16447 return false; 16448 } 16449 16450 if (foreground) { 16451 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16452 R.anim.screen_user_enter); 16453 } 16454 16455 boolean needStart = false; 16456 16457 // If the user we are switching to is not currently started, then 16458 // we need to start it now. 16459 if (mStartedUsers.get(userId) == null) { 16460 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16461 updateStartedUserArrayLocked(); 16462 needStart = true; 16463 } 16464 16465 final Integer userIdInt = Integer.valueOf(userId); 16466 mUserLru.remove(userIdInt); 16467 mUserLru.add(userIdInt); 16468 16469 if (foreground) { 16470 mCurrentUserId = userId; 16471 updateCurrentProfileIdsLocked(); 16472 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16473 // Once the internal notion of the active user has switched, we lock the device 16474 // with the option to show the user switcher on the keyguard. 16475 mWindowManager.lockNow(null); 16476 } else { 16477 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16478 updateCurrentProfileIdsLocked(); 16479 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16480 mUserLru.remove(currentUserIdInt); 16481 mUserLru.add(currentUserIdInt); 16482 } 16483 16484 final UserStartedState uss = mStartedUsers.get(userId); 16485 16486 // Make sure user is in the started state. If it is currently 16487 // stopping, we need to knock that off. 16488 if (uss.mState == UserStartedState.STATE_STOPPING) { 16489 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16490 // so we can just fairly silently bring the user back from 16491 // the almost-dead. 16492 uss.mState = UserStartedState.STATE_RUNNING; 16493 updateStartedUserArrayLocked(); 16494 needStart = true; 16495 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16496 // This means ACTION_SHUTDOWN has been sent, so we will 16497 // need to treat this as a new boot of the user. 16498 uss.mState = UserStartedState.STATE_BOOTING; 16499 updateStartedUserArrayLocked(); 16500 needStart = true; 16501 } 16502 16503 if (uss.mState == UserStartedState.STATE_BOOTING) { 16504 // Booting up a new user, need to tell system services about it. 16505 // Note that this is on the same handler as scheduling of broadcasts, 16506 // which is important because it needs to go first. 16507 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16508 } 16509 16510 if (foreground) { 16511 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16512 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16513 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16514 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16515 oldUserId, userId, uss)); 16516 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16517 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16518 } 16519 16520 if (needStart) { 16521 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16522 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16523 | Intent.FLAG_RECEIVER_FOREGROUND); 16524 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16525 broadcastIntentLocked(null, null, intent, 16526 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16527 false, false, MY_PID, Process.SYSTEM_UID, userId); 16528 } 16529 16530 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16531 if (userId != 0) { 16532 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16533 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16534 broadcastIntentLocked(null, null, intent, null, 16535 new IIntentReceiver.Stub() { 16536 public void performReceive(Intent intent, int resultCode, 16537 String data, Bundle extras, boolean ordered, 16538 boolean sticky, int sendingUser) { 16539 userInitialized(uss, userId); 16540 } 16541 }, 0, null, null, null, AppOpsManager.OP_NONE, 16542 true, false, MY_PID, Process.SYSTEM_UID, 16543 userId); 16544 uss.initializing = true; 16545 } else { 16546 getUserManagerLocked().makeInitialized(userInfo.id); 16547 } 16548 } 16549 16550 if (foreground) { 16551 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16552 if (homeInFront) { 16553 startHomeActivityLocked(userId); 16554 } else { 16555 mStackSupervisor.resumeTopActivitiesLocked(); 16556 } 16557 EventLogTags.writeAmSwitchUser(userId); 16558 getUserManagerLocked().userForeground(userId); 16559 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16560 } 16561 16562 if (needStart) { 16563 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16564 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16565 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16566 broadcastIntentLocked(null, null, intent, 16567 null, new IIntentReceiver.Stub() { 16568 @Override 16569 public void performReceive(Intent intent, int resultCode, String data, 16570 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16571 throws RemoteException { 16572 } 16573 }, 0, null, null, 16574 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16575 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16576 } 16577 } 16578 } finally { 16579 Binder.restoreCallingIdentity(ident); 16580 } 16581 16582 return true; 16583 } 16584 16585 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16586 long ident = Binder.clearCallingIdentity(); 16587 try { 16588 Intent intent; 16589 if (oldUserId >= 0) { 16590 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16591 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16592 | Intent.FLAG_RECEIVER_FOREGROUND); 16593 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16594 broadcastIntentLocked(null, null, intent, 16595 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16596 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16597 } 16598 if (newUserId >= 0) { 16599 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16600 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16601 | Intent.FLAG_RECEIVER_FOREGROUND); 16602 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16603 broadcastIntentLocked(null, null, intent, 16604 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16605 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16606 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16607 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16608 | Intent.FLAG_RECEIVER_FOREGROUND); 16609 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16610 broadcastIntentLocked(null, null, intent, 16611 null, null, 0, null, null, 16612 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16613 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16614 } 16615 } finally { 16616 Binder.restoreCallingIdentity(ident); 16617 } 16618 } 16619 16620 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16621 final int newUserId) { 16622 final int N = mUserSwitchObservers.beginBroadcast(); 16623 if (N > 0) { 16624 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16625 int mCount = 0; 16626 @Override 16627 public void sendResult(Bundle data) throws RemoteException { 16628 synchronized (ActivityManagerService.this) { 16629 if (mCurUserSwitchCallback == this) { 16630 mCount++; 16631 if (mCount == N) { 16632 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16633 } 16634 } 16635 } 16636 } 16637 }; 16638 synchronized (this) { 16639 uss.switching = true; 16640 mCurUserSwitchCallback = callback; 16641 } 16642 for (int i=0; i<N; i++) { 16643 try { 16644 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16645 newUserId, callback); 16646 } catch (RemoteException e) { 16647 } 16648 } 16649 } else { 16650 synchronized (this) { 16651 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16652 } 16653 } 16654 mUserSwitchObservers.finishBroadcast(); 16655 } 16656 16657 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16658 synchronized (this) { 16659 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16660 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16661 } 16662 } 16663 16664 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16665 mCurUserSwitchCallback = null; 16666 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16667 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16668 oldUserId, newUserId, uss)); 16669 } 16670 16671 void userInitialized(UserStartedState uss, int newUserId) { 16672 completeSwitchAndInitalize(uss, newUserId, true, false); 16673 } 16674 16675 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16676 completeSwitchAndInitalize(uss, newUserId, false, true); 16677 } 16678 16679 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16680 boolean clearInitializing, boolean clearSwitching) { 16681 boolean unfrozen = false; 16682 synchronized (this) { 16683 if (clearInitializing) { 16684 uss.initializing = false; 16685 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16686 } 16687 if (clearSwitching) { 16688 uss.switching = false; 16689 } 16690 if (!uss.switching && !uss.initializing) { 16691 mWindowManager.stopFreezingScreen(); 16692 unfrozen = true; 16693 } 16694 } 16695 if (unfrozen) { 16696 final int N = mUserSwitchObservers.beginBroadcast(); 16697 for (int i=0; i<N; i++) { 16698 try { 16699 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16700 } catch (RemoteException e) { 16701 } 16702 } 16703 mUserSwitchObservers.finishBroadcast(); 16704 } 16705 } 16706 16707 void scheduleStartProfilesLocked() { 16708 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16709 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16710 DateUtils.SECOND_IN_MILLIS); 16711 } 16712 } 16713 16714 void startProfilesLocked() { 16715 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16716 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16717 mCurrentUserId, false /* enabledOnly */); 16718 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16719 for (UserInfo user : profiles) { 16720 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16721 && user.id != mCurrentUserId) { 16722 toStart.add(user); 16723 } 16724 } 16725 final int n = toStart.size(); 16726 int i = 0; 16727 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16728 startUserInBackground(toStart.get(i).id); 16729 } 16730 if (i < n) { 16731 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16732 } 16733 } 16734 16735 void finishUserSwitch(UserStartedState uss) { 16736 synchronized (this) { 16737 if (uss.mState == UserStartedState.STATE_BOOTING 16738 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16739 uss.mState = UserStartedState.STATE_RUNNING; 16740 final int userId = uss.mHandle.getIdentifier(); 16741 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16742 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16743 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16744 broadcastIntentLocked(null, null, intent, 16745 null, null, 0, null, null, 16746 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16747 true, false, MY_PID, Process.SYSTEM_UID, userId); 16748 } 16749 16750 startProfilesLocked(); 16751 16752 int num = mUserLru.size(); 16753 int i = 0; 16754 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16755 Integer oldUserId = mUserLru.get(i); 16756 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16757 if (oldUss == null) { 16758 // Shouldn't happen, but be sane if it does. 16759 mUserLru.remove(i); 16760 num--; 16761 continue; 16762 } 16763 if (oldUss.mState == UserStartedState.STATE_STOPPING 16764 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16765 // This user is already stopping, doesn't count. 16766 num--; 16767 i++; 16768 continue; 16769 } 16770 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16771 // Owner and current can't be stopped, but count as running. 16772 i++; 16773 continue; 16774 } 16775 // This is a user to be stopped. 16776 stopUserLocked(oldUserId, null); 16777 num--; 16778 i++; 16779 } 16780 } 16781 } 16782 16783 @Override 16784 public int stopUser(final int userId, final IStopUserCallback callback) { 16785 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16786 != PackageManager.PERMISSION_GRANTED) { 16787 String msg = "Permission Denial: switchUser() from pid=" 16788 + Binder.getCallingPid() 16789 + ", uid=" + Binder.getCallingUid() 16790 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16791 Slog.w(TAG, msg); 16792 throw new SecurityException(msg); 16793 } 16794 if (userId <= 0) { 16795 throw new IllegalArgumentException("Can't stop primary user " + userId); 16796 } 16797 synchronized (this) { 16798 return stopUserLocked(userId, callback); 16799 } 16800 } 16801 16802 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16803 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16804 if (mCurrentUserId == userId) { 16805 return ActivityManager.USER_OP_IS_CURRENT; 16806 } 16807 16808 final UserStartedState uss = mStartedUsers.get(userId); 16809 if (uss == null) { 16810 // User is not started, nothing to do... but we do need to 16811 // callback if requested. 16812 if (callback != null) { 16813 mHandler.post(new Runnable() { 16814 @Override 16815 public void run() { 16816 try { 16817 callback.userStopped(userId); 16818 } catch (RemoteException e) { 16819 } 16820 } 16821 }); 16822 } 16823 return ActivityManager.USER_OP_SUCCESS; 16824 } 16825 16826 if (callback != null) { 16827 uss.mStopCallbacks.add(callback); 16828 } 16829 16830 if (uss.mState != UserStartedState.STATE_STOPPING 16831 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16832 uss.mState = UserStartedState.STATE_STOPPING; 16833 updateStartedUserArrayLocked(); 16834 16835 long ident = Binder.clearCallingIdentity(); 16836 try { 16837 // We are going to broadcast ACTION_USER_STOPPING and then 16838 // once that is done send a final ACTION_SHUTDOWN and then 16839 // stop the user. 16840 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16841 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16842 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16843 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16844 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16845 // This is the result receiver for the final shutdown broadcast. 16846 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16847 @Override 16848 public void performReceive(Intent intent, int resultCode, String data, 16849 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16850 finishUserStop(uss); 16851 } 16852 }; 16853 // This is the result receiver for the initial stopping broadcast. 16854 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16855 @Override 16856 public void performReceive(Intent intent, int resultCode, String data, 16857 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16858 // On to the next. 16859 synchronized (ActivityManagerService.this) { 16860 if (uss.mState != UserStartedState.STATE_STOPPING) { 16861 // Whoops, we are being started back up. Abort, abort! 16862 return; 16863 } 16864 uss.mState = UserStartedState.STATE_SHUTDOWN; 16865 } 16866 mSystemServiceManager.stopUser(userId); 16867 broadcastIntentLocked(null, null, shutdownIntent, 16868 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16869 true, false, MY_PID, Process.SYSTEM_UID, userId); 16870 } 16871 }; 16872 // Kick things off. 16873 broadcastIntentLocked(null, null, stoppingIntent, 16874 null, stoppingReceiver, 0, null, null, 16875 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16876 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16877 } finally { 16878 Binder.restoreCallingIdentity(ident); 16879 } 16880 } 16881 16882 return ActivityManager.USER_OP_SUCCESS; 16883 } 16884 16885 void finishUserStop(UserStartedState uss) { 16886 final int userId = uss.mHandle.getIdentifier(); 16887 boolean stopped; 16888 ArrayList<IStopUserCallback> callbacks; 16889 synchronized (this) { 16890 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16891 if (mStartedUsers.get(userId) != uss) { 16892 stopped = false; 16893 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16894 stopped = false; 16895 } else { 16896 stopped = true; 16897 // User can no longer run. 16898 mStartedUsers.remove(userId); 16899 mUserLru.remove(Integer.valueOf(userId)); 16900 updateStartedUserArrayLocked(); 16901 16902 // Clean up all state and processes associated with the user. 16903 // Kill all the processes for the user. 16904 forceStopUserLocked(userId, "finish user"); 16905 } 16906 } 16907 16908 for (int i=0; i<callbacks.size(); i++) { 16909 try { 16910 if (stopped) callbacks.get(i).userStopped(userId); 16911 else callbacks.get(i).userStopAborted(userId); 16912 } catch (RemoteException e) { 16913 } 16914 } 16915 16916 if (stopped) { 16917 mSystemServiceManager.cleanupUser(userId); 16918 synchronized (this) { 16919 mStackSupervisor.removeUserLocked(userId); 16920 } 16921 } 16922 } 16923 16924 @Override 16925 public UserInfo getCurrentUser() { 16926 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16927 != PackageManager.PERMISSION_GRANTED) && ( 16928 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16929 != PackageManager.PERMISSION_GRANTED)) { 16930 String msg = "Permission Denial: getCurrentUser() from pid=" 16931 + Binder.getCallingPid() 16932 + ", uid=" + Binder.getCallingUid() 16933 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16934 Slog.w(TAG, msg); 16935 throw new SecurityException(msg); 16936 } 16937 synchronized (this) { 16938 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16939 } 16940 } 16941 16942 int getCurrentUserIdLocked() { 16943 return mCurrentUserId; 16944 } 16945 16946 @Override 16947 public boolean isUserRunning(int userId, boolean orStopped) { 16948 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16949 != PackageManager.PERMISSION_GRANTED) { 16950 String msg = "Permission Denial: isUserRunning() from pid=" 16951 + Binder.getCallingPid() 16952 + ", uid=" + Binder.getCallingUid() 16953 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16954 Slog.w(TAG, msg); 16955 throw new SecurityException(msg); 16956 } 16957 synchronized (this) { 16958 return isUserRunningLocked(userId, orStopped); 16959 } 16960 } 16961 16962 boolean isUserRunningLocked(int userId, boolean orStopped) { 16963 UserStartedState state = mStartedUsers.get(userId); 16964 if (state == null) { 16965 return false; 16966 } 16967 if (orStopped) { 16968 return true; 16969 } 16970 return state.mState != UserStartedState.STATE_STOPPING 16971 && state.mState != UserStartedState.STATE_SHUTDOWN; 16972 } 16973 16974 @Override 16975 public int[] getRunningUserIds() { 16976 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16977 != PackageManager.PERMISSION_GRANTED) { 16978 String msg = "Permission Denial: isUserRunning() from pid=" 16979 + Binder.getCallingPid() 16980 + ", uid=" + Binder.getCallingUid() 16981 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16982 Slog.w(TAG, msg); 16983 throw new SecurityException(msg); 16984 } 16985 synchronized (this) { 16986 return mStartedUserArray; 16987 } 16988 } 16989 16990 private void updateStartedUserArrayLocked() { 16991 int num = 0; 16992 for (int i=0; i<mStartedUsers.size(); i++) { 16993 UserStartedState uss = mStartedUsers.valueAt(i); 16994 // This list does not include stopping users. 16995 if (uss.mState != UserStartedState.STATE_STOPPING 16996 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16997 num++; 16998 } 16999 } 17000 mStartedUserArray = new int[num]; 17001 num = 0; 17002 for (int i=0; i<mStartedUsers.size(); i++) { 17003 UserStartedState uss = mStartedUsers.valueAt(i); 17004 if (uss.mState != UserStartedState.STATE_STOPPING 17005 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17006 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17007 num++; 17008 } 17009 } 17010 } 17011 17012 @Override 17013 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17014 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17015 != PackageManager.PERMISSION_GRANTED) { 17016 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17017 + Binder.getCallingPid() 17018 + ", uid=" + Binder.getCallingUid() 17019 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 17020 Slog.w(TAG, msg); 17021 throw new SecurityException(msg); 17022 } 17023 17024 mUserSwitchObservers.register(observer); 17025 } 17026 17027 @Override 17028 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17029 mUserSwitchObservers.unregister(observer); 17030 } 17031 17032 private boolean userExists(int userId) { 17033 if (userId == 0) { 17034 return true; 17035 } 17036 UserManagerService ums = getUserManagerLocked(); 17037 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17038 } 17039 17040 int[] getUsersLocked() { 17041 UserManagerService ums = getUserManagerLocked(); 17042 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17043 } 17044 17045 UserManagerService getUserManagerLocked() { 17046 if (mUserManager == null) { 17047 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17048 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17049 } 17050 return mUserManager; 17051 } 17052 17053 private int applyUserId(int uid, int userId) { 17054 return UserHandle.getUid(userId, uid); 17055 } 17056 17057 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17058 if (info == null) return null; 17059 ApplicationInfo newInfo = new ApplicationInfo(info); 17060 newInfo.uid = applyUserId(info.uid, userId); 17061 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17062 + info.packageName; 17063 return newInfo; 17064 } 17065 17066 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17067 if (aInfo == null 17068 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17069 return aInfo; 17070 } 17071 17072 ActivityInfo info = new ActivityInfo(aInfo); 17073 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17074 return info; 17075 } 17076 17077 private final class LocalService extends ActivityManagerInternal { 17078 @Override 17079 public void goingToSleep() { 17080 ActivityManagerService.this.goingToSleep(); 17081 } 17082 17083 @Override 17084 public void wakingUp() { 17085 ActivityManagerService.this.wakingUp(); 17086 } 17087 } 17088} 17089