ActivityManagerService.java revision 4b9d79c30eccb61645d98a4f0d49b7769e8c7ccc
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.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 20import static android.content.pm.PackageManager.PERMISSION_GRANTED; 21import static com.android.internal.util.XmlUtils.readBooleanAttribute; 22import static com.android.internal.util.XmlUtils.readIntAttribute; 23import static com.android.internal.util.XmlUtils.readLongAttribute; 24import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 25import static com.android.internal.util.XmlUtils.writeIntAttribute; 26import static com.android.internal.util.XmlUtils.writeLongAttribute; 27import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 28import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 29import static org.xmlpull.v1.XmlPullParser.START_TAG; 30import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 31 32import android.Manifest; 33import android.app.AppOpsManager; 34import android.app.IActivityContainer; 35import android.app.IActivityContainerCallback; 36import android.app.IAppTask; 37import android.app.admin.DevicePolicyManager; 38import android.appwidget.AppWidgetManager; 39import android.graphics.Rect; 40import android.os.BatteryStats; 41import android.os.PersistableBundle; 42import android.service.voice.IVoiceInteractionSession; 43import android.util.ArrayMap; 44 45import com.android.internal.R; 46import com.android.internal.annotations.GuardedBy; 47import com.android.internal.app.IAppOpsService; 48import com.android.internal.app.IVoiceInteractor; 49import com.android.internal.app.ProcessMap; 50import com.android.internal.app.ProcessStats; 51import com.android.internal.content.PackageMonitor; 52import com.android.internal.os.BackgroundThread; 53import com.android.internal.os.BatteryStatsImpl; 54import com.android.internal.os.ProcessCpuTracker; 55import com.android.internal.os.TransferPipe; 56import com.android.internal.os.Zygote; 57import com.android.internal.util.FastPrintWriter; 58import com.android.internal.util.FastXmlSerializer; 59import com.android.internal.util.MemInfoReader; 60import com.android.internal.util.Preconditions; 61import com.android.server.AppOpsService; 62import com.android.server.AttributeCache; 63import com.android.server.IntentResolver; 64import com.android.server.LocalServices; 65import com.android.server.ServiceThread; 66import com.android.server.SystemService; 67import com.android.server.SystemServiceManager; 68import com.android.server.Watchdog; 69import com.android.server.am.ActivityStack.ActivityState; 70import com.android.server.firewall.IntentFirewall; 71import com.android.server.pm.UserManagerService; 72import com.android.server.wm.AppTransition; 73import com.android.server.wm.WindowManagerService; 74import com.google.android.collect.Lists; 75import com.google.android.collect.Maps; 76 77import libcore.io.IoUtils; 78 79import org.xmlpull.v1.XmlPullParser; 80import org.xmlpull.v1.XmlPullParserException; 81import org.xmlpull.v1.XmlSerializer; 82 83import android.app.Activity; 84import android.app.ActivityManager; 85import android.app.ActivityManager.RunningTaskInfo; 86import android.app.ActivityManager.StackInfo; 87import android.app.ActivityManagerInternal; 88import android.app.ActivityManagerNative; 89import android.app.ActivityOptions; 90import android.app.ActivityThread; 91import android.app.AlertDialog; 92import android.app.AppGlobals; 93import android.app.ApplicationErrorReport; 94import android.app.Dialog; 95import android.app.IActivityController; 96import android.app.IApplicationThread; 97import android.app.IInstrumentationWatcher; 98import android.app.INotificationManager; 99import android.app.IProcessObserver; 100import android.app.IServiceConnection; 101import android.app.IStopUserCallback; 102import android.app.IUiAutomationConnection; 103import android.app.IUserSwitchObserver; 104import android.app.Instrumentation; 105import android.app.Notification; 106import android.app.NotificationManager; 107import android.app.PendingIntent; 108import android.app.backup.IBackupManager; 109import android.content.ActivityNotFoundException; 110import android.content.BroadcastReceiver; 111import android.content.ClipData; 112import android.content.ComponentCallbacks2; 113import android.content.ComponentName; 114import android.content.ContentProvider; 115import android.content.ContentResolver; 116import android.content.Context; 117import android.content.DialogInterface; 118import android.content.IContentProvider; 119import android.content.IIntentReceiver; 120import android.content.IIntentSender; 121import android.content.Intent; 122import android.content.IntentFilter; 123import android.content.IntentSender; 124import android.content.pm.ActivityInfo; 125import android.content.pm.ApplicationInfo; 126import android.content.pm.ConfigurationInfo; 127import android.content.pm.IPackageDataObserver; 128import android.content.pm.IPackageManager; 129import android.content.pm.InstrumentationInfo; 130import android.content.pm.PackageInfo; 131import android.content.pm.PackageManager; 132import android.content.pm.ParceledListSlice; 133import android.content.pm.UserInfo; 134import android.content.pm.PackageManager.NameNotFoundException; 135import android.content.pm.PathPermission; 136import android.content.pm.ProviderInfo; 137import android.content.pm.ResolveInfo; 138import android.content.pm.ServiceInfo; 139import android.content.res.CompatibilityInfo; 140import android.content.res.Configuration; 141import android.graphics.Bitmap; 142import android.net.Proxy; 143import android.net.ProxyInfo; 144import android.net.Uri; 145import android.os.Binder; 146import android.os.Build; 147import android.os.Bundle; 148import android.os.Debug; 149import android.os.DropBoxManager; 150import android.os.Environment; 151import android.os.FactoryTest; 152import android.os.FileObserver; 153import android.os.FileUtils; 154import android.os.Handler; 155import android.os.IBinder; 156import android.os.IPermissionController; 157import android.os.IRemoteCallback; 158import android.os.IUserManager; 159import android.os.Looper; 160import android.os.Message; 161import android.os.Parcel; 162import android.os.ParcelFileDescriptor; 163import android.os.Process; 164import android.os.RemoteCallbackList; 165import android.os.RemoteException; 166import android.os.SELinux; 167import android.os.ServiceManager; 168import android.os.StrictMode; 169import android.os.SystemClock; 170import android.os.SystemProperties; 171import android.os.UpdateLock; 172import android.os.UserHandle; 173import android.provider.Settings; 174import android.text.format.DateUtils; 175import android.text.format.Time; 176import android.util.AtomicFile; 177import android.util.EventLog; 178import android.util.Log; 179import android.util.Pair; 180import android.util.PrintWriterPrinter; 181import android.util.Slog; 182import android.util.SparseArray; 183import android.util.TimeUtils; 184import android.util.Xml; 185import android.view.Gravity; 186import android.view.LayoutInflater; 187import android.view.View; 188import android.view.WindowManager; 189 190import java.io.BufferedInputStream; 191import java.io.BufferedOutputStream; 192import java.io.DataInputStream; 193import java.io.DataOutputStream; 194import java.io.File; 195import java.io.FileDescriptor; 196import java.io.FileInputStream; 197import java.io.FileNotFoundException; 198import java.io.FileOutputStream; 199import java.io.IOException; 200import java.io.InputStreamReader; 201import java.io.PrintWriter; 202import java.io.StringWriter; 203import java.lang.ref.WeakReference; 204import java.util.ArrayList; 205import java.util.Arrays; 206import java.util.Collections; 207import java.util.Comparator; 208import java.util.HashMap; 209import java.util.HashSet; 210import java.util.Iterator; 211import java.util.List; 212import java.util.Locale; 213import java.util.Map; 214import java.util.Set; 215import java.util.concurrent.atomic.AtomicBoolean; 216import java.util.concurrent.atomic.AtomicLong; 217 218public final class ActivityManagerService extends ActivityManagerNative 219 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 220 private static final String USER_DATA_DIR = "/data/user/"; 221 static final String TAG = "ActivityManager"; 222 static final String TAG_MU = "ActivityManagerServiceMU"; 223 static final boolean DEBUG = false; 224 static final boolean localLOGV = DEBUG; 225 static final boolean DEBUG_BACKUP = localLOGV || false; 226 static final boolean DEBUG_BROADCAST = localLOGV || false; 227 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 228 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 229 static final boolean DEBUG_CLEANUP = localLOGV || false; 230 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 231 static final boolean DEBUG_FOCUS = false; 232 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 233 static final boolean DEBUG_MU = localLOGV || false; 234 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 235 static final boolean DEBUG_LRU = localLOGV || false; 236 static final boolean DEBUG_PAUSE = localLOGV || false; 237 static final boolean DEBUG_POWER = localLOGV || false; 238 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 239 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 240 static final boolean DEBUG_PROCESSES = localLOGV || false; 241 static final boolean DEBUG_PROVIDER = localLOGV || false; 242 static final boolean DEBUG_RESULTS = localLOGV || false; 243 static final boolean DEBUG_SERVICE = localLOGV || false; 244 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 245 static final boolean DEBUG_STACK = localLOGV || false; 246 static final boolean DEBUG_SWITCH = localLOGV || false; 247 static final boolean DEBUG_TASKS = localLOGV || false; 248 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 249 static final boolean DEBUG_TRANSITION = localLOGV || false; 250 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 251 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 252 static final boolean DEBUG_VISBILITY = localLOGV || false; 253 static final boolean DEBUG_PSS = localLOGV || false; 254 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 255 static final boolean VALIDATE_TOKENS = false; 256 static final boolean SHOW_ACTIVITY_START_TIME = true; 257 258 // Control over CPU and battery monitoring. 259 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 260 static final boolean MONITOR_CPU_USAGE = true; 261 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 262 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 263 static final boolean MONITOR_THREAD_CPU_USAGE = false; 264 265 // The flags that are set for all calls we make to the package manager. 266 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 267 268 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 269 270 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 271 272 // Maximum number of recent tasks that we can remember. 273 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 274 275 // Amount of time after a call to stopAppSwitches() during which we will 276 // prevent further untrusted switches from happening. 277 static final long APP_SWITCH_DELAY_TIME = 5*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. 281 static final int PROC_START_TIMEOUT = 10*1000; 282 283 // How long we wait for a launched process to attach to the activity manager 284 // before we decide it's never going to come up for real, when the process was 285 // started with a wrapper for instrumentation (such as Valgrind) because it 286 // could take much longer than usual. 287 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 288 289 // How long to wait after going idle before forcing apps to GC. 290 static final int GC_TIMEOUT = 5*1000; 291 292 // The minimum amount of time between successive GC requests for a process. 293 static final int GC_MIN_INTERVAL = 60*1000; 294 295 // The minimum amount of time between successive PSS requests for a process. 296 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 297 298 // The minimum amount of time between successive PSS requests for a process 299 // when the request is due to the memory state being lowered. 300 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 301 302 // The rate at which we check for apps using excessive power -- 15 mins. 303 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 304 305 // The minimum sample duration we will allow before deciding we have 306 // enough data on wake locks to start killing things. 307 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 308 309 // The minimum sample duration we will allow before deciding we have 310 // enough data on CPU usage to start killing things. 311 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 312 313 // How long we allow a receiver to run before giving up on it. 314 static final int BROADCAST_FG_TIMEOUT = 10*1000; 315 static final int BROADCAST_BG_TIMEOUT = 60*1000; 316 317 // How long we wait until we timeout on key dispatching. 318 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 319 320 // How long we wait until we timeout on key dispatching during instrumentation. 321 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 322 323 // Amount of time we wait for observers to handle a user switch before 324 // giving up on them and unfreezing the screen. 325 static final int USER_SWITCH_TIMEOUT = 2*1000; 326 327 // Maximum number of users we allow to be running at a time. 328 static final int MAX_RUNNING_USERS = 3; 329 330 // How long to wait in getAssistContextExtras for the activity and foreground services 331 // to respond with the result. 332 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 333 334 // Maximum number of persisted Uri grants a package is allowed 335 static final int MAX_PERSISTED_URI_GRANTS = 128; 336 337 static final int MY_PID = Process.myPid(); 338 339 static final String[] EMPTY_STRING_ARRAY = new String[0]; 340 341 // How many bytes to write into the dropbox log before truncating 342 static final int DROPBOX_MAX_SIZE = 256 * 1024; 343 344 /** All system services */ 345 SystemServiceManager mSystemServiceManager; 346 347 /** Run all ActivityStacks through this */ 348 ActivityStackSupervisor mStackSupervisor; 349 350 public IntentFirewall mIntentFirewall; 351 352 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 353 // default actuion automatically. Important for devices without direct input 354 // devices. 355 private boolean mShowDialogs = true; 356 357 /** 358 * Description of a request to start a new activity, which has been held 359 * due to app switches being disabled. 360 */ 361 static class PendingActivityLaunch { 362 final ActivityRecord r; 363 final ActivityRecord sourceRecord; 364 final int startFlags; 365 final ActivityStack stack; 366 367 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 368 int _startFlags, ActivityStack _stack) { 369 r = _r; 370 sourceRecord = _sourceRecord; 371 startFlags = _startFlags; 372 stack = _stack; 373 } 374 } 375 376 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 377 = new ArrayList<PendingActivityLaunch>(); 378 379 BroadcastQueue mFgBroadcastQueue; 380 BroadcastQueue mBgBroadcastQueue; 381 // Convenient for easy iteration over the queues. Foreground is first 382 // so that dispatch of foreground broadcasts gets precedence. 383 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 384 385 BroadcastQueue broadcastQueueForIntent(Intent intent) { 386 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 387 if (DEBUG_BACKGROUND_BROADCAST) { 388 Slog.i(TAG, "Broadcast intent " + intent + " on " 389 + (isFg ? "foreground" : "background") 390 + " queue"); 391 } 392 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 393 } 394 395 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 396 for (BroadcastQueue queue : mBroadcastQueues) { 397 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 398 if (r != null) { 399 return r; 400 } 401 } 402 return null; 403 } 404 405 /** 406 * Activity we have told the window manager to have key focus. 407 */ 408 ActivityRecord mFocusedActivity = null; 409 410 /** 411 * List of intents that were used to start the most recent tasks. 412 */ 413 ArrayList<TaskRecord> mRecentTasks; 414 415 public class PendingAssistExtras extends Binder implements Runnable { 416 public final ActivityRecord activity; 417 public boolean haveResult = false; 418 public Bundle result = null; 419 public PendingAssistExtras(ActivityRecord _activity) { 420 activity = _activity; 421 } 422 @Override 423 public void run() { 424 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 425 synchronized (this) { 426 haveResult = true; 427 notifyAll(); 428 } 429 } 430 } 431 432 final ArrayList<PendingAssistExtras> mPendingAssistExtras 433 = new ArrayList<PendingAssistExtras>(); 434 435 /** 436 * Process management. 437 */ 438 final ProcessList mProcessList = new ProcessList(); 439 440 /** 441 * All of the applications we currently have running organized by name. 442 * The keys are strings of the application package name (as 443 * returned by the package manager), and the keys are ApplicationRecord 444 * objects. 445 */ 446 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 447 448 /** 449 * Tracking long-term execution of processes to look for abuse and other 450 * bad app behavior. 451 */ 452 final ProcessStatsService mProcessStats; 453 454 /** 455 * The currently running isolated processes. 456 */ 457 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 458 459 /** 460 * Counter for assigning isolated process uids, to avoid frequently reusing the 461 * same ones. 462 */ 463 int mNextIsolatedProcessUid = 0; 464 465 /** 466 * The currently running heavy-weight process, if any. 467 */ 468 ProcessRecord mHeavyWeightProcess = null; 469 470 /** 471 * The last time that various processes have crashed. 472 */ 473 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 474 475 /** 476 * Information about a process that is currently marked as bad. 477 */ 478 static final class BadProcessInfo { 479 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 480 this.time = time; 481 this.shortMsg = shortMsg; 482 this.longMsg = longMsg; 483 this.stack = stack; 484 } 485 486 final long time; 487 final String shortMsg; 488 final String longMsg; 489 final String stack; 490 } 491 492 /** 493 * Set of applications that we consider to be bad, and will reject 494 * incoming broadcasts from (which the user has no control over). 495 * Processes are added to this set when they have crashed twice within 496 * a minimum amount of time; they are removed from it when they are 497 * later restarted (hopefully due to some user action). The value is the 498 * time it was added to the list. 499 */ 500 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 501 502 /** 503 * All of the processes we currently have running organized by pid. 504 * The keys are the pid running the application. 505 * 506 * <p>NOTE: This object is protected by its own lock, NOT the global 507 * activity manager lock! 508 */ 509 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 510 511 /** 512 * All of the processes that have been forced to be foreground. The key 513 * is the pid of the caller who requested it (we hold a death 514 * link on it). 515 */ 516 abstract class ForegroundToken implements IBinder.DeathRecipient { 517 int pid; 518 IBinder token; 519 } 520 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 521 522 /** 523 * List of records for processes that someone had tried to start before the 524 * system was ready. We don't start them at that point, but ensure they 525 * are started by the time booting is complete. 526 */ 527 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 528 529 /** 530 * List of persistent applications that are in the process 531 * of being started. 532 */ 533 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 534 535 /** 536 * Processes that are being forcibly torn down. 537 */ 538 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 539 540 /** 541 * List of running applications, sorted by recent usage. 542 * The first entry in the list is the least recently used. 543 */ 544 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 545 546 /** 547 * Where in mLruProcesses that the processes hosting activities start. 548 */ 549 int mLruProcessActivityStart = 0; 550 551 /** 552 * Where in mLruProcesses that the processes hosting services start. 553 * This is after (lower index) than mLruProcessesActivityStart. 554 */ 555 int mLruProcessServiceStart = 0; 556 557 /** 558 * List of processes that should gc as soon as things are idle. 559 */ 560 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 561 562 /** 563 * Processes we want to collect PSS data from. 564 */ 565 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 566 567 /** 568 * Last time we requested PSS data of all processes. 569 */ 570 long mLastFullPssTime = SystemClock.uptimeMillis(); 571 572 /** 573 * This is the process holding what we currently consider to be 574 * the "home" activity. 575 */ 576 ProcessRecord mHomeProcess; 577 578 /** 579 * This is the process holding the activity the user last visited that 580 * is in a different process from the one they are currently in. 581 */ 582 ProcessRecord mPreviousProcess; 583 584 /** 585 * The time at which the previous process was last visible. 586 */ 587 long mPreviousProcessVisibleTime; 588 589 /** 590 * Which uses have been started, so are allowed to run code. 591 */ 592 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 593 594 /** 595 * LRU list of history of current users. Most recently current is at the end. 596 */ 597 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 598 599 /** 600 * Constant array of the users that are currently started. 601 */ 602 int[] mStartedUserArray = new int[] { 0 }; 603 604 /** 605 * Registered observers of the user switching mechanics. 606 */ 607 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 608 = new RemoteCallbackList<IUserSwitchObserver>(); 609 610 /** 611 * Currently active user switch. 612 */ 613 Object mCurUserSwitchCallback; 614 615 /** 616 * Packages that the user has asked to have run in screen size 617 * compatibility mode instead of filling the screen. 618 */ 619 final CompatModePackages mCompatModePackages; 620 621 /** 622 * Set of IntentSenderRecord objects that are currently active. 623 */ 624 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 625 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 626 627 /** 628 * Fingerprints (hashCode()) of stack traces that we've 629 * already logged DropBox entries for. Guarded by itself. If 630 * something (rogue user app) forces this over 631 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 632 */ 633 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 634 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 635 636 /** 637 * Strict Mode background batched logging state. 638 * 639 * The string buffer is guarded by itself, and its lock is also 640 * used to determine if another batched write is already 641 * in-flight. 642 */ 643 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 644 645 /** 646 * Keeps track of all IIntentReceivers that have been registered for 647 * broadcasts. Hash keys are the receiver IBinder, hash value is 648 * a ReceiverList. 649 */ 650 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 651 new HashMap<IBinder, ReceiverList>(); 652 653 /** 654 * Resolver for broadcast intents to registered receivers. 655 * Holds BroadcastFilter (subclass of IntentFilter). 656 */ 657 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 658 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 659 @Override 660 protected boolean allowFilterResult( 661 BroadcastFilter filter, List<BroadcastFilter> dest) { 662 IBinder target = filter.receiverList.receiver.asBinder(); 663 for (int i=dest.size()-1; i>=0; i--) { 664 if (dest.get(i).receiverList.receiver.asBinder() == target) { 665 return false; 666 } 667 } 668 return true; 669 } 670 671 @Override 672 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 673 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 674 || userId == filter.owningUserId) { 675 return super.newResult(filter, match, userId); 676 } 677 return null; 678 } 679 680 @Override 681 protected BroadcastFilter[] newArray(int size) { 682 return new BroadcastFilter[size]; 683 } 684 685 @Override 686 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 687 return packageName.equals(filter.packageName); 688 } 689 }; 690 691 /** 692 * State of all active sticky broadcasts per user. Keys are the action of the 693 * sticky Intent, values are an ArrayList of all broadcasted intents with 694 * that action (which should usually be one). The SparseArray is keyed 695 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 696 * for stickies that are sent to all users. 697 */ 698 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 699 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 700 701 final ActiveServices mServices; 702 703 /** 704 * Backup/restore process management 705 */ 706 String mBackupAppName = null; 707 BackupRecord mBackupTarget = null; 708 709 final ProviderMap mProviderMap; 710 711 /** 712 * List of content providers who have clients waiting for them. The 713 * application is currently being launched and the provider will be 714 * removed from this list once it is published. 715 */ 716 final ArrayList<ContentProviderRecord> mLaunchingProviders 717 = new ArrayList<ContentProviderRecord>(); 718 719 /** 720 * File storing persisted {@link #mGrantedUriPermissions}. 721 */ 722 private final AtomicFile mGrantFile; 723 724 /** XML constants used in {@link #mGrantFile} */ 725 private static final String TAG_URI_GRANTS = "uri-grants"; 726 private static final String TAG_URI_GRANT = "uri-grant"; 727 private static final String ATTR_USER_HANDLE = "userHandle"; 728 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 729 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 730 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 731 private static final String ATTR_TARGET_PKG = "targetPkg"; 732 private static final String ATTR_URI = "uri"; 733 private static final String ATTR_MODE_FLAGS = "modeFlags"; 734 private static final String ATTR_CREATED_TIME = "createdTime"; 735 private static final String ATTR_PREFIX = "prefix"; 736 737 /** 738 * Global set of specific {@link Uri} permissions that have been granted. 739 * This optimized lookup structure maps from {@link UriPermission#targetUid} 740 * to {@link UriPermission#uri} to {@link UriPermission}. 741 */ 742 @GuardedBy("this") 743 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 744 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 745 746 public static class GrantUri { 747 public final int sourceUserId; 748 public final Uri uri; 749 public boolean prefix; 750 751 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 752 this.sourceUserId = sourceUserId; 753 this.uri = uri; 754 this.prefix = prefix; 755 } 756 757 @Override 758 public int hashCode() { 759 return toString().hashCode(); 760 } 761 762 @Override 763 public boolean equals(Object o) { 764 if (o instanceof GrantUri) { 765 GrantUri other = (GrantUri) o; 766 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 767 && prefix == other.prefix; 768 } 769 return false; 770 } 771 772 @Override 773 public String toString() { 774 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 775 if (prefix) result += " [prefix]"; 776 return result; 777 } 778 779 public String toSafeString() { 780 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 781 if (prefix) result += " [prefix]"; 782 return result; 783 } 784 785 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 786 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 787 ContentProvider.getUriWithoutUserId(uri), false); 788 } 789 } 790 791 CoreSettingsObserver mCoreSettingsObserver; 792 793 /** 794 * Thread-local storage used to carry caller permissions over through 795 * indirect content-provider access. 796 */ 797 private class Identity { 798 public int pid; 799 public int uid; 800 801 Identity(int _pid, int _uid) { 802 pid = _pid; 803 uid = _uid; 804 } 805 } 806 807 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 808 809 /** 810 * All information we have collected about the runtime performance of 811 * any user id that can impact battery performance. 812 */ 813 final BatteryStatsService mBatteryStatsService; 814 815 /** 816 * Information about component usage 817 */ 818 final UsageStatsService mUsageStatsService; 819 820 /** 821 * Information about and control over application operations 822 */ 823 final AppOpsService mAppOpsService; 824 825 /** 826 * Save recent tasks information across reboots. 827 */ 828 final TaskPersister mTaskPersister; 829 830 /** 831 * Current configuration information. HistoryRecord objects are given 832 * a reference to this object to indicate which configuration they are 833 * currently running in, so this object must be kept immutable. 834 */ 835 Configuration mConfiguration = new Configuration(); 836 837 /** 838 * Current sequencing integer of the configuration, for skipping old 839 * configurations. 840 */ 841 int mConfigurationSeq = 0; 842 843 /** 844 * Hardware-reported OpenGLES version. 845 */ 846 final int GL_ES_VERSION; 847 848 /** 849 * List of initialization arguments to pass to all processes when binding applications to them. 850 * For example, references to the commonly used services. 851 */ 852 HashMap<String, IBinder> mAppBindArgs; 853 854 /** 855 * Temporary to avoid allocations. Protected by main lock. 856 */ 857 final StringBuilder mStringBuilder = new StringBuilder(256); 858 859 /** 860 * Used to control how we initialize the service. 861 */ 862 ComponentName mTopComponent; 863 String mTopAction = Intent.ACTION_MAIN; 864 String mTopData; 865 boolean mProcessesReady = false; 866 boolean mSystemReady = false; 867 boolean mBooting = false; 868 boolean mWaitingUpdate = false; 869 boolean mDidUpdate = false; 870 boolean mOnBattery = false; 871 boolean mLaunchWarningShown = false; 872 873 Context mContext; 874 875 int mFactoryTest; 876 877 boolean mCheckedForSetup; 878 879 /** 880 * The time at which we will allow normal application switches again, 881 * after a call to {@link #stopAppSwitches()}. 882 */ 883 long mAppSwitchesAllowedTime; 884 885 /** 886 * This is set to true after the first switch after mAppSwitchesAllowedTime 887 * is set; any switches after that will clear the time. 888 */ 889 boolean mDidAppSwitch; 890 891 /** 892 * Last time (in realtime) at which we checked for power usage. 893 */ 894 long mLastPowerCheckRealtime; 895 896 /** 897 * Last time (in uptime) at which we checked for power usage. 898 */ 899 long mLastPowerCheckUptime; 900 901 /** 902 * Set while we are wanting to sleep, to prevent any 903 * activities from being started/resumed. 904 */ 905 private boolean mSleeping = false; 906 907 /** 908 * Set while we are running a voice interaction. This overrides 909 * sleeping while it is active. 910 */ 911 private boolean mRunningVoice = false; 912 913 /** 914 * State of external calls telling us if the device is asleep. 915 */ 916 private boolean mWentToSleep = false; 917 918 /** 919 * State of external call telling us if the lock screen is shown. 920 */ 921 private boolean mLockScreenShown = false; 922 923 /** 924 * Set if we are shutting down the system, similar to sleeping. 925 */ 926 boolean mShuttingDown = false; 927 928 /** 929 * Current sequence id for oom_adj computation traversal. 930 */ 931 int mAdjSeq = 0; 932 933 /** 934 * Current sequence id for process LRU updating. 935 */ 936 int mLruSeq = 0; 937 938 /** 939 * Keep track of the non-cached/empty process we last found, to help 940 * determine how to distribute cached/empty processes next time. 941 */ 942 int mNumNonCachedProcs = 0; 943 944 /** 945 * Keep track of the number of cached hidden procs, to balance oom adj 946 * distribution between those and empty procs. 947 */ 948 int mNumCachedHiddenProcs = 0; 949 950 /** 951 * Keep track of the number of service processes we last found, to 952 * determine on the next iteration which should be B services. 953 */ 954 int mNumServiceProcs = 0; 955 int mNewNumAServiceProcs = 0; 956 int mNewNumServiceProcs = 0; 957 958 /** 959 * Allow the current computed overall memory level of the system to go down? 960 * This is set to false when we are killing processes for reasons other than 961 * memory management, so that the now smaller process list will not be taken as 962 * an indication that memory is tighter. 963 */ 964 boolean mAllowLowerMemLevel = false; 965 966 /** 967 * The last computed memory level, for holding when we are in a state that 968 * processes are going away for other reasons. 969 */ 970 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 971 972 /** 973 * The last total number of process we have, to determine if changes actually look 974 * like a shrinking number of process due to lower RAM. 975 */ 976 int mLastNumProcesses; 977 978 /** 979 * The uptime of the last time we performed idle maintenance. 980 */ 981 long mLastIdleTime = SystemClock.uptimeMillis(); 982 983 /** 984 * Total time spent with RAM that has been added in the past since the last idle time. 985 */ 986 long mLowRamTimeSinceLastIdle = 0; 987 988 /** 989 * If RAM is currently low, when that horrible situation started. 990 */ 991 long mLowRamStartTime = 0; 992 993 /** 994 * For reporting to battery stats the current top application. 995 */ 996 private String mCurResumedPackage = null; 997 private int mCurResumedUid = -1; 998 999 /** 1000 * For reporting to battery stats the apps currently running foreground 1001 * service. The ProcessMap is package/uid tuples; each of these contain 1002 * an array of the currently foreground processes. 1003 */ 1004 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1005 = new ProcessMap<ArrayList<ProcessRecord>>(); 1006 1007 /** 1008 * This is set if we had to do a delayed dexopt of an app before launching 1009 * it, to increase the ANR timeouts in that case. 1010 */ 1011 boolean mDidDexOpt; 1012 1013 /** 1014 * Set if the systemServer made a call to enterSafeMode. 1015 */ 1016 boolean mSafeMode; 1017 1018 String mDebugApp = null; 1019 boolean mWaitForDebugger = false; 1020 boolean mDebugTransient = false; 1021 String mOrigDebugApp = null; 1022 boolean mOrigWaitForDebugger = false; 1023 boolean mAlwaysFinishActivities = false; 1024 IActivityController mController = null; 1025 String mProfileApp = null; 1026 ProcessRecord mProfileProc = null; 1027 String mProfileFile; 1028 ParcelFileDescriptor mProfileFd; 1029 int mProfileType = 0; 1030 boolean mAutoStopProfiler = false; 1031 String mOpenGlTraceApp = null; 1032 1033 static class ProcessChangeItem { 1034 static final int CHANGE_ACTIVITIES = 1<<0; 1035 static final int CHANGE_PROCESS_STATE = 1<<1; 1036 int changes; 1037 int uid; 1038 int pid; 1039 int processState; 1040 boolean foregroundActivities; 1041 } 1042 1043 final RemoteCallbackList<IProcessObserver> mProcessObservers 1044 = new RemoteCallbackList<IProcessObserver>(); 1045 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1046 1047 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1048 = new ArrayList<ProcessChangeItem>(); 1049 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1050 = new ArrayList<ProcessChangeItem>(); 1051 1052 /** 1053 * Runtime CPU use collection thread. This object's lock is used to 1054 * protect all related state. 1055 */ 1056 final Thread mProcessCpuThread; 1057 1058 /** 1059 * Used to collect process stats when showing not responding dialog. 1060 * Protected by mProcessCpuThread. 1061 */ 1062 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1063 MONITOR_THREAD_CPU_USAGE); 1064 final AtomicLong mLastCpuTime = new AtomicLong(0); 1065 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1066 1067 long mLastWriteTime = 0; 1068 1069 /** 1070 * Used to retain an update lock when the foreground activity is in 1071 * immersive mode. 1072 */ 1073 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1074 1075 /** 1076 * Set to true after the system has finished booting. 1077 */ 1078 boolean mBooted = false; 1079 1080 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1081 int mProcessLimitOverride = -1; 1082 1083 WindowManagerService mWindowManager; 1084 1085 final ActivityThread mSystemThread; 1086 1087 int mCurrentUserId = 0; 1088 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1089 private UserManagerService mUserManager; 1090 1091 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1092 final ProcessRecord mApp; 1093 final int mPid; 1094 final IApplicationThread mAppThread; 1095 1096 AppDeathRecipient(ProcessRecord app, int pid, 1097 IApplicationThread thread) { 1098 if (localLOGV) Slog.v( 1099 TAG, "New death recipient " + this 1100 + " for thread " + thread.asBinder()); 1101 mApp = app; 1102 mPid = pid; 1103 mAppThread = thread; 1104 } 1105 1106 @Override 1107 public void binderDied() { 1108 if (localLOGV) Slog.v( 1109 TAG, "Death received in " + this 1110 + " for thread " + mAppThread.asBinder()); 1111 synchronized(ActivityManagerService.this) { 1112 appDiedLocked(mApp, mPid, mAppThread); 1113 } 1114 } 1115 } 1116 1117 static final int SHOW_ERROR_MSG = 1; 1118 static final int SHOW_NOT_RESPONDING_MSG = 2; 1119 static final int SHOW_FACTORY_ERROR_MSG = 3; 1120 static final int UPDATE_CONFIGURATION_MSG = 4; 1121 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1122 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1123 static final int SERVICE_TIMEOUT_MSG = 12; 1124 static final int UPDATE_TIME_ZONE = 13; 1125 static final int SHOW_UID_ERROR_MSG = 14; 1126 static final int IM_FEELING_LUCKY_MSG = 15; 1127 static final int PROC_START_TIMEOUT_MSG = 20; 1128 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1129 static final int KILL_APPLICATION_MSG = 22; 1130 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1131 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1132 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1133 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1134 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1135 static final int CLEAR_DNS_CACHE_MSG = 28; 1136 static final int UPDATE_HTTP_PROXY_MSG = 29; 1137 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1138 static final int DISPATCH_PROCESSES_CHANGED = 31; 1139 static final int DISPATCH_PROCESS_DIED = 32; 1140 static final int REPORT_MEM_USAGE_MSG = 33; 1141 static final int REPORT_USER_SWITCH_MSG = 34; 1142 static final int CONTINUE_USER_SWITCH_MSG = 35; 1143 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1144 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1145 static final int PERSIST_URI_GRANTS_MSG = 38; 1146 static final int REQUEST_ALL_PSS_MSG = 39; 1147 static final int START_PROFILES_MSG = 40; 1148 static final int UPDATE_TIME = 41; 1149 static final int SYSTEM_USER_START_MSG = 42; 1150 static final int SYSTEM_USER_CURRENT_MSG = 43; 1151 1152 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1153 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1154 static final int FIRST_COMPAT_MODE_MSG = 300; 1155 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1156 1157 AlertDialog mUidAlert; 1158 CompatModeDialog mCompatModeDialog; 1159 long mLastMemUsageReportTime = 0; 1160 1161 /** 1162 * Flag whether the current user is a "monkey", i.e. whether 1163 * the UI is driven by a UI automation tool. 1164 */ 1165 private boolean mUserIsMonkey; 1166 1167 final ServiceThread mHandlerThread; 1168 final MainHandler mHandler; 1169 1170 final class MainHandler extends Handler { 1171 public MainHandler(Looper looper) { 1172 super(looper, null, true); 1173 } 1174 1175 @Override 1176 public void handleMessage(Message msg) { 1177 switch (msg.what) { 1178 case SHOW_ERROR_MSG: { 1179 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1180 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1181 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1182 synchronized (ActivityManagerService.this) { 1183 ProcessRecord proc = (ProcessRecord)data.get("app"); 1184 AppErrorResult res = (AppErrorResult) data.get("result"); 1185 if (proc != null && proc.crashDialog != null) { 1186 Slog.e(TAG, "App already has crash dialog: " + proc); 1187 if (res != null) { 1188 res.set(0); 1189 } 1190 return; 1191 } 1192 if (!showBackground && UserHandle.getAppId(proc.uid) 1193 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1194 && proc.pid != MY_PID) { 1195 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1196 if (res != null) { 1197 res.set(0); 1198 } 1199 return; 1200 } 1201 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1202 Dialog d = new AppErrorDialog(mContext, 1203 ActivityManagerService.this, res, proc); 1204 d.show(); 1205 proc.crashDialog = d; 1206 } else { 1207 // The device is asleep, so just pretend that the user 1208 // saw a crash dialog and hit "force quit". 1209 if (res != null) { 1210 res.set(0); 1211 } 1212 } 1213 } 1214 1215 ensureBootCompleted(); 1216 } break; 1217 case SHOW_NOT_RESPONDING_MSG: { 1218 synchronized (ActivityManagerService.this) { 1219 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1220 ProcessRecord proc = (ProcessRecord)data.get("app"); 1221 if (proc != null && proc.anrDialog != null) { 1222 Slog.e(TAG, "App already has anr dialog: " + proc); 1223 return; 1224 } 1225 1226 Intent intent = new Intent("android.intent.action.ANR"); 1227 if (!mProcessesReady) { 1228 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1229 | Intent.FLAG_RECEIVER_FOREGROUND); 1230 } 1231 broadcastIntentLocked(null, null, intent, 1232 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1233 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1234 1235 if (mShowDialogs) { 1236 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1237 mContext, proc, (ActivityRecord)data.get("activity"), 1238 msg.arg1 != 0); 1239 d.show(); 1240 proc.anrDialog = d; 1241 } else { 1242 // Just kill the app if there is no dialog to be shown. 1243 killAppAtUsersRequest(proc, null); 1244 } 1245 } 1246 1247 ensureBootCompleted(); 1248 } break; 1249 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1250 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1251 synchronized (ActivityManagerService.this) { 1252 ProcessRecord proc = (ProcessRecord) data.get("app"); 1253 if (proc == null) { 1254 Slog.e(TAG, "App not found when showing strict mode dialog."); 1255 break; 1256 } 1257 if (proc.crashDialog != null) { 1258 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1259 return; 1260 } 1261 AppErrorResult res = (AppErrorResult) data.get("result"); 1262 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1263 Dialog d = new StrictModeViolationDialog(mContext, 1264 ActivityManagerService.this, res, proc); 1265 d.show(); 1266 proc.crashDialog = d; 1267 } else { 1268 // The device is asleep, so just pretend that the user 1269 // saw a crash dialog and hit "force quit". 1270 res.set(0); 1271 } 1272 } 1273 ensureBootCompleted(); 1274 } break; 1275 case SHOW_FACTORY_ERROR_MSG: { 1276 Dialog d = new FactoryErrorDialog( 1277 mContext, msg.getData().getCharSequence("msg")); 1278 d.show(); 1279 ensureBootCompleted(); 1280 } break; 1281 case UPDATE_CONFIGURATION_MSG: { 1282 final ContentResolver resolver = mContext.getContentResolver(); 1283 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1284 } break; 1285 case GC_BACKGROUND_PROCESSES_MSG: { 1286 synchronized (ActivityManagerService.this) { 1287 performAppGcsIfAppropriateLocked(); 1288 } 1289 } break; 1290 case WAIT_FOR_DEBUGGER_MSG: { 1291 synchronized (ActivityManagerService.this) { 1292 ProcessRecord app = (ProcessRecord)msg.obj; 1293 if (msg.arg1 != 0) { 1294 if (!app.waitedForDebugger) { 1295 Dialog d = new AppWaitingForDebuggerDialog( 1296 ActivityManagerService.this, 1297 mContext, app); 1298 app.waitDialog = d; 1299 app.waitedForDebugger = true; 1300 d.show(); 1301 } 1302 } else { 1303 if (app.waitDialog != null) { 1304 app.waitDialog.dismiss(); 1305 app.waitDialog = null; 1306 } 1307 } 1308 } 1309 } break; 1310 case SERVICE_TIMEOUT_MSG: { 1311 if (mDidDexOpt) { 1312 mDidDexOpt = false; 1313 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1314 nmsg.obj = msg.obj; 1315 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1316 return; 1317 } 1318 mServices.serviceTimeout((ProcessRecord)msg.obj); 1319 } break; 1320 case UPDATE_TIME_ZONE: { 1321 synchronized (ActivityManagerService.this) { 1322 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1323 ProcessRecord r = mLruProcesses.get(i); 1324 if (r.thread != null) { 1325 try { 1326 r.thread.updateTimeZone(); 1327 } catch (RemoteException ex) { 1328 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1329 } 1330 } 1331 } 1332 } 1333 } break; 1334 case CLEAR_DNS_CACHE_MSG: { 1335 synchronized (ActivityManagerService.this) { 1336 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1337 ProcessRecord r = mLruProcesses.get(i); 1338 if (r.thread != null) { 1339 try { 1340 r.thread.clearDnsCache(); 1341 } catch (RemoteException ex) { 1342 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1343 } 1344 } 1345 } 1346 } 1347 } break; 1348 case UPDATE_HTTP_PROXY_MSG: { 1349 ProxyInfo proxy = (ProxyInfo)msg.obj; 1350 String host = ""; 1351 String port = ""; 1352 String exclList = ""; 1353 Uri pacFileUrl = Uri.EMPTY; 1354 if (proxy != null) { 1355 host = proxy.getHost(); 1356 port = Integer.toString(proxy.getPort()); 1357 exclList = proxy.getExclusionListAsString(); 1358 pacFileUrl = proxy.getPacFileUrl(); 1359 } 1360 synchronized (ActivityManagerService.this) { 1361 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1362 ProcessRecord r = mLruProcesses.get(i); 1363 if (r.thread != null) { 1364 try { 1365 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1366 } catch (RemoteException ex) { 1367 Slog.w(TAG, "Failed to update http proxy for: " + 1368 r.info.processName); 1369 } 1370 } 1371 } 1372 } 1373 } break; 1374 case SHOW_UID_ERROR_MSG: { 1375 String title = "System UIDs Inconsistent"; 1376 String text = "UIDs on the system are inconsistent, you need to wipe your" 1377 + " data partition or your device will be unstable."; 1378 Log.e(TAG, title + ": " + text); 1379 if (mShowDialogs) { 1380 // XXX This is a temporary dialog, no need to localize. 1381 AlertDialog d = new BaseErrorDialog(mContext); 1382 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1383 d.setCancelable(false); 1384 d.setTitle(title); 1385 d.setMessage(text); 1386 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1387 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1388 mUidAlert = d; 1389 d.show(); 1390 } 1391 } break; 1392 case IM_FEELING_LUCKY_MSG: { 1393 if (mUidAlert != null) { 1394 mUidAlert.dismiss(); 1395 mUidAlert = null; 1396 } 1397 } break; 1398 case PROC_START_TIMEOUT_MSG: { 1399 if (mDidDexOpt) { 1400 mDidDexOpt = false; 1401 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1402 nmsg.obj = msg.obj; 1403 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1404 return; 1405 } 1406 ProcessRecord app = (ProcessRecord)msg.obj; 1407 synchronized (ActivityManagerService.this) { 1408 processStartTimedOutLocked(app); 1409 } 1410 } break; 1411 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1412 synchronized (ActivityManagerService.this) { 1413 doPendingActivityLaunchesLocked(true); 1414 } 1415 } break; 1416 case KILL_APPLICATION_MSG: { 1417 synchronized (ActivityManagerService.this) { 1418 int appid = msg.arg1; 1419 boolean restart = (msg.arg2 == 1); 1420 Bundle bundle = (Bundle)msg.obj; 1421 String pkg = bundle.getString("pkg"); 1422 String reason = bundle.getString("reason"); 1423 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1424 false, UserHandle.USER_ALL, reason); 1425 } 1426 } break; 1427 case FINALIZE_PENDING_INTENT_MSG: { 1428 ((PendingIntentRecord)msg.obj).completeFinalize(); 1429 } break; 1430 case POST_HEAVY_NOTIFICATION_MSG: { 1431 INotificationManager inm = NotificationManager.getService(); 1432 if (inm == null) { 1433 return; 1434 } 1435 1436 ActivityRecord root = (ActivityRecord)msg.obj; 1437 ProcessRecord process = root.app; 1438 if (process == null) { 1439 return; 1440 } 1441 1442 try { 1443 Context context = mContext.createPackageContext(process.info.packageName, 0); 1444 String text = mContext.getString(R.string.heavy_weight_notification, 1445 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1446 Notification notification = new Notification(); 1447 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1448 notification.when = 0; 1449 notification.flags = Notification.FLAG_ONGOING_EVENT; 1450 notification.tickerText = text; 1451 notification.defaults = 0; // please be quiet 1452 notification.sound = null; 1453 notification.vibrate = null; 1454 notification.setLatestEventInfo(context, text, 1455 mContext.getText(R.string.heavy_weight_notification_detail), 1456 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1457 PendingIntent.FLAG_CANCEL_CURRENT, null, 1458 new UserHandle(root.userId))); 1459 1460 try { 1461 int[] outId = new int[1]; 1462 inm.enqueueNotificationWithTag("android", "android", null, 1463 R.string.heavy_weight_notification, 1464 notification, outId, root.userId); 1465 } catch (RuntimeException e) { 1466 Slog.w(ActivityManagerService.TAG, 1467 "Error showing notification for heavy-weight app", e); 1468 } catch (RemoteException e) { 1469 } 1470 } catch (NameNotFoundException e) { 1471 Slog.w(TAG, "Unable to create context for heavy notification", e); 1472 } 1473 } break; 1474 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1475 INotificationManager inm = NotificationManager.getService(); 1476 if (inm == null) { 1477 return; 1478 } 1479 try { 1480 inm.cancelNotificationWithTag("android", null, 1481 R.string.heavy_weight_notification, msg.arg1); 1482 } catch (RuntimeException e) { 1483 Slog.w(ActivityManagerService.TAG, 1484 "Error canceling notification for service", e); 1485 } catch (RemoteException e) { 1486 } 1487 } break; 1488 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1489 synchronized (ActivityManagerService.this) { 1490 checkExcessivePowerUsageLocked(true); 1491 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1492 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1493 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1494 } 1495 } break; 1496 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1497 synchronized (ActivityManagerService.this) { 1498 ActivityRecord ar = (ActivityRecord)msg.obj; 1499 if (mCompatModeDialog != null) { 1500 if (mCompatModeDialog.mAppInfo.packageName.equals( 1501 ar.info.applicationInfo.packageName)) { 1502 return; 1503 } 1504 mCompatModeDialog.dismiss(); 1505 mCompatModeDialog = null; 1506 } 1507 if (ar != null && false) { 1508 if (mCompatModePackages.getPackageAskCompatModeLocked( 1509 ar.packageName)) { 1510 int mode = mCompatModePackages.computeCompatModeLocked( 1511 ar.info.applicationInfo); 1512 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1513 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1514 mCompatModeDialog = new CompatModeDialog( 1515 ActivityManagerService.this, mContext, 1516 ar.info.applicationInfo); 1517 mCompatModeDialog.show(); 1518 } 1519 } 1520 } 1521 } 1522 break; 1523 } 1524 case DISPATCH_PROCESSES_CHANGED: { 1525 dispatchProcessesChanged(); 1526 break; 1527 } 1528 case DISPATCH_PROCESS_DIED: { 1529 final int pid = msg.arg1; 1530 final int uid = msg.arg2; 1531 dispatchProcessDied(pid, uid); 1532 break; 1533 } 1534 case REPORT_MEM_USAGE_MSG: { 1535 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1536 Thread thread = new Thread() { 1537 @Override public void run() { 1538 final SparseArray<ProcessMemInfo> infoMap 1539 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1540 for (int i=0, N=memInfos.size(); i<N; i++) { 1541 ProcessMemInfo mi = memInfos.get(i); 1542 infoMap.put(mi.pid, mi); 1543 } 1544 updateCpuStatsNow(); 1545 synchronized (mProcessCpuThread) { 1546 final int N = mProcessCpuTracker.countStats(); 1547 for (int i=0; i<N; i++) { 1548 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1549 if (st.vsize > 0) { 1550 long pss = Debug.getPss(st.pid, null); 1551 if (pss > 0) { 1552 if (infoMap.indexOfKey(st.pid) < 0) { 1553 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1554 ProcessList.NATIVE_ADJ, -1, "native", null); 1555 mi.pss = pss; 1556 memInfos.add(mi); 1557 } 1558 } 1559 } 1560 } 1561 } 1562 1563 long totalPss = 0; 1564 for (int i=0, N=memInfos.size(); i<N; i++) { 1565 ProcessMemInfo mi = memInfos.get(i); 1566 if (mi.pss == 0) { 1567 mi.pss = Debug.getPss(mi.pid, null); 1568 } 1569 totalPss += mi.pss; 1570 } 1571 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1572 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1573 if (lhs.oomAdj != rhs.oomAdj) { 1574 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1575 } 1576 if (lhs.pss != rhs.pss) { 1577 return lhs.pss < rhs.pss ? 1 : -1; 1578 } 1579 return 0; 1580 } 1581 }); 1582 1583 StringBuilder tag = new StringBuilder(128); 1584 StringBuilder stack = new StringBuilder(128); 1585 tag.append("Low on memory -- "); 1586 appendMemBucket(tag, totalPss, "total", false); 1587 appendMemBucket(stack, totalPss, "total", true); 1588 1589 StringBuilder logBuilder = new StringBuilder(1024); 1590 logBuilder.append("Low on memory:\n"); 1591 1592 boolean firstLine = true; 1593 int lastOomAdj = Integer.MIN_VALUE; 1594 for (int i=0, N=memInfos.size(); i<N; i++) { 1595 ProcessMemInfo mi = memInfos.get(i); 1596 1597 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1598 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1599 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1600 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1601 if (lastOomAdj != mi.oomAdj) { 1602 lastOomAdj = mi.oomAdj; 1603 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1604 tag.append(" / "); 1605 } 1606 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1607 if (firstLine) { 1608 stack.append(":"); 1609 firstLine = false; 1610 } 1611 stack.append("\n\t at "); 1612 } else { 1613 stack.append("$"); 1614 } 1615 } else { 1616 tag.append(" "); 1617 stack.append("$"); 1618 } 1619 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1620 appendMemBucket(tag, mi.pss, mi.name, false); 1621 } 1622 appendMemBucket(stack, mi.pss, mi.name, true); 1623 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1624 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1625 stack.append("("); 1626 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1627 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1628 stack.append(DUMP_MEM_OOM_LABEL[k]); 1629 stack.append(":"); 1630 stack.append(DUMP_MEM_OOM_ADJ[k]); 1631 } 1632 } 1633 stack.append(")"); 1634 } 1635 } 1636 1637 logBuilder.append(" "); 1638 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1639 logBuilder.append(' '); 1640 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1641 logBuilder.append(' '); 1642 ProcessList.appendRamKb(logBuilder, mi.pss); 1643 logBuilder.append(" kB: "); 1644 logBuilder.append(mi.name); 1645 logBuilder.append(" ("); 1646 logBuilder.append(mi.pid); 1647 logBuilder.append(") "); 1648 logBuilder.append(mi.adjType); 1649 logBuilder.append('\n'); 1650 if (mi.adjReason != null) { 1651 logBuilder.append(" "); 1652 logBuilder.append(mi.adjReason); 1653 logBuilder.append('\n'); 1654 } 1655 } 1656 1657 logBuilder.append(" "); 1658 ProcessList.appendRamKb(logBuilder, totalPss); 1659 logBuilder.append(" kB: TOTAL\n"); 1660 1661 long[] infos = new long[Debug.MEMINFO_COUNT]; 1662 Debug.getMemInfo(infos); 1663 logBuilder.append(" MemInfo: "); 1664 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1665 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1666 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1667 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1668 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1669 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1670 logBuilder.append(" ZRAM: "); 1671 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1672 logBuilder.append(" kB RAM, "); 1673 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1674 logBuilder.append(" kB swap total, "); 1675 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1676 logBuilder.append(" kB swap free\n"); 1677 } 1678 Slog.i(TAG, logBuilder.toString()); 1679 1680 StringBuilder dropBuilder = new StringBuilder(1024); 1681 /* 1682 StringWriter oomSw = new StringWriter(); 1683 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1684 StringWriter catSw = new StringWriter(); 1685 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1686 String[] emptyArgs = new String[] { }; 1687 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1688 oomPw.flush(); 1689 String oomString = oomSw.toString(); 1690 */ 1691 dropBuilder.append(stack); 1692 dropBuilder.append('\n'); 1693 dropBuilder.append('\n'); 1694 dropBuilder.append(logBuilder); 1695 dropBuilder.append('\n'); 1696 /* 1697 dropBuilder.append(oomString); 1698 dropBuilder.append('\n'); 1699 */ 1700 StringWriter catSw = new StringWriter(); 1701 synchronized (ActivityManagerService.this) { 1702 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1703 String[] emptyArgs = new String[] { }; 1704 catPw.println(); 1705 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1706 catPw.println(); 1707 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1708 false, false, null); 1709 catPw.println(); 1710 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1711 catPw.flush(); 1712 } 1713 dropBuilder.append(catSw.toString()); 1714 addErrorToDropBox("lowmem", null, "system_server", null, 1715 null, tag.toString(), dropBuilder.toString(), null, null); 1716 //Slog.i(TAG, "Sent to dropbox:"); 1717 //Slog.i(TAG, dropBuilder.toString()); 1718 synchronized (ActivityManagerService.this) { 1719 long now = SystemClock.uptimeMillis(); 1720 if (mLastMemUsageReportTime < now) { 1721 mLastMemUsageReportTime = now; 1722 } 1723 } 1724 } 1725 }; 1726 thread.start(); 1727 break; 1728 } 1729 case REPORT_USER_SWITCH_MSG: { 1730 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1731 break; 1732 } 1733 case CONTINUE_USER_SWITCH_MSG: { 1734 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1735 break; 1736 } 1737 case USER_SWITCH_TIMEOUT_MSG: { 1738 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1739 break; 1740 } 1741 case IMMERSIVE_MODE_LOCK_MSG: { 1742 final boolean nextState = (msg.arg1 != 0); 1743 if (mUpdateLock.isHeld() != nextState) { 1744 if (DEBUG_IMMERSIVE) { 1745 final ActivityRecord r = (ActivityRecord) msg.obj; 1746 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1747 } 1748 if (nextState) { 1749 mUpdateLock.acquire(); 1750 } else { 1751 mUpdateLock.release(); 1752 } 1753 } 1754 break; 1755 } 1756 case PERSIST_URI_GRANTS_MSG: { 1757 writeGrantedUriPermissions(); 1758 break; 1759 } 1760 case REQUEST_ALL_PSS_MSG: { 1761 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1762 break; 1763 } 1764 case START_PROFILES_MSG: { 1765 synchronized (ActivityManagerService.this) { 1766 startProfilesLocked(); 1767 } 1768 break; 1769 } 1770 case UPDATE_TIME: { 1771 synchronized (ActivityManagerService.this) { 1772 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1773 ProcessRecord r = mLruProcesses.get(i); 1774 if (r.thread != null) { 1775 try { 1776 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1777 } catch (RemoteException ex) { 1778 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1779 } 1780 } 1781 } 1782 } 1783 break; 1784 } 1785 case SYSTEM_USER_START_MSG: { 1786 mSystemServiceManager.startUser(msg.arg1); 1787 break; 1788 } 1789 case SYSTEM_USER_CURRENT_MSG: { 1790 mSystemServiceManager.switchUser(msg.arg1); 1791 break; 1792 } 1793 } 1794 } 1795 }; 1796 1797 static final int COLLECT_PSS_BG_MSG = 1; 1798 1799 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1800 @Override 1801 public void handleMessage(Message msg) { 1802 switch (msg.what) { 1803 case COLLECT_PSS_BG_MSG: { 1804 int i=0, num=0; 1805 long start = SystemClock.uptimeMillis(); 1806 long[] tmp = new long[1]; 1807 do { 1808 ProcessRecord proc; 1809 int procState; 1810 int pid; 1811 synchronized (ActivityManagerService.this) { 1812 if (i >= mPendingPssProcesses.size()) { 1813 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1814 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1815 mPendingPssProcesses.clear(); 1816 return; 1817 } 1818 proc = mPendingPssProcesses.get(i); 1819 procState = proc.pssProcState; 1820 if (proc.thread != null && procState == proc.setProcState) { 1821 pid = proc.pid; 1822 } else { 1823 proc = null; 1824 pid = 0; 1825 } 1826 i++; 1827 } 1828 if (proc != null) { 1829 long pss = Debug.getPss(pid, tmp); 1830 synchronized (ActivityManagerService.this) { 1831 if (proc.thread != null && proc.setProcState == procState 1832 && proc.pid == pid) { 1833 num++; 1834 proc.lastPssTime = SystemClock.uptimeMillis(); 1835 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1836 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1837 + ": " + pss + " lastPss=" + proc.lastPss 1838 + " state=" + ProcessList.makeProcStateString(procState)); 1839 if (proc.initialIdlePss == 0) { 1840 proc.initialIdlePss = pss; 1841 } 1842 proc.lastPss = pss; 1843 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1844 proc.lastCachedPss = pss; 1845 } 1846 } 1847 } 1848 } 1849 } while (true); 1850 } 1851 } 1852 } 1853 }; 1854 1855 /** 1856 * Monitor for package changes and update our internal state. 1857 */ 1858 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1859 @Override 1860 public void onPackageRemoved(String packageName, int uid) { 1861 // Remove all tasks with activities in the specified package from the list of recent tasks 1862 synchronized (ActivityManagerService.this) { 1863 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1864 TaskRecord tr = mRecentTasks.get(i); 1865 ComponentName cn = tr.intent.getComponent(); 1866 if (cn != null && cn.getPackageName().equals(packageName)) { 1867 // If the package name matches, remove the task and kill the process 1868 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1869 } 1870 } 1871 } 1872 } 1873 1874 @Override 1875 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1876 onPackageModified(packageName); 1877 return true; 1878 } 1879 1880 @Override 1881 public void onPackageModified(String packageName) { 1882 final PackageManager pm = mContext.getPackageManager(); 1883 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1884 new ArrayList<Pair<Intent, Integer>>(); 1885 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1886 // Copy the list of recent tasks so that we don't hold onto the lock on 1887 // ActivityManagerService for long periods while checking if components exist. 1888 synchronized (ActivityManagerService.this) { 1889 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1890 TaskRecord tr = mRecentTasks.get(i); 1891 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1892 } 1893 } 1894 // Check the recent tasks and filter out all tasks with components that no longer exist. 1895 Intent tmpI = new Intent(); 1896 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1897 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1898 ComponentName cn = p.first.getComponent(); 1899 if (cn != null && cn.getPackageName().equals(packageName)) { 1900 try { 1901 // Add the task to the list to remove if the component no longer exists 1902 tmpI.setComponent(cn); 1903 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1904 tasksToRemove.add(p.second); 1905 } 1906 } catch (Exception e) {} 1907 } 1908 } 1909 // Prune all the tasks with removed components from the list of recent tasks 1910 synchronized (ActivityManagerService.this) { 1911 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1912 // Remove the task but don't kill the process (since other components in that 1913 // package may still be running and in the background) 1914 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1915 } 1916 } 1917 } 1918 1919 @Override 1920 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1921 // Force stop the specified packages 1922 if (packages != null) { 1923 for (String pkg : packages) { 1924 synchronized (ActivityManagerService.this) { 1925 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1926 "finished booting")) { 1927 return true; 1928 } 1929 } 1930 } 1931 } 1932 return false; 1933 } 1934 }; 1935 1936 public void setSystemProcess() { 1937 try { 1938 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1939 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1940 ServiceManager.addService("meminfo", new MemBinder(this)); 1941 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1942 ServiceManager.addService("dbinfo", new DbBinder(this)); 1943 if (MONITOR_CPU_USAGE) { 1944 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1945 } 1946 ServiceManager.addService("permission", new PermissionController(this)); 1947 1948 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1949 "android", STOCK_PM_FLAGS); 1950 mSystemThread.installSystemApplicationInfo(info); 1951 1952 synchronized (this) { 1953 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1954 app.persistent = true; 1955 app.pid = MY_PID; 1956 app.maxAdj = ProcessList.SYSTEM_ADJ; 1957 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1958 mProcessNames.put(app.processName, app.uid, app); 1959 synchronized (mPidsSelfLocked) { 1960 mPidsSelfLocked.put(app.pid, app); 1961 } 1962 updateLruProcessLocked(app, false, null); 1963 updateOomAdjLocked(); 1964 } 1965 } catch (PackageManager.NameNotFoundException e) { 1966 throw new RuntimeException( 1967 "Unable to find android system package", e); 1968 } 1969 } 1970 1971 public void setWindowManager(WindowManagerService wm) { 1972 mWindowManager = wm; 1973 mStackSupervisor.setWindowManager(wm); 1974 } 1975 1976 public void startObservingNativeCrashes() { 1977 final NativeCrashListener ncl = new NativeCrashListener(this); 1978 ncl.start(); 1979 } 1980 1981 public IAppOpsService getAppOpsService() { 1982 return mAppOpsService; 1983 } 1984 1985 static class MemBinder extends Binder { 1986 ActivityManagerService mActivityManagerService; 1987 MemBinder(ActivityManagerService activityManagerService) { 1988 mActivityManagerService = activityManagerService; 1989 } 1990 1991 @Override 1992 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1993 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1994 != PackageManager.PERMISSION_GRANTED) { 1995 pw.println("Permission Denial: can't dump meminfo from from pid=" 1996 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1997 + " without permission " + android.Manifest.permission.DUMP); 1998 return; 1999 } 2000 2001 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2002 } 2003 } 2004 2005 static class GraphicsBinder extends Binder { 2006 ActivityManagerService mActivityManagerService; 2007 GraphicsBinder(ActivityManagerService activityManagerService) { 2008 mActivityManagerService = activityManagerService; 2009 } 2010 2011 @Override 2012 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2013 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2014 != PackageManager.PERMISSION_GRANTED) { 2015 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2016 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2017 + " without permission " + android.Manifest.permission.DUMP); 2018 return; 2019 } 2020 2021 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2022 } 2023 } 2024 2025 static class DbBinder extends Binder { 2026 ActivityManagerService mActivityManagerService; 2027 DbBinder(ActivityManagerService activityManagerService) { 2028 mActivityManagerService = activityManagerService; 2029 } 2030 2031 @Override 2032 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2033 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2034 != PackageManager.PERMISSION_GRANTED) { 2035 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2036 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2037 + " without permission " + android.Manifest.permission.DUMP); 2038 return; 2039 } 2040 2041 mActivityManagerService.dumpDbInfo(fd, pw, args); 2042 } 2043 } 2044 2045 static class CpuBinder extends Binder { 2046 ActivityManagerService mActivityManagerService; 2047 CpuBinder(ActivityManagerService activityManagerService) { 2048 mActivityManagerService = activityManagerService; 2049 } 2050 2051 @Override 2052 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2053 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2054 != PackageManager.PERMISSION_GRANTED) { 2055 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2056 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2057 + " without permission " + android.Manifest.permission.DUMP); 2058 return; 2059 } 2060 2061 synchronized (mActivityManagerService.mProcessCpuThread) { 2062 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2063 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2064 SystemClock.uptimeMillis())); 2065 } 2066 } 2067 } 2068 2069 public static final class Lifecycle extends SystemService { 2070 private final ActivityManagerService mService; 2071 2072 public Lifecycle(Context context) { 2073 super(context); 2074 mService = new ActivityManagerService(context); 2075 } 2076 2077 @Override 2078 public void onStart() { 2079 mService.start(); 2080 } 2081 2082 public ActivityManagerService getService() { 2083 return mService; 2084 } 2085 } 2086 2087 // Note: This method is invoked on the main thread but may need to attach various 2088 // handlers to other threads. So take care to be explicit about the looper. 2089 public ActivityManagerService(Context systemContext) { 2090 mContext = systemContext; 2091 mFactoryTest = FactoryTest.getMode(); 2092 mSystemThread = ActivityThread.currentActivityThread(); 2093 2094 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2095 2096 mHandlerThread = new ServiceThread(TAG, 2097 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2098 mHandlerThread.start(); 2099 mHandler = new MainHandler(mHandlerThread.getLooper()); 2100 2101 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2102 "foreground", BROADCAST_FG_TIMEOUT, false); 2103 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2104 "background", BROADCAST_BG_TIMEOUT, true); 2105 mBroadcastQueues[0] = mFgBroadcastQueue; 2106 mBroadcastQueues[1] = mBgBroadcastQueue; 2107 2108 mServices = new ActiveServices(this); 2109 mProviderMap = new ProviderMap(this); 2110 2111 // TODO: Move creation of battery stats service outside of activity manager service. 2112 File dataDir = Environment.getDataDirectory(); 2113 File systemDir = new File(dataDir, "system"); 2114 systemDir.mkdirs(); 2115 mBatteryStatsService = new BatteryStatsService(new File( 2116 systemDir, "batterystats.bin").toString(), mHandler); 2117 mBatteryStatsService.getActiveStatistics().readLocked(); 2118 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2119 mOnBattery = DEBUG_POWER ? true 2120 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2121 mBatteryStatsService.getActiveStatistics().setCallback(this); 2122 2123 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2124 2125 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2126 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2127 2128 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2129 2130 // User 0 is the first and only user that runs at boot. 2131 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2132 mUserLru.add(Integer.valueOf(0)); 2133 updateStartedUserArrayLocked(); 2134 2135 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2136 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2137 2138 mConfiguration.setToDefaults(); 2139 mConfiguration.setLocale(Locale.getDefault()); 2140 2141 mConfigurationSeq = mConfiguration.seq = 1; 2142 mProcessCpuTracker.init(); 2143 2144 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2145 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2146 mStackSupervisor = new ActivityStackSupervisor(this); 2147 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2148 2149 mProcessCpuThread = new Thread("CpuTracker") { 2150 @Override 2151 public void run() { 2152 while (true) { 2153 try { 2154 try { 2155 synchronized(this) { 2156 final long now = SystemClock.uptimeMillis(); 2157 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2158 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2159 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2160 // + ", write delay=" + nextWriteDelay); 2161 if (nextWriteDelay < nextCpuDelay) { 2162 nextCpuDelay = nextWriteDelay; 2163 } 2164 if (nextCpuDelay > 0) { 2165 mProcessCpuMutexFree.set(true); 2166 this.wait(nextCpuDelay); 2167 } 2168 } 2169 } catch (InterruptedException e) { 2170 } 2171 updateCpuStatsNow(); 2172 } catch (Exception e) { 2173 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2174 } 2175 } 2176 } 2177 }; 2178 2179 Watchdog.getInstance().addMonitor(this); 2180 Watchdog.getInstance().addThread(mHandler); 2181 } 2182 2183 public void setSystemServiceManager(SystemServiceManager mgr) { 2184 mSystemServiceManager = mgr; 2185 } 2186 2187 private void start() { 2188 mProcessCpuThread.start(); 2189 2190 mBatteryStatsService.publish(mContext); 2191 mUsageStatsService.publish(mContext); 2192 mAppOpsService.publish(mContext); 2193 Slog.d("AppOps", "AppOpsService published"); 2194 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2195 } 2196 2197 @Override 2198 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2199 throws RemoteException { 2200 if (code == SYSPROPS_TRANSACTION) { 2201 // We need to tell all apps about the system property change. 2202 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2203 synchronized(this) { 2204 final int NP = mProcessNames.getMap().size(); 2205 for (int ip=0; ip<NP; ip++) { 2206 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2207 final int NA = apps.size(); 2208 for (int ia=0; ia<NA; ia++) { 2209 ProcessRecord app = apps.valueAt(ia); 2210 if (app.thread != null) { 2211 procs.add(app.thread.asBinder()); 2212 } 2213 } 2214 } 2215 } 2216 2217 int N = procs.size(); 2218 for (int i=0; i<N; i++) { 2219 Parcel data2 = Parcel.obtain(); 2220 try { 2221 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2222 } catch (RemoteException e) { 2223 } 2224 data2.recycle(); 2225 } 2226 } 2227 try { 2228 return super.onTransact(code, data, reply, flags); 2229 } catch (RuntimeException e) { 2230 // The activity manager only throws security exceptions, so let's 2231 // log all others. 2232 if (!(e instanceof SecurityException)) { 2233 Slog.wtf(TAG, "Activity Manager Crash", e); 2234 } 2235 throw e; 2236 } 2237 } 2238 2239 void updateCpuStats() { 2240 final long now = SystemClock.uptimeMillis(); 2241 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2242 return; 2243 } 2244 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2245 synchronized (mProcessCpuThread) { 2246 mProcessCpuThread.notify(); 2247 } 2248 } 2249 } 2250 2251 void updateCpuStatsNow() { 2252 synchronized (mProcessCpuThread) { 2253 mProcessCpuMutexFree.set(false); 2254 final long now = SystemClock.uptimeMillis(); 2255 boolean haveNewCpuStats = false; 2256 2257 if (MONITOR_CPU_USAGE && 2258 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2259 mLastCpuTime.set(now); 2260 haveNewCpuStats = true; 2261 mProcessCpuTracker.update(); 2262 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2263 //Slog.i(TAG, "Total CPU usage: " 2264 // + mProcessCpu.getTotalCpuPercent() + "%"); 2265 2266 // Slog the cpu usage if the property is set. 2267 if ("true".equals(SystemProperties.get("events.cpu"))) { 2268 int user = mProcessCpuTracker.getLastUserTime(); 2269 int system = mProcessCpuTracker.getLastSystemTime(); 2270 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2271 int irq = mProcessCpuTracker.getLastIrqTime(); 2272 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2273 int idle = mProcessCpuTracker.getLastIdleTime(); 2274 2275 int total = user + system + iowait + irq + softIrq + idle; 2276 if (total == 0) total = 1; 2277 2278 EventLog.writeEvent(EventLogTags.CPU, 2279 ((user+system+iowait+irq+softIrq) * 100) / total, 2280 (user * 100) / total, 2281 (system * 100) / total, 2282 (iowait * 100) / total, 2283 (irq * 100) / total, 2284 (softIrq * 100) / total); 2285 } 2286 } 2287 2288 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2289 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2290 synchronized(bstats) { 2291 synchronized(mPidsSelfLocked) { 2292 if (haveNewCpuStats) { 2293 if (mOnBattery) { 2294 int perc = bstats.startAddingCpuLocked(); 2295 int totalUTime = 0; 2296 int totalSTime = 0; 2297 final int N = mProcessCpuTracker.countStats(); 2298 for (int i=0; i<N; i++) { 2299 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2300 if (!st.working) { 2301 continue; 2302 } 2303 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2304 int otherUTime = (st.rel_utime*perc)/100; 2305 int otherSTime = (st.rel_stime*perc)/100; 2306 totalUTime += otherUTime; 2307 totalSTime += otherSTime; 2308 if (pr != null) { 2309 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2310 if (ps == null || !ps.isActive()) { 2311 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2312 pr.info.uid, pr.processName); 2313 } 2314 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2315 st.rel_stime-otherSTime); 2316 ps.addSpeedStepTimes(cpuSpeedTimes); 2317 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2318 } else { 2319 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2320 if (ps == null || !ps.isActive()) { 2321 st.batteryStats = ps = bstats.getProcessStatsLocked( 2322 bstats.mapUid(st.uid), st.name); 2323 } 2324 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2325 st.rel_stime-otherSTime); 2326 ps.addSpeedStepTimes(cpuSpeedTimes); 2327 } 2328 } 2329 bstats.finishAddingCpuLocked(perc, totalUTime, 2330 totalSTime, cpuSpeedTimes); 2331 } 2332 } 2333 } 2334 2335 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2336 mLastWriteTime = now; 2337 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2338 } 2339 } 2340 } 2341 } 2342 2343 @Override 2344 public void batteryNeedsCpuUpdate() { 2345 updateCpuStatsNow(); 2346 } 2347 2348 @Override 2349 public void batteryPowerChanged(boolean onBattery) { 2350 // When plugging in, update the CPU stats first before changing 2351 // the plug state. 2352 updateCpuStatsNow(); 2353 synchronized (this) { 2354 synchronized(mPidsSelfLocked) { 2355 mOnBattery = DEBUG_POWER ? true : onBattery; 2356 } 2357 } 2358 } 2359 2360 /** 2361 * Initialize the application bind args. These are passed to each 2362 * process when the bindApplication() IPC is sent to the process. They're 2363 * lazily setup to make sure the services are running when they're asked for. 2364 */ 2365 private HashMap<String, IBinder> getCommonServicesLocked() { 2366 if (mAppBindArgs == null) { 2367 mAppBindArgs = new HashMap<String, IBinder>(); 2368 2369 // Setup the application init args 2370 mAppBindArgs.put("package", ServiceManager.getService("package")); 2371 mAppBindArgs.put("window", ServiceManager.getService("window")); 2372 mAppBindArgs.put(Context.ALARM_SERVICE, 2373 ServiceManager.getService(Context.ALARM_SERVICE)); 2374 } 2375 return mAppBindArgs; 2376 } 2377 2378 final void setFocusedActivityLocked(ActivityRecord r) { 2379 if (mFocusedActivity != r) { 2380 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2381 mFocusedActivity = r; 2382 if (r.task != null && r.task.voiceInteractor != null) { 2383 startRunningVoiceLocked(); 2384 } else { 2385 finishRunningVoiceLocked(); 2386 } 2387 mStackSupervisor.setFocusedStack(r); 2388 if (r != null) { 2389 mWindowManager.setFocusedApp(r.appToken, true); 2390 } 2391 applyUpdateLockStateLocked(r); 2392 } 2393 } 2394 2395 final void clearFocusedActivity(ActivityRecord r) { 2396 if (mFocusedActivity == r) { 2397 mFocusedActivity = null; 2398 } 2399 } 2400 2401 @Override 2402 public void setFocusedStack(int stackId) { 2403 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2404 synchronized (ActivityManagerService.this) { 2405 ActivityStack stack = mStackSupervisor.getStack(stackId); 2406 if (stack != null) { 2407 ActivityRecord r = stack.topRunningActivityLocked(null); 2408 if (r != null) { 2409 setFocusedActivityLocked(r); 2410 } 2411 } 2412 } 2413 } 2414 2415 @Override 2416 public void notifyActivityDrawn(IBinder token) { 2417 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2418 synchronized (this) { 2419 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2420 if (r != null) { 2421 r.task.stack.notifyActivityDrawnLocked(r); 2422 } 2423 } 2424 } 2425 2426 final void applyUpdateLockStateLocked(ActivityRecord r) { 2427 // Modifications to the UpdateLock state are done on our handler, outside 2428 // the activity manager's locks. The new state is determined based on the 2429 // state *now* of the relevant activity record. The object is passed to 2430 // the handler solely for logging detail, not to be consulted/modified. 2431 final boolean nextState = r != null && r.immersive; 2432 mHandler.sendMessage( 2433 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2434 } 2435 2436 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2437 Message msg = Message.obtain(); 2438 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2439 msg.obj = r.task.askedCompatMode ? null : r; 2440 mHandler.sendMessage(msg); 2441 } 2442 2443 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2444 String what, Object obj, ProcessRecord srcApp) { 2445 app.lastActivityTime = now; 2446 2447 if (app.activities.size() > 0) { 2448 // Don't want to touch dependent processes that are hosting activities. 2449 return index; 2450 } 2451 2452 int lrui = mLruProcesses.lastIndexOf(app); 2453 if (lrui < 0) { 2454 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2455 + what + " " + obj + " from " + srcApp); 2456 return index; 2457 } 2458 2459 if (lrui >= index) { 2460 // Don't want to cause this to move dependent processes *back* in the 2461 // list as if they were less frequently used. 2462 return index; 2463 } 2464 2465 if (lrui >= mLruProcessActivityStart) { 2466 // Don't want to touch dependent processes that are hosting activities. 2467 return index; 2468 } 2469 2470 mLruProcesses.remove(lrui); 2471 if (index > 0) { 2472 index--; 2473 } 2474 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2475 + " in LRU list: " + app); 2476 mLruProcesses.add(index, app); 2477 return index; 2478 } 2479 2480 final void removeLruProcessLocked(ProcessRecord app) { 2481 int lrui = mLruProcesses.lastIndexOf(app); 2482 if (lrui >= 0) { 2483 if (lrui <= mLruProcessActivityStart) { 2484 mLruProcessActivityStart--; 2485 } 2486 if (lrui <= mLruProcessServiceStart) { 2487 mLruProcessServiceStart--; 2488 } 2489 mLruProcesses.remove(lrui); 2490 } 2491 } 2492 2493 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2494 ProcessRecord client) { 2495 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2496 || app.treatLikeActivity; 2497 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2498 if (!activityChange && hasActivity) { 2499 // The process has activities, so we are only allowing activity-based adjustments 2500 // to move it. It should be kept in the front of the list with other 2501 // processes that have activities, and we don't want those to change their 2502 // order except due to activity operations. 2503 return; 2504 } 2505 2506 mLruSeq++; 2507 final long now = SystemClock.uptimeMillis(); 2508 app.lastActivityTime = now; 2509 2510 // First a quick reject: if the app is already at the position we will 2511 // put it, then there is nothing to do. 2512 if (hasActivity) { 2513 final int N = mLruProcesses.size(); 2514 if (N > 0 && mLruProcesses.get(N-1) == app) { 2515 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2516 return; 2517 } 2518 } else { 2519 if (mLruProcessServiceStart > 0 2520 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2521 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2522 return; 2523 } 2524 } 2525 2526 int lrui = mLruProcesses.lastIndexOf(app); 2527 2528 if (app.persistent && lrui >= 0) { 2529 // We don't care about the position of persistent processes, as long as 2530 // they are in the list. 2531 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2532 return; 2533 } 2534 2535 /* In progress: compute new position first, so we can avoid doing work 2536 if the process is not actually going to move. Not yet working. 2537 int addIndex; 2538 int nextIndex; 2539 boolean inActivity = false, inService = false; 2540 if (hasActivity) { 2541 // Process has activities, put it at the very tipsy-top. 2542 addIndex = mLruProcesses.size(); 2543 nextIndex = mLruProcessServiceStart; 2544 inActivity = true; 2545 } else if (hasService) { 2546 // Process has services, put it at the top of the service list. 2547 addIndex = mLruProcessActivityStart; 2548 nextIndex = mLruProcessServiceStart; 2549 inActivity = true; 2550 inService = true; 2551 } else { 2552 // Process not otherwise of interest, it goes to the top of the non-service area. 2553 addIndex = mLruProcessServiceStart; 2554 if (client != null) { 2555 int clientIndex = mLruProcesses.lastIndexOf(client); 2556 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2557 + app); 2558 if (clientIndex >= 0 && addIndex > clientIndex) { 2559 addIndex = clientIndex; 2560 } 2561 } 2562 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2563 } 2564 2565 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2566 + mLruProcessActivityStart + "): " + app); 2567 */ 2568 2569 if (lrui >= 0) { 2570 if (lrui < mLruProcessActivityStart) { 2571 mLruProcessActivityStart--; 2572 } 2573 if (lrui < mLruProcessServiceStart) { 2574 mLruProcessServiceStart--; 2575 } 2576 /* 2577 if (addIndex > lrui) { 2578 addIndex--; 2579 } 2580 if (nextIndex > lrui) { 2581 nextIndex--; 2582 } 2583 */ 2584 mLruProcesses.remove(lrui); 2585 } 2586 2587 /* 2588 mLruProcesses.add(addIndex, app); 2589 if (inActivity) { 2590 mLruProcessActivityStart++; 2591 } 2592 if (inService) { 2593 mLruProcessActivityStart++; 2594 } 2595 */ 2596 2597 int nextIndex; 2598 if (hasActivity) { 2599 final int N = mLruProcesses.size(); 2600 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2601 // Process doesn't have activities, but has clients with 2602 // activities... move it up, but one below the top (the top 2603 // should always have a real activity). 2604 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2605 mLruProcesses.add(N-1, app); 2606 // To keep it from spamming the LRU list (by making a bunch of clients), 2607 // we will push down any other entries owned by the app. 2608 final int uid = app.info.uid; 2609 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2610 ProcessRecord subProc = mLruProcesses.get(i); 2611 if (subProc.info.uid == uid) { 2612 // We want to push this one down the list. If the process after 2613 // it is for the same uid, however, don't do so, because we don't 2614 // want them internally to be re-ordered. 2615 if (mLruProcesses.get(i-1).info.uid != uid) { 2616 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2617 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2618 ProcessRecord tmp = mLruProcesses.get(i); 2619 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2620 mLruProcesses.set(i-1, tmp); 2621 i--; 2622 } 2623 } else { 2624 // A gap, we can stop here. 2625 break; 2626 } 2627 } 2628 } else { 2629 // Process has activities, put it at the very tipsy-top. 2630 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2631 mLruProcesses.add(app); 2632 } 2633 nextIndex = mLruProcessServiceStart; 2634 } else if (hasService) { 2635 // Process has services, put it at the top of the service list. 2636 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2637 mLruProcesses.add(mLruProcessActivityStart, app); 2638 nextIndex = mLruProcessServiceStart; 2639 mLruProcessActivityStart++; 2640 } else { 2641 // Process not otherwise of interest, it goes to the top of the non-service area. 2642 int index = mLruProcessServiceStart; 2643 if (client != null) { 2644 // If there is a client, don't allow the process to be moved up higher 2645 // in the list than that client. 2646 int clientIndex = mLruProcesses.lastIndexOf(client); 2647 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2648 + " when updating " + app); 2649 if (clientIndex <= lrui) { 2650 // Don't allow the client index restriction to push it down farther in the 2651 // list than it already is. 2652 clientIndex = lrui; 2653 } 2654 if (clientIndex >= 0 && index > clientIndex) { 2655 index = clientIndex; 2656 } 2657 } 2658 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2659 mLruProcesses.add(index, app); 2660 nextIndex = index-1; 2661 mLruProcessActivityStart++; 2662 mLruProcessServiceStart++; 2663 } 2664 2665 // If the app is currently using a content provider or service, 2666 // bump those processes as well. 2667 for (int j=app.connections.size()-1; j>=0; j--) { 2668 ConnectionRecord cr = app.connections.valueAt(j); 2669 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2670 && cr.binding.service.app != null 2671 && cr.binding.service.app.lruSeq != mLruSeq 2672 && !cr.binding.service.app.persistent) { 2673 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2674 "service connection", cr, app); 2675 } 2676 } 2677 for (int j=app.conProviders.size()-1; j>=0; j--) { 2678 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2679 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2680 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2681 "provider reference", cpr, app); 2682 } 2683 } 2684 } 2685 2686 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2687 if (uid == Process.SYSTEM_UID) { 2688 // The system gets to run in any process. If there are multiple 2689 // processes with the same uid, just pick the first (this 2690 // should never happen). 2691 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2692 if (procs == null) return null; 2693 final int N = procs.size(); 2694 for (int i = 0; i < N; i++) { 2695 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2696 } 2697 } 2698 ProcessRecord proc = mProcessNames.get(processName, uid); 2699 if (false && proc != null && !keepIfLarge 2700 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2701 && proc.lastCachedPss >= 4000) { 2702 // Turn this condition on to cause killing to happen regularly, for testing. 2703 if (proc.baseProcessTracker != null) { 2704 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2705 } 2706 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2707 + "k from cached"); 2708 } else if (proc != null && !keepIfLarge 2709 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2710 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2711 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2712 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2713 if (proc.baseProcessTracker != null) { 2714 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2715 } 2716 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2717 + "k from cached"); 2718 } 2719 } 2720 return proc; 2721 } 2722 2723 void ensurePackageDexOpt(String packageName) { 2724 IPackageManager pm = AppGlobals.getPackageManager(); 2725 try { 2726 if (pm.performDexOpt(packageName)) { 2727 mDidDexOpt = true; 2728 } 2729 } catch (RemoteException e) { 2730 } 2731 } 2732 2733 boolean isNextTransitionForward() { 2734 int transit = mWindowManager.getPendingAppTransition(); 2735 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2736 || transit == AppTransition.TRANSIT_TASK_OPEN 2737 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2738 } 2739 2740 final ProcessRecord startProcessLocked(String processName, 2741 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2742 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2743 boolean isolated, boolean keepIfLarge) { 2744 ProcessRecord app; 2745 if (!isolated) { 2746 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2747 } else { 2748 // If this is an isolated process, it can't re-use an existing process. 2749 app = null; 2750 } 2751 // We don't have to do anything more if: 2752 // (1) There is an existing application record; and 2753 // (2) The caller doesn't think it is dead, OR there is no thread 2754 // object attached to it so we know it couldn't have crashed; and 2755 // (3) There is a pid assigned to it, so it is either starting or 2756 // already running. 2757 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2758 + " app=" + app + " knownToBeDead=" + knownToBeDead 2759 + " thread=" + (app != null ? app.thread : null) 2760 + " pid=" + (app != null ? app.pid : -1)); 2761 if (app != null && app.pid > 0) { 2762 if (!knownToBeDead || app.thread == null) { 2763 // We already have the app running, or are waiting for it to 2764 // come up (we have a pid but not yet its thread), so keep it. 2765 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2766 // If this is a new package in the process, add the package to the list 2767 app.addPackage(info.packageName, mProcessStats); 2768 return app; 2769 } 2770 2771 // An application record is attached to a previous process, 2772 // clean it up now. 2773 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2774 handleAppDiedLocked(app, true, true); 2775 } 2776 2777 String hostingNameStr = hostingName != null 2778 ? hostingName.flattenToShortString() : null; 2779 2780 if (!isolated) { 2781 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2782 // If we are in the background, then check to see if this process 2783 // is bad. If so, we will just silently fail. 2784 if (mBadProcesses.get(info.processName, info.uid) != null) { 2785 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2786 + "/" + info.processName); 2787 return null; 2788 } 2789 } else { 2790 // When the user is explicitly starting a process, then clear its 2791 // crash count so that we won't make it bad until they see at 2792 // least one crash dialog again, and make the process good again 2793 // if it had been bad. 2794 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2795 + "/" + info.processName); 2796 mProcessCrashTimes.remove(info.processName, info.uid); 2797 if (mBadProcesses.get(info.processName, info.uid) != null) { 2798 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2799 UserHandle.getUserId(info.uid), info.uid, 2800 info.processName); 2801 mBadProcesses.remove(info.processName, info.uid); 2802 if (app != null) { 2803 app.bad = false; 2804 } 2805 } 2806 } 2807 } 2808 2809 if (app == null) { 2810 app = newProcessRecordLocked(info, processName, isolated); 2811 if (app == null) { 2812 Slog.w(TAG, "Failed making new process record for " 2813 + processName + "/" + info.uid + " isolated=" + isolated); 2814 return null; 2815 } 2816 mProcessNames.put(processName, app.uid, app); 2817 if (isolated) { 2818 mIsolatedProcesses.put(app.uid, app); 2819 } 2820 } else { 2821 // If this is a new package in the process, add the package to the list 2822 app.addPackage(info.packageName, mProcessStats); 2823 } 2824 2825 // If the system is not ready yet, then hold off on starting this 2826 // process until it is. 2827 if (!mProcessesReady 2828 && !isAllowedWhileBooting(info) 2829 && !allowWhileBooting) { 2830 if (!mProcessesOnHold.contains(app)) { 2831 mProcessesOnHold.add(app); 2832 } 2833 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2834 return app; 2835 } 2836 2837 startProcessLocked(app, hostingType, hostingNameStr); 2838 return (app.pid != 0) ? app : null; 2839 } 2840 2841 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2842 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2843 } 2844 2845 private final void startProcessLocked(ProcessRecord app, 2846 String hostingType, String hostingNameStr) { 2847 if (app.pid > 0 && app.pid != MY_PID) { 2848 synchronized (mPidsSelfLocked) { 2849 mPidsSelfLocked.remove(app.pid); 2850 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2851 } 2852 app.setPid(0); 2853 } 2854 2855 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2856 "startProcessLocked removing on hold: " + app); 2857 mProcessesOnHold.remove(app); 2858 2859 updateCpuStats(); 2860 2861 try { 2862 int uid = app.uid; 2863 2864 int[] gids = null; 2865 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2866 if (!app.isolated) { 2867 int[] permGids = null; 2868 try { 2869 final PackageManager pm = mContext.getPackageManager(); 2870 permGids = pm.getPackageGids(app.info.packageName); 2871 2872 if (Environment.isExternalStorageEmulated()) { 2873 if (pm.checkPermission( 2874 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2875 app.info.packageName) == PERMISSION_GRANTED) { 2876 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2877 } else { 2878 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2879 } 2880 } 2881 } catch (PackageManager.NameNotFoundException e) { 2882 Slog.w(TAG, "Unable to retrieve gids", e); 2883 } 2884 2885 /* 2886 * Add shared application GID so applications can share some 2887 * resources like shared libraries 2888 */ 2889 if (permGids == null) { 2890 gids = new int[1]; 2891 } else { 2892 gids = new int[permGids.length + 1]; 2893 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2894 } 2895 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2896 } 2897 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2898 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2899 && mTopComponent != null 2900 && app.processName.equals(mTopComponent.getPackageName())) { 2901 uid = 0; 2902 } 2903 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2904 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2905 uid = 0; 2906 } 2907 } 2908 int debugFlags = 0; 2909 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2910 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2911 // Also turn on CheckJNI for debuggable apps. It's quite 2912 // awkward to turn on otherwise. 2913 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2914 } 2915 // Run the app in safe mode if its manifest requests so or the 2916 // system is booted in safe mode. 2917 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2918 mSafeMode == true) { 2919 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2920 } 2921 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2922 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2923 } 2924 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2925 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2926 } 2927 if ("1".equals(SystemProperties.get("debug.assert"))) { 2928 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2929 } 2930 2931 String requiredAbi = app.info.cpuAbi; 2932 if (requiredAbi == null) { 2933 requiredAbi = Build.SUPPORTED_ABIS[0]; 2934 } 2935 2936 // Start the process. It will either succeed and return a result containing 2937 // the PID of the new process, or else throw a RuntimeException. 2938 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2939 app.processName, uid, uid, gids, debugFlags, mountExternal, 2940 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2941 2942 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2943 synchronized (bs) { 2944 if (bs.isOnBattery()) { 2945 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2946 } 2947 } 2948 2949 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2950 UserHandle.getUserId(uid), startResult.pid, uid, 2951 app.processName, hostingType, 2952 hostingNameStr != null ? hostingNameStr : ""); 2953 2954 if (app.persistent) { 2955 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2956 } 2957 2958 StringBuilder buf = mStringBuilder; 2959 buf.setLength(0); 2960 buf.append("Start proc "); 2961 buf.append(app.processName); 2962 buf.append(" for "); 2963 buf.append(hostingType); 2964 if (hostingNameStr != null) { 2965 buf.append(" "); 2966 buf.append(hostingNameStr); 2967 } 2968 buf.append(": pid="); 2969 buf.append(startResult.pid); 2970 buf.append(" uid="); 2971 buf.append(uid); 2972 buf.append(" gids={"); 2973 if (gids != null) { 2974 for (int gi=0; gi<gids.length; gi++) { 2975 if (gi != 0) buf.append(", "); 2976 buf.append(gids[gi]); 2977 2978 } 2979 } 2980 buf.append("}"); 2981 Slog.i(TAG, buf.toString()); 2982 app.setPid(startResult.pid); 2983 app.usingWrapper = startResult.usingWrapper; 2984 app.removed = false; 2985 synchronized (mPidsSelfLocked) { 2986 this.mPidsSelfLocked.put(startResult.pid, app); 2987 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2988 msg.obj = app; 2989 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2990 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2991 } 2992 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2993 app.processName, app.info.uid); 2994 if (app.isolated) { 2995 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2996 } 2997 } catch (RuntimeException e) { 2998 // XXX do better error recovery. 2999 app.setPid(0); 3000 Slog.e(TAG, "Failure starting process " + app.processName, e); 3001 } 3002 } 3003 3004 void updateUsageStats(ActivityRecord component, boolean resumed) { 3005 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3006 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3007 if (resumed) { 3008 mUsageStatsService.noteResumeComponent(component.realActivity); 3009 synchronized (stats) { 3010 stats.noteActivityResumedLocked(component.app.uid); 3011 } 3012 } else { 3013 mUsageStatsService.notePauseComponent(component.realActivity); 3014 synchronized (stats) { 3015 stats.noteActivityPausedLocked(component.app.uid); 3016 } 3017 } 3018 } 3019 3020 Intent getHomeIntent() { 3021 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3022 intent.setComponent(mTopComponent); 3023 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3024 intent.addCategory(Intent.CATEGORY_HOME); 3025 } 3026 return intent; 3027 } 3028 3029 boolean startHomeActivityLocked(int userId) { 3030 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3031 && mTopAction == null) { 3032 // We are running in factory test mode, but unable to find 3033 // the factory test app, so just sit around displaying the 3034 // error message and don't try to start anything. 3035 return false; 3036 } 3037 Intent intent = getHomeIntent(); 3038 ActivityInfo aInfo = 3039 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3040 if (aInfo != null) { 3041 intent.setComponent(new ComponentName( 3042 aInfo.applicationInfo.packageName, aInfo.name)); 3043 // Don't do this if the home app is currently being 3044 // instrumented. 3045 aInfo = new ActivityInfo(aInfo); 3046 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3047 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3048 aInfo.applicationInfo.uid, true); 3049 if (app == null || app.instrumentationClass == null) { 3050 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3051 mStackSupervisor.startHomeActivity(intent, aInfo); 3052 } 3053 } 3054 3055 return true; 3056 } 3057 3058 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3059 ActivityInfo ai = null; 3060 ComponentName comp = intent.getComponent(); 3061 try { 3062 if (comp != null) { 3063 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3064 } else { 3065 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3066 intent, 3067 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3068 flags, userId); 3069 3070 if (info != null) { 3071 ai = info.activityInfo; 3072 } 3073 } 3074 } catch (RemoteException e) { 3075 // ignore 3076 } 3077 3078 return ai; 3079 } 3080 3081 /** 3082 * Starts the "new version setup screen" if appropriate. 3083 */ 3084 void startSetupActivityLocked() { 3085 // Only do this once per boot. 3086 if (mCheckedForSetup) { 3087 return; 3088 } 3089 3090 // We will show this screen if the current one is a different 3091 // version than the last one shown, and we are not running in 3092 // low-level factory test mode. 3093 final ContentResolver resolver = mContext.getContentResolver(); 3094 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3095 Settings.Global.getInt(resolver, 3096 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3097 mCheckedForSetup = true; 3098 3099 // See if we should be showing the platform update setup UI. 3100 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3101 List<ResolveInfo> ris = mContext.getPackageManager() 3102 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3103 3104 // We don't allow third party apps to replace this. 3105 ResolveInfo ri = null; 3106 for (int i=0; ris != null && i<ris.size(); i++) { 3107 if ((ris.get(i).activityInfo.applicationInfo.flags 3108 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3109 ri = ris.get(i); 3110 break; 3111 } 3112 } 3113 3114 if (ri != null) { 3115 String vers = ri.activityInfo.metaData != null 3116 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3117 : null; 3118 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3119 vers = ri.activityInfo.applicationInfo.metaData.getString( 3120 Intent.METADATA_SETUP_VERSION); 3121 } 3122 String lastVers = Settings.Secure.getString( 3123 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3124 if (vers != null && !vers.equals(lastVers)) { 3125 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3126 intent.setComponent(new ComponentName( 3127 ri.activityInfo.packageName, ri.activityInfo.name)); 3128 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3129 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3130 } 3131 } 3132 } 3133 } 3134 3135 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3136 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3137 } 3138 3139 void enforceNotIsolatedCaller(String caller) { 3140 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3141 throw new SecurityException("Isolated process not allowed to call " + caller); 3142 } 3143 } 3144 3145 @Override 3146 public int getFrontActivityScreenCompatMode() { 3147 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3148 synchronized (this) { 3149 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3150 } 3151 } 3152 3153 @Override 3154 public void setFrontActivityScreenCompatMode(int mode) { 3155 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3156 "setFrontActivityScreenCompatMode"); 3157 synchronized (this) { 3158 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3159 } 3160 } 3161 3162 @Override 3163 public int getPackageScreenCompatMode(String packageName) { 3164 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3165 synchronized (this) { 3166 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3167 } 3168 } 3169 3170 @Override 3171 public void setPackageScreenCompatMode(String packageName, int mode) { 3172 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3173 "setPackageScreenCompatMode"); 3174 synchronized (this) { 3175 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3176 } 3177 } 3178 3179 @Override 3180 public boolean getPackageAskScreenCompat(String packageName) { 3181 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3182 synchronized (this) { 3183 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3184 } 3185 } 3186 3187 @Override 3188 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3189 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3190 "setPackageAskScreenCompat"); 3191 synchronized (this) { 3192 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3193 } 3194 } 3195 3196 private void dispatchProcessesChanged() { 3197 int N; 3198 synchronized (this) { 3199 N = mPendingProcessChanges.size(); 3200 if (mActiveProcessChanges.length < N) { 3201 mActiveProcessChanges = new ProcessChangeItem[N]; 3202 } 3203 mPendingProcessChanges.toArray(mActiveProcessChanges); 3204 mAvailProcessChanges.addAll(mPendingProcessChanges); 3205 mPendingProcessChanges.clear(); 3206 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3207 } 3208 3209 int i = mProcessObservers.beginBroadcast(); 3210 while (i > 0) { 3211 i--; 3212 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3213 if (observer != null) { 3214 try { 3215 for (int j=0; j<N; j++) { 3216 ProcessChangeItem item = mActiveProcessChanges[j]; 3217 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3218 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3219 + item.pid + " uid=" + item.uid + ": " 3220 + item.foregroundActivities); 3221 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3222 item.foregroundActivities); 3223 } 3224 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3225 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3226 + item.pid + " uid=" + item.uid + ": " + item.processState); 3227 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3228 } 3229 } 3230 } catch (RemoteException e) { 3231 } 3232 } 3233 } 3234 mProcessObservers.finishBroadcast(); 3235 } 3236 3237 private void dispatchProcessDied(int pid, int uid) { 3238 int i = mProcessObservers.beginBroadcast(); 3239 while (i > 0) { 3240 i--; 3241 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3242 if (observer != null) { 3243 try { 3244 observer.onProcessDied(pid, uid); 3245 } catch (RemoteException e) { 3246 } 3247 } 3248 } 3249 mProcessObservers.finishBroadcast(); 3250 } 3251 3252 final void doPendingActivityLaunchesLocked(boolean doResume) { 3253 final int N = mPendingActivityLaunches.size(); 3254 if (N <= 0) { 3255 return; 3256 } 3257 for (int i=0; i<N; i++) { 3258 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3259 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3260 doResume && i == (N-1), null); 3261 } 3262 mPendingActivityLaunches.clear(); 3263 } 3264 3265 @Override 3266 public final int startActivity(IApplicationThread caller, String callingPackage, 3267 Intent intent, String resolvedType, IBinder resultTo, 3268 String resultWho, int requestCode, int startFlags, 3269 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3270 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3271 resultWho, requestCode, 3272 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3273 } 3274 3275 @Override 3276 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3277 Intent intent, String resolvedType, IBinder resultTo, 3278 String resultWho, int requestCode, int startFlags, 3279 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3280 enforceNotIsolatedCaller("startActivity"); 3281 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3282 false, true, "startActivity", null); 3283 // TODO: Switch to user app stacks here. 3284 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3285 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3286 null, null, options, userId, null); 3287 } 3288 3289 @Override 3290 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3291 Intent intent, String resolvedType, IBinder resultTo, 3292 String resultWho, int requestCode, int startFlags, String profileFile, 3293 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3294 enforceNotIsolatedCaller("startActivityAndWait"); 3295 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3296 false, true, "startActivityAndWait", null); 3297 WaitResult res = new WaitResult(); 3298 // TODO: Switch to user app stacks here. 3299 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3300 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3301 res, null, options, UserHandle.getCallingUserId(), null); 3302 return res; 3303 } 3304 3305 @Override 3306 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3307 Intent intent, String resolvedType, IBinder resultTo, 3308 String resultWho, int requestCode, int startFlags, Configuration config, 3309 Bundle options, int userId) { 3310 enforceNotIsolatedCaller("startActivityWithConfig"); 3311 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3312 false, true, "startActivityWithConfig", null); 3313 // TODO: Switch to user app stacks here. 3314 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3315 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3316 null, null, null, config, options, userId, null); 3317 return ret; 3318 } 3319 3320 @Override 3321 public int startActivityIntentSender(IApplicationThread caller, 3322 IntentSender intent, Intent fillInIntent, String resolvedType, 3323 IBinder resultTo, String resultWho, int requestCode, 3324 int flagsMask, int flagsValues, Bundle options) { 3325 enforceNotIsolatedCaller("startActivityIntentSender"); 3326 // Refuse possible leaked file descriptors 3327 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3328 throw new IllegalArgumentException("File descriptors passed in Intent"); 3329 } 3330 3331 IIntentSender sender = intent.getTarget(); 3332 if (!(sender instanceof PendingIntentRecord)) { 3333 throw new IllegalArgumentException("Bad PendingIntent object"); 3334 } 3335 3336 PendingIntentRecord pir = (PendingIntentRecord)sender; 3337 3338 synchronized (this) { 3339 // If this is coming from the currently resumed activity, it is 3340 // effectively saying that app switches are allowed at this point. 3341 final ActivityStack stack = getFocusedStack(); 3342 if (stack.mResumedActivity != null && 3343 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3344 mAppSwitchesAllowedTime = 0; 3345 } 3346 } 3347 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3348 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3349 return ret; 3350 } 3351 3352 @Override 3353 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3354 Intent intent, String resolvedType, IVoiceInteractionSession session, 3355 IVoiceInteractor interactor, int startFlags, String profileFile, 3356 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3357 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3358 != PackageManager.PERMISSION_GRANTED) { 3359 String msg = "Permission Denial: startVoiceActivity() from pid=" 3360 + Binder.getCallingPid() 3361 + ", uid=" + Binder.getCallingUid() 3362 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3363 Slog.w(TAG, msg); 3364 throw new SecurityException(msg); 3365 } 3366 if (session == null || interactor == null) { 3367 throw new NullPointerException("null session or interactor"); 3368 } 3369 userId = handleIncomingUser(callingPid, callingUid, userId, 3370 false, true, "startVoiceActivity", null); 3371 // TODO: Switch to user app stacks here. 3372 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3373 resolvedType, session, interactor, null, null, 0, startFlags, 3374 profileFile, profileFd, null, null, options, userId, null); 3375 } 3376 3377 @Override 3378 public boolean startNextMatchingActivity(IBinder callingActivity, 3379 Intent intent, Bundle options) { 3380 // Refuse possible leaked file descriptors 3381 if (intent != null && intent.hasFileDescriptors() == true) { 3382 throw new IllegalArgumentException("File descriptors passed in Intent"); 3383 } 3384 3385 synchronized (this) { 3386 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3387 if (r == null) { 3388 ActivityOptions.abort(options); 3389 return false; 3390 } 3391 if (r.app == null || r.app.thread == null) { 3392 // The caller is not running... d'oh! 3393 ActivityOptions.abort(options); 3394 return false; 3395 } 3396 intent = new Intent(intent); 3397 // The caller is not allowed to change the data. 3398 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3399 // And we are resetting to find the next component... 3400 intent.setComponent(null); 3401 3402 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3403 3404 ActivityInfo aInfo = null; 3405 try { 3406 List<ResolveInfo> resolves = 3407 AppGlobals.getPackageManager().queryIntentActivities( 3408 intent, r.resolvedType, 3409 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3410 UserHandle.getCallingUserId()); 3411 3412 // Look for the original activity in the list... 3413 final int N = resolves != null ? resolves.size() : 0; 3414 for (int i=0; i<N; i++) { 3415 ResolveInfo rInfo = resolves.get(i); 3416 if (rInfo.activityInfo.packageName.equals(r.packageName) 3417 && rInfo.activityInfo.name.equals(r.info.name)) { 3418 // We found the current one... the next matching is 3419 // after it. 3420 i++; 3421 if (i<N) { 3422 aInfo = resolves.get(i).activityInfo; 3423 } 3424 if (debug) { 3425 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3426 + "/" + r.info.name); 3427 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3428 + "/" + aInfo.name); 3429 } 3430 break; 3431 } 3432 } 3433 } catch (RemoteException e) { 3434 } 3435 3436 if (aInfo == null) { 3437 // Nobody who is next! 3438 ActivityOptions.abort(options); 3439 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3440 return false; 3441 } 3442 3443 intent.setComponent(new ComponentName( 3444 aInfo.applicationInfo.packageName, aInfo.name)); 3445 intent.setFlags(intent.getFlags()&~( 3446 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3447 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3448 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3449 Intent.FLAG_ACTIVITY_NEW_TASK)); 3450 3451 // Okay now we need to start the new activity, replacing the 3452 // currently running activity. This is a little tricky because 3453 // we want to start the new one as if the current one is finished, 3454 // but not finish the current one first so that there is no flicker. 3455 // And thus... 3456 final boolean wasFinishing = r.finishing; 3457 r.finishing = true; 3458 3459 // Propagate reply information over to the new activity. 3460 final ActivityRecord resultTo = r.resultTo; 3461 final String resultWho = r.resultWho; 3462 final int requestCode = r.requestCode; 3463 r.resultTo = null; 3464 if (resultTo != null) { 3465 resultTo.removeResultsLocked(r, resultWho, requestCode); 3466 } 3467 3468 final long origId = Binder.clearCallingIdentity(); 3469 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3470 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3471 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3472 options, false, null, null); 3473 Binder.restoreCallingIdentity(origId); 3474 3475 r.finishing = wasFinishing; 3476 if (res != ActivityManager.START_SUCCESS) { 3477 return false; 3478 } 3479 return true; 3480 } 3481 } 3482 3483 final int startActivityInPackage(int uid, String callingPackage, 3484 Intent intent, String resolvedType, IBinder resultTo, 3485 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3486 IActivityContainer container) { 3487 3488 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3489 false, true, "startActivityInPackage", null); 3490 3491 // TODO: Switch to user app stacks here. 3492 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3493 null, null, resultTo, resultWho, requestCode, startFlags, 3494 null, null, null, null, options, userId, container); 3495 return ret; 3496 } 3497 3498 @Override 3499 public final int startActivities(IApplicationThread caller, String callingPackage, 3500 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3501 int userId) { 3502 enforceNotIsolatedCaller("startActivities"); 3503 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3504 false, true, "startActivity", null); 3505 // TODO: Switch to user app stacks here. 3506 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3507 resolvedTypes, resultTo, options, userId); 3508 return ret; 3509 } 3510 3511 final int startActivitiesInPackage(int uid, String callingPackage, 3512 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3513 Bundle options, int userId) { 3514 3515 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3516 false, true, "startActivityInPackage", null); 3517 // TODO: Switch to user app stacks here. 3518 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3519 resultTo, options, userId); 3520 return ret; 3521 } 3522 3523 final void addRecentTaskLocked(TaskRecord task) { 3524 int N = mRecentTasks.size(); 3525 // Quick case: check if the top-most recent task is the same. 3526 if (N > 0 && mRecentTasks.get(0) == task) { 3527 return; 3528 } 3529 // Another quick case: never add voice sessions. 3530 if (task.voiceSession != null) { 3531 return; 3532 } 3533 // Remove any existing entries that are the same kind of task. 3534 final Intent intent = task.intent; 3535 final boolean document = intent != null && intent.isDocument(); 3536 for (int i=0; i<N; i++) { 3537 TaskRecord tr = mRecentTasks.get(i); 3538 if (task != tr) { 3539 if (task.userId != tr.userId) { 3540 continue; 3541 } 3542 final Intent trIntent = tr.intent; 3543 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3544 (intent == null || !intent.filterEquals(trIntent))) { 3545 continue; 3546 } 3547 if (document || trIntent != null && trIntent.isDocument()) { 3548 // Document tasks do not match other tasks. 3549 continue; 3550 } 3551 } 3552 3553 // Either task and tr are the same or, their affinities match or their intents match 3554 // and neither of them is a document. 3555 tr.disposeThumbnail(); 3556 mRecentTasks.remove(i); 3557 i--; 3558 N--; 3559 if (task.intent == null) { 3560 // If the new recent task we are adding is not fully 3561 // specified, then replace it with the existing recent task. 3562 task = tr; 3563 } 3564 } 3565 if (N >= MAX_RECENT_TASKS) { 3566 mRecentTasks.remove(N-1).disposeThumbnail(); 3567 } 3568 mRecentTasks.add(0, task); 3569 } 3570 3571 @Override 3572 public void reportActivityFullyDrawn(IBinder token) { 3573 synchronized (this) { 3574 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3575 if (r == null) { 3576 return; 3577 } 3578 r.reportFullyDrawnLocked(); 3579 } 3580 } 3581 3582 @Override 3583 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3584 synchronized (this) { 3585 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3586 if (r == null) { 3587 return; 3588 } 3589 final long origId = Binder.clearCallingIdentity(); 3590 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3591 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3592 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3593 if (config != null) { 3594 r.frozenBeforeDestroy = true; 3595 if (!updateConfigurationLocked(config, r, false, false)) { 3596 mStackSupervisor.resumeTopActivitiesLocked(); 3597 } 3598 } 3599 Binder.restoreCallingIdentity(origId); 3600 } 3601 } 3602 3603 @Override 3604 public int getRequestedOrientation(IBinder token) { 3605 synchronized (this) { 3606 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3607 if (r == null) { 3608 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3609 } 3610 return mWindowManager.getAppOrientation(r.appToken); 3611 } 3612 } 3613 3614 /** 3615 * This is the internal entry point for handling Activity.finish(). 3616 * 3617 * @param token The Binder token referencing the Activity we want to finish. 3618 * @param resultCode Result code, if any, from this Activity. 3619 * @param resultData Result data (Intent), if any, from this Activity. 3620 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3621 * the root Activity in the task. 3622 * 3623 * @return Returns true if the activity successfully finished, or false if it is still running. 3624 */ 3625 @Override 3626 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3627 boolean finishTask) { 3628 // Refuse possible leaked file descriptors 3629 if (resultData != null && resultData.hasFileDescriptors() == true) { 3630 throw new IllegalArgumentException("File descriptors passed in Intent"); 3631 } 3632 3633 synchronized(this) { 3634 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3635 if (r == null) { 3636 return true; 3637 } 3638 // Keep track of the root activity of the task before we finish it 3639 TaskRecord tr = r.task; 3640 ActivityRecord rootR = tr.getRootActivity(); 3641 if (mController != null) { 3642 // Find the first activity that is not finishing. 3643 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3644 if (next != null) { 3645 // ask watcher if this is allowed 3646 boolean resumeOK = true; 3647 try { 3648 resumeOK = mController.activityResuming(next.packageName); 3649 } catch (RemoteException e) { 3650 mController = null; 3651 Watchdog.getInstance().setActivityController(null); 3652 } 3653 3654 if (!resumeOK) { 3655 return false; 3656 } 3657 } 3658 } 3659 final long origId = Binder.clearCallingIdentity(); 3660 try { 3661 boolean res; 3662 if (finishTask && r == rootR) { 3663 // If requested, remove the task that is associated to this activity only if it 3664 // was the root activity in the task. The result code and data is ignored because 3665 // we don't support returning them across task boundaries. 3666 res = removeTaskByIdLocked(tr.taskId, 0); 3667 } else { 3668 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3669 resultData, "app-request", true); 3670 } 3671 return res; 3672 } finally { 3673 Binder.restoreCallingIdentity(origId); 3674 } 3675 } 3676 } 3677 3678 @Override 3679 public final void finishHeavyWeightApp() { 3680 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3681 != PackageManager.PERMISSION_GRANTED) { 3682 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3683 + Binder.getCallingPid() 3684 + ", uid=" + Binder.getCallingUid() 3685 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3686 Slog.w(TAG, msg); 3687 throw new SecurityException(msg); 3688 } 3689 3690 synchronized(this) { 3691 if (mHeavyWeightProcess == null) { 3692 return; 3693 } 3694 3695 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3696 mHeavyWeightProcess.activities); 3697 for (int i=0; i<activities.size(); i++) { 3698 ActivityRecord r = activities.get(i); 3699 if (!r.finishing) { 3700 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3701 null, "finish-heavy", true); 3702 } 3703 } 3704 3705 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3706 mHeavyWeightProcess.userId, 0)); 3707 mHeavyWeightProcess = null; 3708 } 3709 } 3710 3711 @Override 3712 public void crashApplication(int uid, int initialPid, String packageName, 3713 String message) { 3714 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3715 != PackageManager.PERMISSION_GRANTED) { 3716 String msg = "Permission Denial: crashApplication() from pid=" 3717 + Binder.getCallingPid() 3718 + ", uid=" + Binder.getCallingUid() 3719 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3720 Slog.w(TAG, msg); 3721 throw new SecurityException(msg); 3722 } 3723 3724 synchronized(this) { 3725 ProcessRecord proc = null; 3726 3727 // Figure out which process to kill. We don't trust that initialPid 3728 // still has any relation to current pids, so must scan through the 3729 // list. 3730 synchronized (mPidsSelfLocked) { 3731 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3732 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3733 if (p.uid != uid) { 3734 continue; 3735 } 3736 if (p.pid == initialPid) { 3737 proc = p; 3738 break; 3739 } 3740 if (p.pkgList.containsKey(packageName)) { 3741 proc = p; 3742 } 3743 } 3744 } 3745 3746 if (proc == null) { 3747 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3748 + " initialPid=" + initialPid 3749 + " packageName=" + packageName); 3750 return; 3751 } 3752 3753 if (proc.thread != null) { 3754 if (proc.pid == Process.myPid()) { 3755 Log.w(TAG, "crashApplication: trying to crash self!"); 3756 return; 3757 } 3758 long ident = Binder.clearCallingIdentity(); 3759 try { 3760 proc.thread.scheduleCrash(message); 3761 } catch (RemoteException e) { 3762 } 3763 Binder.restoreCallingIdentity(ident); 3764 } 3765 } 3766 } 3767 3768 @Override 3769 public final void finishSubActivity(IBinder token, String resultWho, 3770 int requestCode) { 3771 synchronized(this) { 3772 final long origId = Binder.clearCallingIdentity(); 3773 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3774 if (r != null) { 3775 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3776 } 3777 Binder.restoreCallingIdentity(origId); 3778 } 3779 } 3780 3781 @Override 3782 public boolean finishActivityAffinity(IBinder token) { 3783 synchronized(this) { 3784 final long origId = Binder.clearCallingIdentity(); 3785 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3786 boolean res = false; 3787 if (r != null) { 3788 res = r.task.stack.finishActivityAffinityLocked(r); 3789 } 3790 Binder.restoreCallingIdentity(origId); 3791 return res; 3792 } 3793 } 3794 3795 @Override 3796 public boolean willActivityBeVisible(IBinder token) { 3797 synchronized(this) { 3798 ActivityStack stack = ActivityRecord.getStackLocked(token); 3799 if (stack != null) { 3800 return stack.willActivityBeVisibleLocked(token); 3801 } 3802 return false; 3803 } 3804 } 3805 3806 @Override 3807 public void overridePendingTransition(IBinder token, String packageName, 3808 int enterAnim, int exitAnim) { 3809 synchronized(this) { 3810 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3811 if (self == null) { 3812 return; 3813 } 3814 3815 final long origId = Binder.clearCallingIdentity(); 3816 3817 if (self.state == ActivityState.RESUMED 3818 || self.state == ActivityState.PAUSING) { 3819 mWindowManager.overridePendingAppTransition(packageName, 3820 enterAnim, exitAnim, null); 3821 } 3822 3823 Binder.restoreCallingIdentity(origId); 3824 } 3825 } 3826 3827 /** 3828 * Main function for removing an existing process from the activity manager 3829 * as a result of that process going away. Clears out all connections 3830 * to the process. 3831 */ 3832 private final void handleAppDiedLocked(ProcessRecord app, 3833 boolean restarting, boolean allowRestart) { 3834 int pid = app.pid; 3835 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3836 if (!restarting) { 3837 removeLruProcessLocked(app); 3838 if (pid > 0) { 3839 ProcessList.remove(pid); 3840 } 3841 } 3842 3843 if (mProfileProc == app) { 3844 clearProfilerLocked(); 3845 } 3846 3847 // Remove this application's activities from active lists. 3848 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3849 3850 app.activities.clear(); 3851 3852 if (app.instrumentationClass != null) { 3853 Slog.w(TAG, "Crash of app " + app.processName 3854 + " running instrumentation " + app.instrumentationClass); 3855 Bundle info = new Bundle(); 3856 info.putString("shortMsg", "Process crashed."); 3857 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3858 } 3859 3860 if (!restarting) { 3861 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3862 // If there was nothing to resume, and we are not already 3863 // restarting this process, but there is a visible activity that 3864 // is hosted by the process... then make sure all visible 3865 // activities are running, taking care of restarting this 3866 // process. 3867 if (hasVisibleActivities) { 3868 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3869 } 3870 } 3871 } 3872 } 3873 3874 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3875 IBinder threadBinder = thread.asBinder(); 3876 // Find the application record. 3877 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3878 ProcessRecord rec = mLruProcesses.get(i); 3879 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3880 return i; 3881 } 3882 } 3883 return -1; 3884 } 3885 3886 final ProcessRecord getRecordForAppLocked( 3887 IApplicationThread thread) { 3888 if (thread == null) { 3889 return null; 3890 } 3891 3892 int appIndex = getLRURecordIndexForAppLocked(thread); 3893 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3894 } 3895 3896 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3897 // If there are no longer any background processes running, 3898 // and the app that died was not running instrumentation, 3899 // then tell everyone we are now low on memory. 3900 boolean haveBg = false; 3901 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3902 ProcessRecord rec = mLruProcesses.get(i); 3903 if (rec.thread != null 3904 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3905 haveBg = true; 3906 break; 3907 } 3908 } 3909 3910 if (!haveBg) { 3911 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3912 if (doReport) { 3913 long now = SystemClock.uptimeMillis(); 3914 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3915 doReport = false; 3916 } else { 3917 mLastMemUsageReportTime = now; 3918 } 3919 } 3920 final ArrayList<ProcessMemInfo> memInfos 3921 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3922 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3923 long now = SystemClock.uptimeMillis(); 3924 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3925 ProcessRecord rec = mLruProcesses.get(i); 3926 if (rec == dyingProc || rec.thread == null) { 3927 continue; 3928 } 3929 if (doReport) { 3930 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3931 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3932 } 3933 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3934 // The low memory report is overriding any current 3935 // state for a GC request. Make sure to do 3936 // heavy/important/visible/foreground processes first. 3937 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3938 rec.lastRequestedGc = 0; 3939 } else { 3940 rec.lastRequestedGc = rec.lastLowMemory; 3941 } 3942 rec.reportLowMemory = true; 3943 rec.lastLowMemory = now; 3944 mProcessesToGc.remove(rec); 3945 addProcessToGcListLocked(rec); 3946 } 3947 } 3948 if (doReport) { 3949 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3950 mHandler.sendMessage(msg); 3951 } 3952 scheduleAppGcsLocked(); 3953 } 3954 } 3955 3956 final void appDiedLocked(ProcessRecord app, int pid, 3957 IApplicationThread thread) { 3958 3959 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3960 synchronized (stats) { 3961 stats.noteProcessDiedLocked(app.info.uid, pid); 3962 } 3963 3964 // Clean up already done if the process has been re-started. 3965 if (app.pid == pid && app.thread != null && 3966 app.thread.asBinder() == thread.asBinder()) { 3967 boolean doLowMem = app.instrumentationClass == null; 3968 boolean doOomAdj = doLowMem; 3969 if (!app.killedByAm) { 3970 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3971 + ") has died."); 3972 mAllowLowerMemLevel = true; 3973 } else { 3974 // Note that we always want to do oom adj to update our state with the 3975 // new number of procs. 3976 mAllowLowerMemLevel = false; 3977 doLowMem = false; 3978 } 3979 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3980 if (DEBUG_CLEANUP) Slog.v( 3981 TAG, "Dying app: " + app + ", pid: " + pid 3982 + ", thread: " + thread.asBinder()); 3983 handleAppDiedLocked(app, false, true); 3984 3985 if (doOomAdj) { 3986 updateOomAdjLocked(); 3987 } 3988 if (doLowMem) { 3989 doLowMemReportIfNeededLocked(app); 3990 } 3991 } else if (app.pid != pid) { 3992 // A new process has already been started. 3993 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3994 + ") has died and restarted (pid " + app.pid + ")."); 3995 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3996 } else if (DEBUG_PROCESSES) { 3997 Slog.d(TAG, "Received spurious death notification for thread " 3998 + thread.asBinder()); 3999 } 4000 } 4001 4002 /** 4003 * If a stack trace dump file is configured, dump process stack traces. 4004 * @param clearTraces causes the dump file to be erased prior to the new 4005 * traces being written, if true; when false, the new traces will be 4006 * appended to any existing file content. 4007 * @param firstPids of dalvik VM processes to dump stack traces for first 4008 * @param lastPids of dalvik VM processes to dump stack traces for last 4009 * @param nativeProcs optional list of native process names to dump stack crawls 4010 * @return file containing stack traces, or null if no dump file is configured 4011 */ 4012 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4013 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4014 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4015 if (tracesPath == null || tracesPath.length() == 0) { 4016 return null; 4017 } 4018 4019 File tracesFile = new File(tracesPath); 4020 try { 4021 File tracesDir = tracesFile.getParentFile(); 4022 if (!tracesDir.exists()) { 4023 tracesFile.mkdirs(); 4024 if (!SELinux.restorecon(tracesDir)) { 4025 return null; 4026 } 4027 } 4028 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4029 4030 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4031 tracesFile.createNewFile(); 4032 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4033 } catch (IOException e) { 4034 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4035 return null; 4036 } 4037 4038 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4039 return tracesFile; 4040 } 4041 4042 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4043 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4044 // Use a FileObserver to detect when traces finish writing. 4045 // The order of traces is considered important to maintain for legibility. 4046 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4047 @Override 4048 public synchronized void onEvent(int event, String path) { notify(); } 4049 }; 4050 4051 try { 4052 observer.startWatching(); 4053 4054 // First collect all of the stacks of the most important pids. 4055 if (firstPids != null) { 4056 try { 4057 int num = firstPids.size(); 4058 for (int i = 0; i < num; i++) { 4059 synchronized (observer) { 4060 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4061 observer.wait(200); // Wait for write-close, give up after 200msec 4062 } 4063 } 4064 } catch (InterruptedException e) { 4065 Log.wtf(TAG, e); 4066 } 4067 } 4068 4069 // Next collect the stacks of the native pids 4070 if (nativeProcs != null) { 4071 int[] pids = Process.getPidsForCommands(nativeProcs); 4072 if (pids != null) { 4073 for (int pid : pids) { 4074 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4075 } 4076 } 4077 } 4078 4079 // Lastly, measure CPU usage. 4080 if (processCpuTracker != null) { 4081 processCpuTracker.init(); 4082 System.gc(); 4083 processCpuTracker.update(); 4084 try { 4085 synchronized (processCpuTracker) { 4086 processCpuTracker.wait(500); // measure over 1/2 second. 4087 } 4088 } catch (InterruptedException e) { 4089 } 4090 processCpuTracker.update(); 4091 4092 // We'll take the stack crawls of just the top apps using CPU. 4093 final int N = processCpuTracker.countWorkingStats(); 4094 int numProcs = 0; 4095 for (int i=0; i<N && numProcs<5; i++) { 4096 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4097 if (lastPids.indexOfKey(stats.pid) >= 0) { 4098 numProcs++; 4099 try { 4100 synchronized (observer) { 4101 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4102 observer.wait(200); // Wait for write-close, give up after 200msec 4103 } 4104 } catch (InterruptedException e) { 4105 Log.wtf(TAG, e); 4106 } 4107 4108 } 4109 } 4110 } 4111 } finally { 4112 observer.stopWatching(); 4113 } 4114 } 4115 4116 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4117 if (true || IS_USER_BUILD) { 4118 return; 4119 } 4120 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4121 if (tracesPath == null || tracesPath.length() == 0) { 4122 return; 4123 } 4124 4125 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4126 StrictMode.allowThreadDiskWrites(); 4127 try { 4128 final File tracesFile = new File(tracesPath); 4129 final File tracesDir = tracesFile.getParentFile(); 4130 final File tracesTmp = new File(tracesDir, "__tmp__"); 4131 try { 4132 if (!tracesDir.exists()) { 4133 tracesFile.mkdirs(); 4134 if (!SELinux.restorecon(tracesDir.getPath())) { 4135 return; 4136 } 4137 } 4138 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4139 4140 if (tracesFile.exists()) { 4141 tracesTmp.delete(); 4142 tracesFile.renameTo(tracesTmp); 4143 } 4144 StringBuilder sb = new StringBuilder(); 4145 Time tobj = new Time(); 4146 tobj.set(System.currentTimeMillis()); 4147 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4148 sb.append(": "); 4149 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4150 sb.append(" since "); 4151 sb.append(msg); 4152 FileOutputStream fos = new FileOutputStream(tracesFile); 4153 fos.write(sb.toString().getBytes()); 4154 if (app == null) { 4155 fos.write("\n*** No application process!".getBytes()); 4156 } 4157 fos.close(); 4158 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4159 } catch (IOException e) { 4160 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4161 return; 4162 } 4163 4164 if (app != null) { 4165 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4166 firstPids.add(app.pid); 4167 dumpStackTraces(tracesPath, firstPids, null, null, null); 4168 } 4169 4170 File lastTracesFile = null; 4171 File curTracesFile = null; 4172 for (int i=9; i>=0; i--) { 4173 String name = String.format(Locale.US, "slow%02d.txt", i); 4174 curTracesFile = new File(tracesDir, name); 4175 if (curTracesFile.exists()) { 4176 if (lastTracesFile != null) { 4177 curTracesFile.renameTo(lastTracesFile); 4178 } else { 4179 curTracesFile.delete(); 4180 } 4181 } 4182 lastTracesFile = curTracesFile; 4183 } 4184 tracesFile.renameTo(curTracesFile); 4185 if (tracesTmp.exists()) { 4186 tracesTmp.renameTo(tracesFile); 4187 } 4188 } finally { 4189 StrictMode.setThreadPolicy(oldPolicy); 4190 } 4191 } 4192 4193 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4194 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4195 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4196 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4197 4198 if (mController != null) { 4199 try { 4200 // 0 == continue, -1 = kill process immediately 4201 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4202 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4203 } catch (RemoteException e) { 4204 mController = null; 4205 Watchdog.getInstance().setActivityController(null); 4206 } 4207 } 4208 4209 long anrTime = SystemClock.uptimeMillis(); 4210 if (MONITOR_CPU_USAGE) { 4211 updateCpuStatsNow(); 4212 } 4213 4214 synchronized (this) { 4215 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4216 if (mShuttingDown) { 4217 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4218 return; 4219 } else if (app.notResponding) { 4220 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4221 return; 4222 } else if (app.crashing) { 4223 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4224 return; 4225 } 4226 4227 // In case we come through here for the same app before completing 4228 // this one, mark as anring now so we will bail out. 4229 app.notResponding = true; 4230 4231 // Log the ANR to the event log. 4232 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4233 app.processName, app.info.flags, annotation); 4234 4235 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4236 firstPids.add(app.pid); 4237 4238 int parentPid = app.pid; 4239 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4240 if (parentPid != app.pid) firstPids.add(parentPid); 4241 4242 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4243 4244 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4245 ProcessRecord r = mLruProcesses.get(i); 4246 if (r != null && r.thread != null) { 4247 int pid = r.pid; 4248 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4249 if (r.persistent) { 4250 firstPids.add(pid); 4251 } else { 4252 lastPids.put(pid, Boolean.TRUE); 4253 } 4254 } 4255 } 4256 } 4257 } 4258 4259 // Log the ANR to the main log. 4260 StringBuilder info = new StringBuilder(); 4261 info.setLength(0); 4262 info.append("ANR in ").append(app.processName); 4263 if (activity != null && activity.shortComponentName != null) { 4264 info.append(" (").append(activity.shortComponentName).append(")"); 4265 } 4266 info.append("\n"); 4267 info.append("PID: ").append(app.pid).append("\n"); 4268 if (annotation != null) { 4269 info.append("Reason: ").append(annotation).append("\n"); 4270 } 4271 if (parent != null && parent != activity) { 4272 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4273 } 4274 4275 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4276 4277 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4278 NATIVE_STACKS_OF_INTEREST); 4279 4280 String cpuInfo = null; 4281 if (MONITOR_CPU_USAGE) { 4282 updateCpuStatsNow(); 4283 synchronized (mProcessCpuThread) { 4284 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4285 } 4286 info.append(processCpuTracker.printCurrentLoad()); 4287 info.append(cpuInfo); 4288 } 4289 4290 info.append(processCpuTracker.printCurrentState(anrTime)); 4291 4292 Slog.e(TAG, info.toString()); 4293 if (tracesFile == null) { 4294 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4295 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4296 } 4297 4298 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4299 cpuInfo, tracesFile, null); 4300 4301 if (mController != null) { 4302 try { 4303 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4304 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4305 if (res != 0) { 4306 if (res < 0 && app.pid != MY_PID) { 4307 Process.killProcess(app.pid); 4308 } else { 4309 synchronized (this) { 4310 mServices.scheduleServiceTimeoutLocked(app); 4311 } 4312 } 4313 return; 4314 } 4315 } catch (RemoteException e) { 4316 mController = null; 4317 Watchdog.getInstance().setActivityController(null); 4318 } 4319 } 4320 4321 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4322 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4323 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4324 4325 synchronized (this) { 4326 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4327 killUnneededProcessLocked(app, "background ANR"); 4328 return; 4329 } 4330 4331 // Set the app's notResponding state, and look up the errorReportReceiver 4332 makeAppNotRespondingLocked(app, 4333 activity != null ? activity.shortComponentName : null, 4334 annotation != null ? "ANR " + annotation : "ANR", 4335 info.toString()); 4336 4337 // Bring up the infamous App Not Responding dialog 4338 Message msg = Message.obtain(); 4339 HashMap<String, Object> map = new HashMap<String, Object>(); 4340 msg.what = SHOW_NOT_RESPONDING_MSG; 4341 msg.obj = map; 4342 msg.arg1 = aboveSystem ? 1 : 0; 4343 map.put("app", app); 4344 if (activity != null) { 4345 map.put("activity", activity); 4346 } 4347 4348 mHandler.sendMessage(msg); 4349 } 4350 } 4351 4352 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4353 if (!mLaunchWarningShown) { 4354 mLaunchWarningShown = true; 4355 mHandler.post(new Runnable() { 4356 @Override 4357 public void run() { 4358 synchronized (ActivityManagerService.this) { 4359 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4360 d.show(); 4361 mHandler.postDelayed(new Runnable() { 4362 @Override 4363 public void run() { 4364 synchronized (ActivityManagerService.this) { 4365 d.dismiss(); 4366 mLaunchWarningShown = false; 4367 } 4368 } 4369 }, 4000); 4370 } 4371 } 4372 }); 4373 } 4374 } 4375 4376 @Override 4377 public boolean clearApplicationUserData(final String packageName, 4378 final IPackageDataObserver observer, int userId) { 4379 enforceNotIsolatedCaller("clearApplicationUserData"); 4380 int uid = Binder.getCallingUid(); 4381 int pid = Binder.getCallingPid(); 4382 userId = handleIncomingUser(pid, uid, 4383 userId, false, true, "clearApplicationUserData", null); 4384 long callingId = Binder.clearCallingIdentity(); 4385 try { 4386 IPackageManager pm = AppGlobals.getPackageManager(); 4387 int pkgUid = -1; 4388 synchronized(this) { 4389 try { 4390 pkgUid = pm.getPackageUid(packageName, userId); 4391 } catch (RemoteException e) { 4392 } 4393 if (pkgUid == -1) { 4394 Slog.w(TAG, "Invalid packageName: " + packageName); 4395 if (observer != null) { 4396 try { 4397 observer.onRemoveCompleted(packageName, false); 4398 } catch (RemoteException e) { 4399 Slog.i(TAG, "Observer no longer exists."); 4400 } 4401 } 4402 return false; 4403 } 4404 if (uid == pkgUid || checkComponentPermission( 4405 android.Manifest.permission.CLEAR_APP_USER_DATA, 4406 pid, uid, -1, true) 4407 == PackageManager.PERMISSION_GRANTED) { 4408 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4409 } else { 4410 throw new SecurityException("PID " + pid + " does not have permission " 4411 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4412 + " of package " + packageName); 4413 } 4414 } 4415 4416 try { 4417 // Clear application user data 4418 pm.clearApplicationUserData(packageName, observer, userId); 4419 4420 // Remove all permissions granted from/to this package 4421 removeUriPermissionsForPackageLocked(packageName, userId, true); 4422 4423 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4424 Uri.fromParts("package", packageName, null)); 4425 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4426 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4427 null, null, 0, null, null, null, false, false, userId); 4428 } catch (RemoteException e) { 4429 } 4430 } finally { 4431 Binder.restoreCallingIdentity(callingId); 4432 } 4433 return true; 4434 } 4435 4436 @Override 4437 public void killBackgroundProcesses(final String packageName, int userId) { 4438 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4439 != PackageManager.PERMISSION_GRANTED && 4440 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4441 != PackageManager.PERMISSION_GRANTED) { 4442 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4443 + Binder.getCallingPid() 4444 + ", uid=" + Binder.getCallingUid() 4445 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4446 Slog.w(TAG, msg); 4447 throw new SecurityException(msg); 4448 } 4449 4450 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4451 userId, true, true, "killBackgroundProcesses", null); 4452 long callingId = Binder.clearCallingIdentity(); 4453 try { 4454 IPackageManager pm = AppGlobals.getPackageManager(); 4455 synchronized(this) { 4456 int appId = -1; 4457 try { 4458 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4459 } catch (RemoteException e) { 4460 } 4461 if (appId == -1) { 4462 Slog.w(TAG, "Invalid packageName: " + packageName); 4463 return; 4464 } 4465 killPackageProcessesLocked(packageName, appId, userId, 4466 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4467 } 4468 } finally { 4469 Binder.restoreCallingIdentity(callingId); 4470 } 4471 } 4472 4473 @Override 4474 public void killAllBackgroundProcesses() { 4475 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4476 != PackageManager.PERMISSION_GRANTED) { 4477 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4478 + Binder.getCallingPid() 4479 + ", uid=" + Binder.getCallingUid() 4480 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4481 Slog.w(TAG, msg); 4482 throw new SecurityException(msg); 4483 } 4484 4485 long callingId = Binder.clearCallingIdentity(); 4486 try { 4487 synchronized(this) { 4488 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4489 final int NP = mProcessNames.getMap().size(); 4490 for (int ip=0; ip<NP; ip++) { 4491 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4492 final int NA = apps.size(); 4493 for (int ia=0; ia<NA; ia++) { 4494 ProcessRecord app = apps.valueAt(ia); 4495 if (app.persistent) { 4496 // we don't kill persistent processes 4497 continue; 4498 } 4499 if (app.removed) { 4500 procs.add(app); 4501 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4502 app.removed = true; 4503 procs.add(app); 4504 } 4505 } 4506 } 4507 4508 int N = procs.size(); 4509 for (int i=0; i<N; i++) { 4510 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4511 } 4512 mAllowLowerMemLevel = true; 4513 updateOomAdjLocked(); 4514 doLowMemReportIfNeededLocked(null); 4515 } 4516 } finally { 4517 Binder.restoreCallingIdentity(callingId); 4518 } 4519 } 4520 4521 @Override 4522 public void forceStopPackage(final String packageName, int userId) { 4523 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4524 != PackageManager.PERMISSION_GRANTED) { 4525 String msg = "Permission Denial: forceStopPackage() from pid=" 4526 + Binder.getCallingPid() 4527 + ", uid=" + Binder.getCallingUid() 4528 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4529 Slog.w(TAG, msg); 4530 throw new SecurityException(msg); 4531 } 4532 final int callingPid = Binder.getCallingPid(); 4533 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4534 userId, true, true, "forceStopPackage", null); 4535 long callingId = Binder.clearCallingIdentity(); 4536 try { 4537 IPackageManager pm = AppGlobals.getPackageManager(); 4538 synchronized(this) { 4539 int[] users = userId == UserHandle.USER_ALL 4540 ? getUsersLocked() : new int[] { userId }; 4541 for (int user : users) { 4542 int pkgUid = -1; 4543 try { 4544 pkgUid = pm.getPackageUid(packageName, user); 4545 } catch (RemoteException e) { 4546 } 4547 if (pkgUid == -1) { 4548 Slog.w(TAG, "Invalid packageName: " + packageName); 4549 continue; 4550 } 4551 try { 4552 pm.setPackageStoppedState(packageName, true, user); 4553 } catch (RemoteException e) { 4554 } catch (IllegalArgumentException e) { 4555 Slog.w(TAG, "Failed trying to unstop package " 4556 + packageName + ": " + e); 4557 } 4558 if (isUserRunningLocked(user, false)) { 4559 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4560 } 4561 } 4562 } 4563 } finally { 4564 Binder.restoreCallingIdentity(callingId); 4565 } 4566 } 4567 4568 /* 4569 * The pkg name and app id have to be specified. 4570 */ 4571 @Override 4572 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4573 if (pkg == null) { 4574 return; 4575 } 4576 // Make sure the uid is valid. 4577 if (appid < 0) { 4578 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4579 return; 4580 } 4581 int callerUid = Binder.getCallingUid(); 4582 // Only the system server can kill an application 4583 if (callerUid == Process.SYSTEM_UID) { 4584 // Post an aysnc message to kill the application 4585 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4586 msg.arg1 = appid; 4587 msg.arg2 = 0; 4588 Bundle bundle = new Bundle(); 4589 bundle.putString("pkg", pkg); 4590 bundle.putString("reason", reason); 4591 msg.obj = bundle; 4592 mHandler.sendMessage(msg); 4593 } else { 4594 throw new SecurityException(callerUid + " cannot kill pkg: " + 4595 pkg); 4596 } 4597 } 4598 4599 @Override 4600 public void closeSystemDialogs(String reason) { 4601 enforceNotIsolatedCaller("closeSystemDialogs"); 4602 4603 final int pid = Binder.getCallingPid(); 4604 final int uid = Binder.getCallingUid(); 4605 final long origId = Binder.clearCallingIdentity(); 4606 try { 4607 synchronized (this) { 4608 // Only allow this from foreground processes, so that background 4609 // applications can't abuse it to prevent system UI from being shown. 4610 if (uid >= Process.FIRST_APPLICATION_UID) { 4611 ProcessRecord proc; 4612 synchronized (mPidsSelfLocked) { 4613 proc = mPidsSelfLocked.get(pid); 4614 } 4615 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4616 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4617 + " from background process " + proc); 4618 return; 4619 } 4620 } 4621 closeSystemDialogsLocked(reason); 4622 } 4623 } finally { 4624 Binder.restoreCallingIdentity(origId); 4625 } 4626 } 4627 4628 void closeSystemDialogsLocked(String reason) { 4629 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4630 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4631 | Intent.FLAG_RECEIVER_FOREGROUND); 4632 if (reason != null) { 4633 intent.putExtra("reason", reason); 4634 } 4635 mWindowManager.closeSystemDialogs(reason); 4636 4637 mStackSupervisor.closeSystemDialogsLocked(); 4638 4639 broadcastIntentLocked(null, null, intent, null, 4640 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4641 Process.SYSTEM_UID, UserHandle.USER_ALL); 4642 } 4643 4644 @Override 4645 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4646 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4647 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4648 for (int i=pids.length-1; i>=0; i--) { 4649 ProcessRecord proc; 4650 int oomAdj; 4651 synchronized (this) { 4652 synchronized (mPidsSelfLocked) { 4653 proc = mPidsSelfLocked.get(pids[i]); 4654 oomAdj = proc != null ? proc.setAdj : 0; 4655 } 4656 } 4657 infos[i] = new Debug.MemoryInfo(); 4658 Debug.getMemoryInfo(pids[i], infos[i]); 4659 if (proc != null) { 4660 synchronized (this) { 4661 if (proc.thread != null && proc.setAdj == oomAdj) { 4662 // Record this for posterity if the process has been stable. 4663 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4664 infos[i].getTotalUss(), false, proc.pkgList); 4665 } 4666 } 4667 } 4668 } 4669 return infos; 4670 } 4671 4672 @Override 4673 public long[] getProcessPss(int[] pids) { 4674 enforceNotIsolatedCaller("getProcessPss"); 4675 long[] pss = new long[pids.length]; 4676 for (int i=pids.length-1; i>=0; i--) { 4677 ProcessRecord proc; 4678 int oomAdj; 4679 synchronized (this) { 4680 synchronized (mPidsSelfLocked) { 4681 proc = mPidsSelfLocked.get(pids[i]); 4682 oomAdj = proc != null ? proc.setAdj : 0; 4683 } 4684 } 4685 long[] tmpUss = new long[1]; 4686 pss[i] = Debug.getPss(pids[i], tmpUss); 4687 if (proc != null) { 4688 synchronized (this) { 4689 if (proc.thread != null && proc.setAdj == oomAdj) { 4690 // Record this for posterity if the process has been stable. 4691 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4692 } 4693 } 4694 } 4695 } 4696 return pss; 4697 } 4698 4699 @Override 4700 public void killApplicationProcess(String processName, int uid) { 4701 if (processName == null) { 4702 return; 4703 } 4704 4705 int callerUid = Binder.getCallingUid(); 4706 // Only the system server can kill an application 4707 if (callerUid == Process.SYSTEM_UID) { 4708 synchronized (this) { 4709 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4710 if (app != null && app.thread != null) { 4711 try { 4712 app.thread.scheduleSuicide(); 4713 } catch (RemoteException e) { 4714 // If the other end already died, then our work here is done. 4715 } 4716 } else { 4717 Slog.w(TAG, "Process/uid not found attempting kill of " 4718 + processName + " / " + uid); 4719 } 4720 } 4721 } else { 4722 throw new SecurityException(callerUid + " cannot kill app process: " + 4723 processName); 4724 } 4725 } 4726 4727 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4728 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4729 false, true, false, false, UserHandle.getUserId(uid), reason); 4730 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4731 Uri.fromParts("package", packageName, null)); 4732 if (!mProcessesReady) { 4733 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4734 | Intent.FLAG_RECEIVER_FOREGROUND); 4735 } 4736 intent.putExtra(Intent.EXTRA_UID, uid); 4737 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4738 broadcastIntentLocked(null, null, intent, 4739 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4740 false, false, 4741 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4742 } 4743 4744 private void forceStopUserLocked(int userId, String reason) { 4745 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4746 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4747 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4748 | Intent.FLAG_RECEIVER_FOREGROUND); 4749 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4750 broadcastIntentLocked(null, null, intent, 4751 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4752 false, false, 4753 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4754 } 4755 4756 private final boolean killPackageProcessesLocked(String packageName, int appId, 4757 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4758 boolean doit, boolean evenPersistent, String reason) { 4759 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4760 4761 // Remove all processes this package may have touched: all with the 4762 // same UID (except for the system or root user), and all whose name 4763 // matches the package name. 4764 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4765 final int NP = mProcessNames.getMap().size(); 4766 for (int ip=0; ip<NP; ip++) { 4767 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4768 final int NA = apps.size(); 4769 for (int ia=0; ia<NA; ia++) { 4770 ProcessRecord app = apps.valueAt(ia); 4771 if (app.persistent && !evenPersistent) { 4772 // we don't kill persistent processes 4773 continue; 4774 } 4775 if (app.removed) { 4776 if (doit) { 4777 procs.add(app); 4778 } 4779 continue; 4780 } 4781 4782 // Skip process if it doesn't meet our oom adj requirement. 4783 if (app.setAdj < minOomAdj) { 4784 continue; 4785 } 4786 4787 // If no package is specified, we call all processes under the 4788 // give user id. 4789 if (packageName == null) { 4790 if (app.userId != userId) { 4791 continue; 4792 } 4793 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4794 continue; 4795 } 4796 // Package has been specified, we want to hit all processes 4797 // that match it. We need to qualify this by the processes 4798 // that are running under the specified app and user ID. 4799 } else { 4800 if (UserHandle.getAppId(app.uid) != appId) { 4801 continue; 4802 } 4803 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4804 continue; 4805 } 4806 if (!app.pkgList.containsKey(packageName)) { 4807 continue; 4808 } 4809 } 4810 4811 // Process has passed all conditions, kill it! 4812 if (!doit) { 4813 return true; 4814 } 4815 app.removed = true; 4816 procs.add(app); 4817 } 4818 } 4819 4820 int N = procs.size(); 4821 for (int i=0; i<N; i++) { 4822 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4823 } 4824 updateOomAdjLocked(); 4825 return N > 0; 4826 } 4827 4828 private final boolean forceStopPackageLocked(String name, int appId, 4829 boolean callerWillRestart, boolean purgeCache, boolean doit, 4830 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4831 int i; 4832 int N; 4833 4834 if (userId == UserHandle.USER_ALL && name == null) { 4835 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4836 } 4837 4838 if (appId < 0 && name != null) { 4839 try { 4840 appId = UserHandle.getAppId( 4841 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4842 } catch (RemoteException e) { 4843 } 4844 } 4845 4846 if (doit) { 4847 if (name != null) { 4848 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4849 + " user=" + userId + ": " + reason); 4850 } else { 4851 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4852 } 4853 4854 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4855 for (int ip=pmap.size()-1; ip>=0; ip--) { 4856 SparseArray<Long> ba = pmap.valueAt(ip); 4857 for (i=ba.size()-1; i>=0; i--) { 4858 boolean remove = false; 4859 final int entUid = ba.keyAt(i); 4860 if (name != null) { 4861 if (userId == UserHandle.USER_ALL) { 4862 if (UserHandle.getAppId(entUid) == appId) { 4863 remove = true; 4864 } 4865 } else { 4866 if (entUid == UserHandle.getUid(userId, appId)) { 4867 remove = true; 4868 } 4869 } 4870 } else if (UserHandle.getUserId(entUid) == userId) { 4871 remove = true; 4872 } 4873 if (remove) { 4874 ba.removeAt(i); 4875 } 4876 } 4877 if (ba.size() == 0) { 4878 pmap.removeAt(ip); 4879 } 4880 } 4881 } 4882 4883 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4884 -100, callerWillRestart, true, doit, evenPersistent, 4885 name == null ? ("stop user " + userId) : ("stop " + name)); 4886 4887 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4888 if (!doit) { 4889 return true; 4890 } 4891 didSomething = true; 4892 } 4893 4894 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4895 if (!doit) { 4896 return true; 4897 } 4898 didSomething = true; 4899 } 4900 4901 if (name == null) { 4902 // Remove all sticky broadcasts from this user. 4903 mStickyBroadcasts.remove(userId); 4904 } 4905 4906 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4907 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4908 userId, providers)) { 4909 if (!doit) { 4910 return true; 4911 } 4912 didSomething = true; 4913 } 4914 N = providers.size(); 4915 for (i=0; i<N; i++) { 4916 removeDyingProviderLocked(null, providers.get(i), true); 4917 } 4918 4919 // Remove transient permissions granted from/to this package/user 4920 removeUriPermissionsForPackageLocked(name, userId, false); 4921 4922 if (name == null || uninstalling) { 4923 // Remove pending intents. For now we only do this when force 4924 // stopping users, because we have some problems when doing this 4925 // for packages -- app widgets are not currently cleaned up for 4926 // such packages, so they can be left with bad pending intents. 4927 if (mIntentSenderRecords.size() > 0) { 4928 Iterator<WeakReference<PendingIntentRecord>> it 4929 = mIntentSenderRecords.values().iterator(); 4930 while (it.hasNext()) { 4931 WeakReference<PendingIntentRecord> wpir = it.next(); 4932 if (wpir == null) { 4933 it.remove(); 4934 continue; 4935 } 4936 PendingIntentRecord pir = wpir.get(); 4937 if (pir == null) { 4938 it.remove(); 4939 continue; 4940 } 4941 if (name == null) { 4942 // Stopping user, remove all objects for the user. 4943 if (pir.key.userId != userId) { 4944 // Not the same user, skip it. 4945 continue; 4946 } 4947 } else { 4948 if (UserHandle.getAppId(pir.uid) != appId) { 4949 // Different app id, skip it. 4950 continue; 4951 } 4952 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4953 // Different user, skip it. 4954 continue; 4955 } 4956 if (!pir.key.packageName.equals(name)) { 4957 // Different package, skip it. 4958 continue; 4959 } 4960 } 4961 if (!doit) { 4962 return true; 4963 } 4964 didSomething = true; 4965 it.remove(); 4966 pir.canceled = true; 4967 if (pir.key.activity != null) { 4968 pir.key.activity.pendingResults.remove(pir.ref); 4969 } 4970 } 4971 } 4972 } 4973 4974 if (doit) { 4975 if (purgeCache && name != null) { 4976 AttributeCache ac = AttributeCache.instance(); 4977 if (ac != null) { 4978 ac.removePackage(name); 4979 } 4980 } 4981 if (mBooted) { 4982 mStackSupervisor.resumeTopActivitiesLocked(); 4983 mStackSupervisor.scheduleIdleLocked(); 4984 } 4985 } 4986 4987 return didSomething; 4988 } 4989 4990 private final boolean removeProcessLocked(ProcessRecord app, 4991 boolean callerWillRestart, boolean allowRestart, String reason) { 4992 final String name = app.processName; 4993 final int uid = app.uid; 4994 if (DEBUG_PROCESSES) Slog.d( 4995 TAG, "Force removing proc " + app.toShortString() + " (" + name 4996 + "/" + uid + ")"); 4997 4998 mProcessNames.remove(name, uid); 4999 mIsolatedProcesses.remove(app.uid); 5000 if (mHeavyWeightProcess == app) { 5001 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5002 mHeavyWeightProcess.userId, 0)); 5003 mHeavyWeightProcess = null; 5004 } 5005 boolean needRestart = false; 5006 if (app.pid > 0 && app.pid != MY_PID) { 5007 int pid = app.pid; 5008 synchronized (mPidsSelfLocked) { 5009 mPidsSelfLocked.remove(pid); 5010 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5011 } 5012 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5013 app.processName, app.info.uid); 5014 if (app.isolated) { 5015 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5016 } 5017 killUnneededProcessLocked(app, reason); 5018 handleAppDiedLocked(app, true, allowRestart); 5019 removeLruProcessLocked(app); 5020 5021 if (app.persistent && !app.isolated) { 5022 if (!callerWillRestart) { 5023 addAppLocked(app.info, false); 5024 } else { 5025 needRestart = true; 5026 } 5027 } 5028 } else { 5029 mRemovedProcesses.add(app); 5030 } 5031 5032 return needRestart; 5033 } 5034 5035 private final void processStartTimedOutLocked(ProcessRecord app) { 5036 final int pid = app.pid; 5037 boolean gone = false; 5038 synchronized (mPidsSelfLocked) { 5039 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5040 if (knownApp != null && knownApp.thread == null) { 5041 mPidsSelfLocked.remove(pid); 5042 gone = true; 5043 } 5044 } 5045 5046 if (gone) { 5047 Slog.w(TAG, "Process " + app + " failed to attach"); 5048 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5049 pid, app.uid, app.processName); 5050 mProcessNames.remove(app.processName, app.uid); 5051 mIsolatedProcesses.remove(app.uid); 5052 if (mHeavyWeightProcess == app) { 5053 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5054 mHeavyWeightProcess.userId, 0)); 5055 mHeavyWeightProcess = null; 5056 } 5057 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5058 app.processName, app.info.uid); 5059 if (app.isolated) { 5060 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5061 } 5062 // Take care of any launching providers waiting for this process. 5063 checkAppInLaunchingProvidersLocked(app, true); 5064 // Take care of any services that are waiting for the process. 5065 mServices.processStartTimedOutLocked(app); 5066 killUnneededProcessLocked(app, "start timeout"); 5067 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5068 Slog.w(TAG, "Unattached app died before backup, skipping"); 5069 try { 5070 IBackupManager bm = IBackupManager.Stub.asInterface( 5071 ServiceManager.getService(Context.BACKUP_SERVICE)); 5072 bm.agentDisconnected(app.info.packageName); 5073 } catch (RemoteException e) { 5074 // Can't happen; the backup manager is local 5075 } 5076 } 5077 if (isPendingBroadcastProcessLocked(pid)) { 5078 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5079 skipPendingBroadcastLocked(pid); 5080 } 5081 } else { 5082 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5083 } 5084 } 5085 5086 private final boolean attachApplicationLocked(IApplicationThread thread, 5087 int pid) { 5088 5089 // Find the application record that is being attached... either via 5090 // the pid if we are running in multiple processes, or just pull the 5091 // next app record if we are emulating process with anonymous threads. 5092 ProcessRecord app; 5093 if (pid != MY_PID && pid >= 0) { 5094 synchronized (mPidsSelfLocked) { 5095 app = mPidsSelfLocked.get(pid); 5096 } 5097 } else { 5098 app = null; 5099 } 5100 5101 if (app == null) { 5102 Slog.w(TAG, "No pending application record for pid " + pid 5103 + " (IApplicationThread " + thread + "); dropping process"); 5104 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5105 if (pid > 0 && pid != MY_PID) { 5106 Process.killProcessQuiet(pid); 5107 } else { 5108 try { 5109 thread.scheduleExit(); 5110 } catch (Exception e) { 5111 // Ignore exceptions. 5112 } 5113 } 5114 return false; 5115 } 5116 5117 // If this application record is still attached to a previous 5118 // process, clean it up now. 5119 if (app.thread != null) { 5120 handleAppDiedLocked(app, true, true); 5121 } 5122 5123 // Tell the process all about itself. 5124 5125 if (localLOGV) Slog.v( 5126 TAG, "Binding process pid " + pid + " to record " + app); 5127 5128 final String processName = app.processName; 5129 try { 5130 AppDeathRecipient adr = new AppDeathRecipient( 5131 app, pid, thread); 5132 thread.asBinder().linkToDeath(adr, 0); 5133 app.deathRecipient = adr; 5134 } catch (RemoteException e) { 5135 app.resetPackageList(mProcessStats); 5136 startProcessLocked(app, "link fail", processName); 5137 return false; 5138 } 5139 5140 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5141 5142 app.makeActive(thread, mProcessStats); 5143 app.curAdj = app.setAdj = -100; 5144 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5145 app.forcingToForeground = null; 5146 updateProcessForegroundLocked(app, false, false); 5147 app.hasShownUi = false; 5148 app.debugging = false; 5149 app.cached = false; 5150 5151 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5152 5153 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5154 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5155 5156 if (!normalMode) { 5157 Slog.i(TAG, "Launching preboot mode app: " + app); 5158 } 5159 5160 if (localLOGV) Slog.v( 5161 TAG, "New app record " + app 5162 + " thread=" + thread.asBinder() + " pid=" + pid); 5163 try { 5164 int testMode = IApplicationThread.DEBUG_OFF; 5165 if (mDebugApp != null && mDebugApp.equals(processName)) { 5166 testMode = mWaitForDebugger 5167 ? IApplicationThread.DEBUG_WAIT 5168 : IApplicationThread.DEBUG_ON; 5169 app.debugging = true; 5170 if (mDebugTransient) { 5171 mDebugApp = mOrigDebugApp; 5172 mWaitForDebugger = mOrigWaitForDebugger; 5173 } 5174 } 5175 String profileFile = app.instrumentationProfileFile; 5176 ParcelFileDescriptor profileFd = null; 5177 boolean profileAutoStop = false; 5178 if (mProfileApp != null && mProfileApp.equals(processName)) { 5179 mProfileProc = app; 5180 profileFile = mProfileFile; 5181 profileFd = mProfileFd; 5182 profileAutoStop = mAutoStopProfiler; 5183 } 5184 boolean enableOpenGlTrace = false; 5185 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5186 enableOpenGlTrace = true; 5187 mOpenGlTraceApp = null; 5188 } 5189 5190 // If the app is being launched for restore or full backup, set it up specially 5191 boolean isRestrictedBackupMode = false; 5192 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5193 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5194 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5195 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5196 } 5197 5198 ensurePackageDexOpt(app.instrumentationInfo != null 5199 ? app.instrumentationInfo.packageName 5200 : app.info.packageName); 5201 if (app.instrumentationClass != null) { 5202 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5203 } 5204 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5205 + processName + " with config " + mConfiguration); 5206 ApplicationInfo appInfo = app.instrumentationInfo != null 5207 ? app.instrumentationInfo : app.info; 5208 app.compat = compatibilityInfoForPackageLocked(appInfo); 5209 if (profileFd != null) { 5210 profileFd = profileFd.dup(); 5211 } 5212 thread.bindApplication(processName, appInfo, providers, 5213 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5214 app.instrumentationArguments, app.instrumentationWatcher, 5215 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5216 isRestrictedBackupMode || !normalMode, app.persistent, 5217 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5218 mCoreSettingsObserver.getCoreSettingsLocked()); 5219 updateLruProcessLocked(app, false, null); 5220 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5221 } catch (Exception e) { 5222 // todo: Yikes! What should we do? For now we will try to 5223 // start another process, but that could easily get us in 5224 // an infinite loop of restarting processes... 5225 Slog.w(TAG, "Exception thrown during bind!", e); 5226 5227 app.resetPackageList(mProcessStats); 5228 app.unlinkDeathRecipient(); 5229 startProcessLocked(app, "bind fail", processName); 5230 return false; 5231 } 5232 5233 // Remove this record from the list of starting applications. 5234 mPersistentStartingProcesses.remove(app); 5235 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5236 "Attach application locked removing on hold: " + app); 5237 mProcessesOnHold.remove(app); 5238 5239 boolean badApp = false; 5240 boolean didSomething = false; 5241 5242 // See if the top visible activity is waiting to run in this process... 5243 if (normalMode) { 5244 try { 5245 if (mStackSupervisor.attachApplicationLocked(app)) { 5246 didSomething = true; 5247 } 5248 } catch (Exception e) { 5249 badApp = true; 5250 } 5251 } 5252 5253 // Find any services that should be running in this process... 5254 if (!badApp) { 5255 try { 5256 didSomething |= mServices.attachApplicationLocked(app, processName); 5257 } catch (Exception e) { 5258 badApp = true; 5259 } 5260 } 5261 5262 // Check if a next-broadcast receiver is in this process... 5263 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5264 try { 5265 didSomething |= sendPendingBroadcastsLocked(app); 5266 } catch (Exception e) { 5267 // If the app died trying to launch the receiver we declare it 'bad' 5268 badApp = true; 5269 } 5270 } 5271 5272 // Check whether the next backup agent is in this process... 5273 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5274 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5275 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5276 try { 5277 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5278 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5279 mBackupTarget.backupMode); 5280 } catch (Exception e) { 5281 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5282 e.printStackTrace(); 5283 } 5284 } 5285 5286 if (badApp) { 5287 // todo: Also need to kill application to deal with all 5288 // kinds of exceptions. 5289 handleAppDiedLocked(app, false, true); 5290 return false; 5291 } 5292 5293 if (!didSomething) { 5294 updateOomAdjLocked(); 5295 } 5296 5297 return true; 5298 } 5299 5300 @Override 5301 public final void attachApplication(IApplicationThread thread) { 5302 synchronized (this) { 5303 int callingPid = Binder.getCallingPid(); 5304 final long origId = Binder.clearCallingIdentity(); 5305 attachApplicationLocked(thread, callingPid); 5306 Binder.restoreCallingIdentity(origId); 5307 } 5308 } 5309 5310 @Override 5311 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5312 final long origId = Binder.clearCallingIdentity(); 5313 synchronized (this) { 5314 ActivityStack stack = ActivityRecord.getStackLocked(token); 5315 if (stack != null) { 5316 ActivityRecord r = 5317 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5318 if (stopProfiling) { 5319 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5320 try { 5321 mProfileFd.close(); 5322 } catch (IOException e) { 5323 } 5324 clearProfilerLocked(); 5325 } 5326 } 5327 } 5328 } 5329 Binder.restoreCallingIdentity(origId); 5330 } 5331 5332 void enableScreenAfterBoot() { 5333 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5334 SystemClock.uptimeMillis()); 5335 mWindowManager.enableScreenAfterBoot(); 5336 5337 synchronized (this) { 5338 updateEventDispatchingLocked(); 5339 } 5340 } 5341 5342 @Override 5343 public void showBootMessage(final CharSequence msg, final boolean always) { 5344 enforceNotIsolatedCaller("showBootMessage"); 5345 mWindowManager.showBootMessage(msg, always); 5346 } 5347 5348 @Override 5349 public void dismissKeyguardOnNextActivity() { 5350 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5351 final long token = Binder.clearCallingIdentity(); 5352 try { 5353 synchronized (this) { 5354 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5355 if (mLockScreenShown) { 5356 mLockScreenShown = false; 5357 comeOutOfSleepIfNeededLocked(); 5358 } 5359 mStackSupervisor.setDismissKeyguard(true); 5360 } 5361 } finally { 5362 Binder.restoreCallingIdentity(token); 5363 } 5364 } 5365 5366 final void finishBooting() { 5367 // Register receivers to handle package update events 5368 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5369 5370 synchronized (this) { 5371 // Ensure that any processes we had put on hold are now started 5372 // up. 5373 final int NP = mProcessesOnHold.size(); 5374 if (NP > 0) { 5375 ArrayList<ProcessRecord> procs = 5376 new ArrayList<ProcessRecord>(mProcessesOnHold); 5377 for (int ip=0; ip<NP; ip++) { 5378 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5379 + procs.get(ip)); 5380 startProcessLocked(procs.get(ip), "on-hold", null); 5381 } 5382 } 5383 5384 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5385 // Start looking for apps that are abusing wake locks. 5386 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5387 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5388 // Tell anyone interested that we are done booting! 5389 SystemProperties.set("sys.boot_completed", "1"); 5390 SystemProperties.set("dev.bootcomplete", "1"); 5391 for (int i=0; i<mStartedUsers.size(); i++) { 5392 UserStartedState uss = mStartedUsers.valueAt(i); 5393 if (uss.mState == UserStartedState.STATE_BOOTING) { 5394 uss.mState = UserStartedState.STATE_RUNNING; 5395 final int userId = mStartedUsers.keyAt(i); 5396 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5397 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5398 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5399 broadcastIntentLocked(null, null, intent, null, 5400 new IIntentReceiver.Stub() { 5401 @Override 5402 public void performReceive(Intent intent, int resultCode, 5403 String data, Bundle extras, boolean ordered, 5404 boolean sticky, int sendingUser) { 5405 synchronized (ActivityManagerService.this) { 5406 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5407 true, false); 5408 } 5409 } 5410 }, 5411 0, null, null, 5412 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5413 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5414 userId); 5415 } 5416 } 5417 scheduleStartProfilesLocked(); 5418 } 5419 } 5420 } 5421 5422 final void ensureBootCompleted() { 5423 boolean booting; 5424 boolean enableScreen; 5425 synchronized (this) { 5426 booting = mBooting; 5427 mBooting = false; 5428 enableScreen = !mBooted; 5429 mBooted = true; 5430 } 5431 5432 if (booting) { 5433 finishBooting(); 5434 } 5435 5436 if (enableScreen) { 5437 enableScreenAfterBoot(); 5438 } 5439 } 5440 5441 @Override 5442 public final void activityResumed(IBinder token) { 5443 final long origId = Binder.clearCallingIdentity(); 5444 synchronized(this) { 5445 ActivityStack stack = ActivityRecord.getStackLocked(token); 5446 if (stack != null) { 5447 ActivityRecord.activityResumedLocked(token); 5448 } 5449 } 5450 Binder.restoreCallingIdentity(origId); 5451 } 5452 5453 @Override 5454 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5455 final long origId = Binder.clearCallingIdentity(); 5456 synchronized(this) { 5457 ActivityStack stack = ActivityRecord.getStackLocked(token); 5458 if (stack != null) { 5459 stack.activityPausedLocked(token, false, persistentState); 5460 } 5461 } 5462 Binder.restoreCallingIdentity(origId); 5463 } 5464 5465 @Override 5466 public final void activityStopped(IBinder token, Bundle icicle, 5467 PersistableBundle persistentState, CharSequence description) { 5468 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5469 5470 // Refuse possible leaked file descriptors 5471 if (icicle != null && icicle.hasFileDescriptors()) { 5472 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5473 } 5474 5475 final long origId = Binder.clearCallingIdentity(); 5476 5477 synchronized (this) { 5478 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5479 if (r != null) { 5480 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5481 } 5482 } 5483 5484 trimApplications(); 5485 5486 Binder.restoreCallingIdentity(origId); 5487 } 5488 5489 @Override 5490 public final void activityDestroyed(IBinder token) { 5491 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5492 synchronized (this) { 5493 ActivityStack stack = ActivityRecord.getStackLocked(token); 5494 if (stack != null) { 5495 stack.activityDestroyedLocked(token); 5496 } 5497 } 5498 } 5499 5500 @Override 5501 public String getCallingPackage(IBinder token) { 5502 synchronized (this) { 5503 ActivityRecord r = getCallingRecordLocked(token); 5504 return r != null ? r.info.packageName : null; 5505 } 5506 } 5507 5508 @Override 5509 public ComponentName getCallingActivity(IBinder token) { 5510 synchronized (this) { 5511 ActivityRecord r = getCallingRecordLocked(token); 5512 return r != null ? r.intent.getComponent() : null; 5513 } 5514 } 5515 5516 private ActivityRecord getCallingRecordLocked(IBinder token) { 5517 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5518 if (r == null) { 5519 return null; 5520 } 5521 return r.resultTo; 5522 } 5523 5524 @Override 5525 public ComponentName getActivityClassForToken(IBinder token) { 5526 synchronized(this) { 5527 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5528 if (r == null) { 5529 return null; 5530 } 5531 return r.intent.getComponent(); 5532 } 5533 } 5534 5535 @Override 5536 public String getPackageForToken(IBinder token) { 5537 synchronized(this) { 5538 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5539 if (r == null) { 5540 return null; 5541 } 5542 return r.packageName; 5543 } 5544 } 5545 5546 @Override 5547 public IIntentSender getIntentSender(int type, 5548 String packageName, IBinder token, String resultWho, 5549 int requestCode, Intent[] intents, String[] resolvedTypes, 5550 int flags, Bundle options, int userId) { 5551 enforceNotIsolatedCaller("getIntentSender"); 5552 // Refuse possible leaked file descriptors 5553 if (intents != null) { 5554 if (intents.length < 1) { 5555 throw new IllegalArgumentException("Intents array length must be >= 1"); 5556 } 5557 for (int i=0; i<intents.length; i++) { 5558 Intent intent = intents[i]; 5559 if (intent != null) { 5560 if (intent.hasFileDescriptors()) { 5561 throw new IllegalArgumentException("File descriptors passed in Intent"); 5562 } 5563 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5564 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5565 throw new IllegalArgumentException( 5566 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5567 } 5568 intents[i] = new Intent(intent); 5569 } 5570 } 5571 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5572 throw new IllegalArgumentException( 5573 "Intent array length does not match resolvedTypes length"); 5574 } 5575 } 5576 if (options != null) { 5577 if (options.hasFileDescriptors()) { 5578 throw new IllegalArgumentException("File descriptors passed in options"); 5579 } 5580 } 5581 5582 synchronized(this) { 5583 int callingUid = Binder.getCallingUid(); 5584 int origUserId = userId; 5585 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5586 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5587 "getIntentSender", null); 5588 if (origUserId == UserHandle.USER_CURRENT) { 5589 // We don't want to evaluate this until the pending intent is 5590 // actually executed. However, we do want to always do the 5591 // security checking for it above. 5592 userId = UserHandle.USER_CURRENT; 5593 } 5594 try { 5595 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5596 int uid = AppGlobals.getPackageManager() 5597 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5598 if (!UserHandle.isSameApp(callingUid, uid)) { 5599 String msg = "Permission Denial: getIntentSender() from pid=" 5600 + Binder.getCallingPid() 5601 + ", uid=" + Binder.getCallingUid() 5602 + ", (need uid=" + uid + ")" 5603 + " is not allowed to send as package " + packageName; 5604 Slog.w(TAG, msg); 5605 throw new SecurityException(msg); 5606 } 5607 } 5608 5609 return getIntentSenderLocked(type, packageName, callingUid, userId, 5610 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5611 5612 } catch (RemoteException e) { 5613 throw new SecurityException(e); 5614 } 5615 } 5616 } 5617 5618 IIntentSender getIntentSenderLocked(int type, String packageName, 5619 int callingUid, int userId, IBinder token, String resultWho, 5620 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5621 Bundle options) { 5622 if (DEBUG_MU) 5623 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5624 ActivityRecord activity = null; 5625 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5626 activity = ActivityRecord.isInStackLocked(token); 5627 if (activity == null) { 5628 return null; 5629 } 5630 if (activity.finishing) { 5631 return null; 5632 } 5633 } 5634 5635 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5636 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5637 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5638 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5639 |PendingIntent.FLAG_UPDATE_CURRENT); 5640 5641 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5642 type, packageName, activity, resultWho, 5643 requestCode, intents, resolvedTypes, flags, options, userId); 5644 WeakReference<PendingIntentRecord> ref; 5645 ref = mIntentSenderRecords.get(key); 5646 PendingIntentRecord rec = ref != null ? ref.get() : null; 5647 if (rec != null) { 5648 if (!cancelCurrent) { 5649 if (updateCurrent) { 5650 if (rec.key.requestIntent != null) { 5651 rec.key.requestIntent.replaceExtras(intents != null ? 5652 intents[intents.length - 1] : null); 5653 } 5654 if (intents != null) { 5655 intents[intents.length-1] = rec.key.requestIntent; 5656 rec.key.allIntents = intents; 5657 rec.key.allResolvedTypes = resolvedTypes; 5658 } else { 5659 rec.key.allIntents = null; 5660 rec.key.allResolvedTypes = null; 5661 } 5662 } 5663 return rec; 5664 } 5665 rec.canceled = true; 5666 mIntentSenderRecords.remove(key); 5667 } 5668 if (noCreate) { 5669 return rec; 5670 } 5671 rec = new PendingIntentRecord(this, key, callingUid); 5672 mIntentSenderRecords.put(key, rec.ref); 5673 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5674 if (activity.pendingResults == null) { 5675 activity.pendingResults 5676 = new HashSet<WeakReference<PendingIntentRecord>>(); 5677 } 5678 activity.pendingResults.add(rec.ref); 5679 } 5680 return rec; 5681 } 5682 5683 @Override 5684 public void cancelIntentSender(IIntentSender sender) { 5685 if (!(sender instanceof PendingIntentRecord)) { 5686 return; 5687 } 5688 synchronized(this) { 5689 PendingIntentRecord rec = (PendingIntentRecord)sender; 5690 try { 5691 int uid = AppGlobals.getPackageManager() 5692 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5693 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5694 String msg = "Permission Denial: cancelIntentSender() from pid=" 5695 + Binder.getCallingPid() 5696 + ", uid=" + Binder.getCallingUid() 5697 + " is not allowed to cancel packges " 5698 + rec.key.packageName; 5699 Slog.w(TAG, msg); 5700 throw new SecurityException(msg); 5701 } 5702 } catch (RemoteException e) { 5703 throw new SecurityException(e); 5704 } 5705 cancelIntentSenderLocked(rec, true); 5706 } 5707 } 5708 5709 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5710 rec.canceled = true; 5711 mIntentSenderRecords.remove(rec.key); 5712 if (cleanActivity && rec.key.activity != null) { 5713 rec.key.activity.pendingResults.remove(rec.ref); 5714 } 5715 } 5716 5717 @Override 5718 public String getPackageForIntentSender(IIntentSender pendingResult) { 5719 if (!(pendingResult instanceof PendingIntentRecord)) { 5720 return null; 5721 } 5722 try { 5723 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5724 return res.key.packageName; 5725 } catch (ClassCastException e) { 5726 } 5727 return null; 5728 } 5729 5730 @Override 5731 public int getUidForIntentSender(IIntentSender sender) { 5732 if (sender instanceof PendingIntentRecord) { 5733 try { 5734 PendingIntentRecord res = (PendingIntentRecord)sender; 5735 return res.uid; 5736 } catch (ClassCastException e) { 5737 } 5738 } 5739 return -1; 5740 } 5741 5742 @Override 5743 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5744 if (!(pendingResult instanceof PendingIntentRecord)) { 5745 return false; 5746 } 5747 try { 5748 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5749 if (res.key.allIntents == null) { 5750 return false; 5751 } 5752 for (int i=0; i<res.key.allIntents.length; i++) { 5753 Intent intent = res.key.allIntents[i]; 5754 if (intent.getPackage() != null && intent.getComponent() != null) { 5755 return false; 5756 } 5757 } 5758 return true; 5759 } catch (ClassCastException e) { 5760 } 5761 return false; 5762 } 5763 5764 @Override 5765 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5766 if (!(pendingResult instanceof PendingIntentRecord)) { 5767 return false; 5768 } 5769 try { 5770 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5771 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5772 return true; 5773 } 5774 return false; 5775 } catch (ClassCastException e) { 5776 } 5777 return false; 5778 } 5779 5780 @Override 5781 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5782 if (!(pendingResult instanceof PendingIntentRecord)) { 5783 return null; 5784 } 5785 try { 5786 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5787 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5788 } catch (ClassCastException e) { 5789 } 5790 return null; 5791 } 5792 5793 @Override 5794 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5795 if (!(pendingResult instanceof PendingIntentRecord)) { 5796 return null; 5797 } 5798 try { 5799 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5800 Intent intent = res.key.requestIntent; 5801 if (intent != null) { 5802 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5803 || res.lastTagPrefix.equals(prefix))) { 5804 return res.lastTag; 5805 } 5806 res.lastTagPrefix = prefix; 5807 StringBuilder sb = new StringBuilder(128); 5808 if (prefix != null) { 5809 sb.append(prefix); 5810 } 5811 if (intent.getAction() != null) { 5812 sb.append(intent.getAction()); 5813 } else if (intent.getComponent() != null) { 5814 intent.getComponent().appendShortString(sb); 5815 } else { 5816 sb.append("?"); 5817 } 5818 return res.lastTag = sb.toString(); 5819 } 5820 } catch (ClassCastException e) { 5821 } 5822 return null; 5823 } 5824 5825 @Override 5826 public void setProcessLimit(int max) { 5827 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5828 "setProcessLimit()"); 5829 synchronized (this) { 5830 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5831 mProcessLimitOverride = max; 5832 } 5833 trimApplications(); 5834 } 5835 5836 @Override 5837 public int getProcessLimit() { 5838 synchronized (this) { 5839 return mProcessLimitOverride; 5840 } 5841 } 5842 5843 void foregroundTokenDied(ForegroundToken token) { 5844 synchronized (ActivityManagerService.this) { 5845 synchronized (mPidsSelfLocked) { 5846 ForegroundToken cur 5847 = mForegroundProcesses.get(token.pid); 5848 if (cur != token) { 5849 return; 5850 } 5851 mForegroundProcesses.remove(token.pid); 5852 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5853 if (pr == null) { 5854 return; 5855 } 5856 pr.forcingToForeground = null; 5857 updateProcessForegroundLocked(pr, false, false); 5858 } 5859 updateOomAdjLocked(); 5860 } 5861 } 5862 5863 @Override 5864 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5865 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5866 "setProcessForeground()"); 5867 synchronized(this) { 5868 boolean changed = false; 5869 5870 synchronized (mPidsSelfLocked) { 5871 ProcessRecord pr = mPidsSelfLocked.get(pid); 5872 if (pr == null && isForeground) { 5873 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5874 return; 5875 } 5876 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5877 if (oldToken != null) { 5878 oldToken.token.unlinkToDeath(oldToken, 0); 5879 mForegroundProcesses.remove(pid); 5880 if (pr != null) { 5881 pr.forcingToForeground = null; 5882 } 5883 changed = true; 5884 } 5885 if (isForeground && token != null) { 5886 ForegroundToken newToken = new ForegroundToken() { 5887 @Override 5888 public void binderDied() { 5889 foregroundTokenDied(this); 5890 } 5891 }; 5892 newToken.pid = pid; 5893 newToken.token = token; 5894 try { 5895 token.linkToDeath(newToken, 0); 5896 mForegroundProcesses.put(pid, newToken); 5897 pr.forcingToForeground = token; 5898 changed = true; 5899 } catch (RemoteException e) { 5900 // If the process died while doing this, we will later 5901 // do the cleanup with the process death link. 5902 } 5903 } 5904 } 5905 5906 if (changed) { 5907 updateOomAdjLocked(); 5908 } 5909 } 5910 } 5911 5912 // ========================================================= 5913 // PERMISSIONS 5914 // ========================================================= 5915 5916 static class PermissionController extends IPermissionController.Stub { 5917 ActivityManagerService mActivityManagerService; 5918 PermissionController(ActivityManagerService activityManagerService) { 5919 mActivityManagerService = activityManagerService; 5920 } 5921 5922 @Override 5923 public boolean checkPermission(String permission, int pid, int uid) { 5924 return mActivityManagerService.checkPermission(permission, pid, 5925 uid) == PackageManager.PERMISSION_GRANTED; 5926 } 5927 } 5928 5929 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5930 @Override 5931 public int checkComponentPermission(String permission, int pid, int uid, 5932 int owningUid, boolean exported) { 5933 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5934 owningUid, exported); 5935 } 5936 5937 @Override 5938 public Object getAMSLock() { 5939 return ActivityManagerService.this; 5940 } 5941 } 5942 5943 /** 5944 * This can be called with or without the global lock held. 5945 */ 5946 int checkComponentPermission(String permission, int pid, int uid, 5947 int owningUid, boolean exported) { 5948 // We might be performing an operation on behalf of an indirect binder 5949 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5950 // client identity accordingly before proceeding. 5951 Identity tlsIdentity = sCallerIdentity.get(); 5952 if (tlsIdentity != null) { 5953 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5954 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5955 uid = tlsIdentity.uid; 5956 pid = tlsIdentity.pid; 5957 } 5958 5959 if (pid == MY_PID) { 5960 return PackageManager.PERMISSION_GRANTED; 5961 } 5962 5963 return ActivityManager.checkComponentPermission(permission, uid, 5964 owningUid, exported); 5965 } 5966 5967 /** 5968 * As the only public entry point for permissions checking, this method 5969 * can enforce the semantic that requesting a check on a null global 5970 * permission is automatically denied. (Internally a null permission 5971 * string is used when calling {@link #checkComponentPermission} in cases 5972 * when only uid-based security is needed.) 5973 * 5974 * This can be called with or without the global lock held. 5975 */ 5976 @Override 5977 public int checkPermission(String permission, int pid, int uid) { 5978 if (permission == null) { 5979 return PackageManager.PERMISSION_DENIED; 5980 } 5981 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5982 } 5983 5984 /** 5985 * Binder IPC calls go through the public entry point. 5986 * This can be called with or without the global lock held. 5987 */ 5988 int checkCallingPermission(String permission) { 5989 return checkPermission(permission, 5990 Binder.getCallingPid(), 5991 UserHandle.getAppId(Binder.getCallingUid())); 5992 } 5993 5994 /** 5995 * This can be called with or without the global lock held. 5996 */ 5997 void enforceCallingPermission(String permission, String func) { 5998 if (checkCallingPermission(permission) 5999 == PackageManager.PERMISSION_GRANTED) { 6000 return; 6001 } 6002 6003 String msg = "Permission Denial: " + func + " from pid=" 6004 + Binder.getCallingPid() 6005 + ", uid=" + Binder.getCallingUid() 6006 + " requires " + permission; 6007 Slog.w(TAG, msg); 6008 throw new SecurityException(msg); 6009 } 6010 6011 /** 6012 * Determine if UID is holding permissions required to access {@link Uri} in 6013 * the given {@link ProviderInfo}. Final permission checking is always done 6014 * in {@link ContentProvider}. 6015 */ 6016 private final boolean checkHoldingPermissionsLocked( 6017 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6018 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6019 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6020 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6021 return false; 6022 } 6023 6024 if (pi.applicationInfo.uid == uid) { 6025 return true; 6026 } else if (!pi.exported) { 6027 return false; 6028 } 6029 6030 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6031 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6032 try { 6033 // check if target holds top-level <provider> permissions 6034 if (!readMet && pi.readPermission != null 6035 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6036 readMet = true; 6037 } 6038 if (!writeMet && pi.writePermission != null 6039 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6040 writeMet = true; 6041 } 6042 6043 // track if unprotected read/write is allowed; any denied 6044 // <path-permission> below removes this ability 6045 boolean allowDefaultRead = pi.readPermission == null; 6046 boolean allowDefaultWrite = pi.writePermission == null; 6047 6048 // check if target holds any <path-permission> that match uri 6049 final PathPermission[] pps = pi.pathPermissions; 6050 if (pps != null) { 6051 final String path = grantUri.uri.getPath(); 6052 int i = pps.length; 6053 while (i > 0 && (!readMet || !writeMet)) { 6054 i--; 6055 PathPermission pp = pps[i]; 6056 if (pp.match(path)) { 6057 if (!readMet) { 6058 final String pprperm = pp.getReadPermission(); 6059 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6060 + pprperm + " for " + pp.getPath() 6061 + ": match=" + pp.match(path) 6062 + " check=" + pm.checkUidPermission(pprperm, uid)); 6063 if (pprperm != null) { 6064 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 6065 readMet = true; 6066 } else { 6067 allowDefaultRead = false; 6068 } 6069 } 6070 } 6071 if (!writeMet) { 6072 final String ppwperm = pp.getWritePermission(); 6073 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6074 + ppwperm + " for " + pp.getPath() 6075 + ": match=" + pp.match(path) 6076 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6077 if (ppwperm != null) { 6078 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 6079 writeMet = true; 6080 } else { 6081 allowDefaultWrite = false; 6082 } 6083 } 6084 } 6085 } 6086 } 6087 } 6088 6089 // grant unprotected <provider> read/write, if not blocked by 6090 // <path-permission> above 6091 if (allowDefaultRead) readMet = true; 6092 if (allowDefaultWrite) writeMet = true; 6093 6094 } catch (RemoteException e) { 6095 return false; 6096 } 6097 6098 return readMet && writeMet; 6099 } 6100 6101 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6102 ProviderInfo pi = null; 6103 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6104 if (cpr != null) { 6105 pi = cpr.info; 6106 } else { 6107 try { 6108 pi = AppGlobals.getPackageManager().resolveContentProvider( 6109 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6110 } catch (RemoteException ex) { 6111 } 6112 } 6113 return pi; 6114 } 6115 6116 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6117 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6118 if (targetUris != null) { 6119 return targetUris.get(grantUri); 6120 } 6121 return null; 6122 } 6123 6124 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6125 String targetPkg, int targetUid, GrantUri grantUri) { 6126 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6127 if (targetUris == null) { 6128 targetUris = Maps.newArrayMap(); 6129 mGrantedUriPermissions.put(targetUid, targetUris); 6130 } 6131 6132 UriPermission perm = targetUris.get(grantUri); 6133 if (perm == null) { 6134 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6135 targetUris.put(grantUri, perm); 6136 } 6137 6138 return perm; 6139 } 6140 6141 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6142 final int modeFlags) { 6143 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6144 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6145 : UriPermission.STRENGTH_OWNED; 6146 6147 // Root gets to do everything. 6148 if (uid == 0) { 6149 return true; 6150 } 6151 6152 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6153 if (perms == null) return false; 6154 6155 // First look for exact match 6156 final UriPermission exactPerm = perms.get(grantUri); 6157 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6158 return true; 6159 } 6160 6161 // No exact match, look for prefixes 6162 final int N = perms.size(); 6163 for (int i = 0; i < N; i++) { 6164 final UriPermission perm = perms.valueAt(i); 6165 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6166 && perm.getStrength(modeFlags) >= minStrength) { 6167 return true; 6168 } 6169 } 6170 6171 return false; 6172 } 6173 6174 @Override 6175 public int checkUriPermission(Uri uri, int pid, int uid, 6176 final int modeFlags, int userId) { 6177 enforceNotIsolatedCaller("checkUriPermission"); 6178 6179 // Another redirected-binder-call permissions check as in 6180 // {@link checkComponentPermission}. 6181 Identity tlsIdentity = sCallerIdentity.get(); 6182 if (tlsIdentity != null) { 6183 uid = tlsIdentity.uid; 6184 pid = tlsIdentity.pid; 6185 } 6186 6187 // Our own process gets to do everything. 6188 if (pid == MY_PID) { 6189 return PackageManager.PERMISSION_GRANTED; 6190 } 6191 synchronized (this) { 6192 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6193 ? PackageManager.PERMISSION_GRANTED 6194 : PackageManager.PERMISSION_DENIED; 6195 } 6196 } 6197 6198 /** 6199 * Check if the targetPkg can be granted permission to access uri by 6200 * the callingUid using the given modeFlags. Throws a security exception 6201 * if callingUid is not allowed to do this. Returns the uid of the target 6202 * if the URI permission grant should be performed; returns -1 if it is not 6203 * needed (for example targetPkg already has permission to access the URI). 6204 * If you already know the uid of the target, you can supply it in 6205 * lastTargetUid else set that to -1. 6206 */ 6207 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6208 final int modeFlags, int lastTargetUid) { 6209 if (!Intent.isAccessUriMode(modeFlags)) { 6210 return -1; 6211 } 6212 6213 if (targetPkg != null) { 6214 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6215 "Checking grant " + targetPkg + " permission to " + grantUri); 6216 } 6217 6218 final IPackageManager pm = AppGlobals.getPackageManager(); 6219 6220 // If this is not a content: uri, we can't do anything with it. 6221 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6222 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6223 "Can't grant URI permission for non-content URI: " + grantUri); 6224 return -1; 6225 } 6226 6227 final String authority = grantUri.uri.getAuthority(); 6228 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6229 if (pi == null) { 6230 Slog.w(TAG, "No content provider found for permission check: " + 6231 grantUri.uri.toSafeString()); 6232 return -1; 6233 } 6234 6235 int targetUid = lastTargetUid; 6236 if (targetUid < 0 && targetPkg != null) { 6237 try { 6238 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6239 if (targetUid < 0) { 6240 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6241 "Can't grant URI permission no uid for: " + targetPkg); 6242 return -1; 6243 } 6244 } catch (RemoteException ex) { 6245 return -1; 6246 } 6247 } 6248 6249 if (targetUid >= 0) { 6250 // First... does the target actually need this permission? 6251 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6252 // No need to grant the target this permission. 6253 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6254 "Target " + targetPkg + " already has full permission to " + grantUri); 6255 return -1; 6256 } 6257 } else { 6258 // First... there is no target package, so can anyone access it? 6259 boolean allowed = pi.exported; 6260 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6261 if (pi.readPermission != null) { 6262 allowed = false; 6263 } 6264 } 6265 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6266 if (pi.writePermission != null) { 6267 allowed = false; 6268 } 6269 } 6270 if (allowed) { 6271 return -1; 6272 } 6273 } 6274 6275 // Second... is the provider allowing granting of URI permissions? 6276 if (!pi.grantUriPermissions) { 6277 throw new SecurityException("Provider " + pi.packageName 6278 + "/" + pi.name 6279 + " does not allow granting of Uri permissions (uri " 6280 + grantUri + ")"); 6281 } 6282 if (pi.uriPermissionPatterns != null) { 6283 final int N = pi.uriPermissionPatterns.length; 6284 boolean allowed = false; 6285 for (int i=0; i<N; i++) { 6286 if (pi.uriPermissionPatterns[i] != null 6287 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6288 allowed = true; 6289 break; 6290 } 6291 } 6292 if (!allowed) { 6293 throw new SecurityException("Provider " + pi.packageName 6294 + "/" + pi.name 6295 + " does not allow granting of permission to path of Uri " 6296 + grantUri); 6297 } 6298 } 6299 6300 // Third... does the caller itself have permission to access 6301 // this uri? 6302 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6303 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6304 // Require they hold a strong enough Uri permission 6305 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6306 throw new SecurityException("Uid " + callingUid 6307 + " does not have permission to uri " + grantUri); 6308 } 6309 } 6310 } 6311 return targetUid; 6312 } 6313 6314 @Override 6315 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6316 final int modeFlags, int userId) { 6317 enforceNotIsolatedCaller("checkGrantUriPermission"); 6318 synchronized(this) { 6319 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6320 new GrantUri(userId, uri, false), modeFlags, -1); 6321 } 6322 } 6323 6324 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6325 final int modeFlags, UriPermissionOwner owner) { 6326 if (!Intent.isAccessUriMode(modeFlags)) { 6327 return; 6328 } 6329 6330 // So here we are: the caller has the assumed permission 6331 // to the uri, and the target doesn't. Let's now give this to 6332 // the target. 6333 6334 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6335 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6336 6337 final String authority = grantUri.uri.getAuthority(); 6338 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6339 if (pi == null) { 6340 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6341 return; 6342 } 6343 6344 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6345 grantUri.prefix = true; 6346 } 6347 final UriPermission perm = findOrCreateUriPermissionLocked( 6348 pi.packageName, targetPkg, targetUid, grantUri); 6349 perm.grantModes(modeFlags, owner); 6350 } 6351 6352 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6353 final int modeFlags, UriPermissionOwner owner) { 6354 if (targetPkg == null) { 6355 throw new NullPointerException("targetPkg"); 6356 } 6357 6358 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6359 -1); 6360 if (targetUid < 0) { 6361 return; 6362 } 6363 6364 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6365 owner); 6366 } 6367 6368 static class NeededUriGrants extends ArrayList<GrantUri> { 6369 final String targetPkg; 6370 final int targetUid; 6371 final int flags; 6372 6373 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6374 this.targetPkg = targetPkg; 6375 this.targetUid = targetUid; 6376 this.flags = flags; 6377 } 6378 } 6379 6380 /** 6381 * Like checkGrantUriPermissionLocked, but takes an Intent. 6382 */ 6383 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6384 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6385 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6386 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6387 + " clip=" + (intent != null ? intent.getClipData() : null) 6388 + " from " + intent + "; flags=0x" 6389 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6390 6391 if (targetPkg == null) { 6392 throw new NullPointerException("targetPkg"); 6393 } 6394 6395 if (intent == null) { 6396 return null; 6397 } 6398 Uri data = intent.getData(); 6399 ClipData clip = intent.getClipData(); 6400 if (data == null && clip == null) { 6401 return null; 6402 } 6403 6404 if (data != null) { 6405 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data); 6406 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6407 needed != null ? needed.targetUid : -1); 6408 if (targetUid > 0) { 6409 if (needed == null) { 6410 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6411 } 6412 needed.add(grantUri); 6413 } 6414 } 6415 if (clip != null) { 6416 for (int i=0; i<clip.getItemCount(); i++) { 6417 Uri uri = clip.getItemAt(i).getUri(); 6418 if (uri != null) { 6419 int targetUid = -1; 6420 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri); 6421 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6422 needed != null ? needed.targetUid : -1); 6423 if (targetUid > 0) { 6424 if (needed == null) { 6425 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6426 } 6427 needed.add(grantUri); 6428 } 6429 } else { 6430 Intent clipIntent = clip.getItemAt(i).getIntent(); 6431 if (clipIntent != null) { 6432 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6433 callingUid, targetPkg, clipIntent, mode, needed); 6434 if (newNeeded != null) { 6435 needed = newNeeded; 6436 } 6437 } 6438 } 6439 } 6440 } 6441 6442 return needed; 6443 } 6444 6445 /** 6446 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6447 */ 6448 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6449 UriPermissionOwner owner) { 6450 if (needed != null) { 6451 for (int i=0; i<needed.size(); i++) { 6452 GrantUri grantUri = needed.get(i); 6453 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6454 grantUri, needed.flags, owner); 6455 } 6456 } 6457 } 6458 6459 void grantUriPermissionFromIntentLocked(int callingUid, 6460 String targetPkg, Intent intent, UriPermissionOwner owner) { 6461 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6462 intent, intent != null ? intent.getFlags() : 0, null); 6463 if (needed == null) { 6464 return; 6465 } 6466 6467 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6468 } 6469 6470 @Override 6471 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6472 final int modeFlags, int userId) { 6473 enforceNotIsolatedCaller("grantUriPermission"); 6474 GrantUri grantUri = new GrantUri(userId, uri, false); 6475 synchronized(this) { 6476 final ProcessRecord r = getRecordForAppLocked(caller); 6477 if (r == null) { 6478 throw new SecurityException("Unable to find app for caller " 6479 + caller 6480 + " when granting permission to uri " + grantUri); 6481 } 6482 if (targetPkg == null) { 6483 throw new IllegalArgumentException("null target"); 6484 } 6485 if (grantUri == null) { 6486 throw new IllegalArgumentException("null uri"); 6487 } 6488 6489 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6490 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6491 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6492 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6493 6494 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null); 6495 } 6496 } 6497 6498 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6499 if (perm.modeFlags == 0) { 6500 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6501 perm.targetUid); 6502 if (perms != null) { 6503 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6504 "Removing " + perm.targetUid + " permission to " + perm.uri); 6505 6506 perms.remove(perm.uri); 6507 if (perms.isEmpty()) { 6508 mGrantedUriPermissions.remove(perm.targetUid); 6509 } 6510 } 6511 } 6512 } 6513 6514 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 6515 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 6516 6517 final IPackageManager pm = AppGlobals.getPackageManager(); 6518 final String authority = grantUri.uri.getAuthority(); 6519 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6520 if (pi == null) { 6521 Slog.w(TAG, "No content provider found for permission revoke: " 6522 + grantUri.toSafeString()); 6523 return; 6524 } 6525 6526 // Does the caller have this permission on the URI? 6527 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6528 // Right now, if you are not the original owner of the permission, 6529 // you are not allowed to revoke it. 6530 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6531 throw new SecurityException("Uid " + callingUid 6532 + " does not have permission to uri " + grantUri); 6533 //} 6534 } 6535 6536 boolean persistChanged = false; 6537 6538 // Go through all of the permissions and remove any that match. 6539 int N = mGrantedUriPermissions.size(); 6540 for (int i = 0; i < N; i++) { 6541 final int targetUid = mGrantedUriPermissions.keyAt(i); 6542 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6543 6544 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6545 final UriPermission perm = it.next(); 6546 if (perm.uri.sourceUserId == grantUri.sourceUserId 6547 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 6548 if (DEBUG_URI_PERMISSION) 6549 Slog.v(TAG, 6550 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6551 persistChanged |= perm.revokeModes( 6552 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6553 if (perm.modeFlags == 0) { 6554 it.remove(); 6555 } 6556 } 6557 } 6558 6559 if (perms.isEmpty()) { 6560 mGrantedUriPermissions.remove(targetUid); 6561 N--; 6562 i--; 6563 } 6564 } 6565 6566 if (persistChanged) { 6567 schedulePersistUriGrants(); 6568 } 6569 } 6570 6571 @Override 6572 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 6573 int userId) { 6574 enforceNotIsolatedCaller("revokeUriPermission"); 6575 synchronized(this) { 6576 final ProcessRecord r = getRecordForAppLocked(caller); 6577 if (r == null) { 6578 throw new SecurityException("Unable to find app for caller " 6579 + caller 6580 + " when revoking permission to uri " + uri); 6581 } 6582 if (uri == null) { 6583 Slog.w(TAG, "revokeUriPermission: null uri"); 6584 return; 6585 } 6586 6587 if (!Intent.isAccessUriMode(modeFlags)) { 6588 return; 6589 } 6590 6591 final IPackageManager pm = AppGlobals.getPackageManager(); 6592 final String authority = uri.getAuthority(); 6593 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 6594 if (pi == null) { 6595 Slog.w(TAG, "No content provider found for permission revoke: " 6596 + uri.toSafeString()); 6597 return; 6598 } 6599 6600 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 6601 } 6602 } 6603 6604 /** 6605 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6606 * given package. 6607 * 6608 * @param packageName Package name to match, or {@code null} to apply to all 6609 * packages. 6610 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6611 * to all users. 6612 * @param persistable If persistable grants should be removed. 6613 */ 6614 private void removeUriPermissionsForPackageLocked( 6615 String packageName, int userHandle, boolean persistable) { 6616 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6617 throw new IllegalArgumentException("Must narrow by either package or user"); 6618 } 6619 6620 boolean persistChanged = false; 6621 6622 int N = mGrantedUriPermissions.size(); 6623 for (int i = 0; i < N; i++) { 6624 final int targetUid = mGrantedUriPermissions.keyAt(i); 6625 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6626 6627 // Only inspect grants matching user 6628 if (userHandle == UserHandle.USER_ALL 6629 || userHandle == UserHandle.getUserId(targetUid)) { 6630 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6631 final UriPermission perm = it.next(); 6632 6633 // Only inspect grants matching package 6634 if (packageName == null || perm.sourcePkg.equals(packageName) 6635 || perm.targetPkg.equals(packageName)) { 6636 persistChanged |= perm.revokeModes( 6637 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6638 6639 // Only remove when no modes remain; any persisted grants 6640 // will keep this alive. 6641 if (perm.modeFlags == 0) { 6642 it.remove(); 6643 } 6644 } 6645 } 6646 6647 if (perms.isEmpty()) { 6648 mGrantedUriPermissions.remove(targetUid); 6649 N--; 6650 i--; 6651 } 6652 } 6653 } 6654 6655 if (persistChanged) { 6656 schedulePersistUriGrants(); 6657 } 6658 } 6659 6660 @Override 6661 public IBinder newUriPermissionOwner(String name) { 6662 enforceNotIsolatedCaller("newUriPermissionOwner"); 6663 synchronized(this) { 6664 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6665 return owner.getExternalTokenLocked(); 6666 } 6667 } 6668 6669 @Override 6670 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 6671 final int modeFlags, int userId) { 6672 synchronized(this) { 6673 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6674 if (owner == null) { 6675 throw new IllegalArgumentException("Unknown owner: " + token); 6676 } 6677 if (fromUid != Binder.getCallingUid()) { 6678 if (Binder.getCallingUid() != Process.myUid()) { 6679 // Only system code can grant URI permissions on behalf 6680 // of other users. 6681 throw new SecurityException("nice try"); 6682 } 6683 } 6684 if (targetPkg == null) { 6685 throw new IllegalArgumentException("null target"); 6686 } 6687 if (uri == null) { 6688 throw new IllegalArgumentException("null uri"); 6689 } 6690 6691 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false), 6692 modeFlags, owner); 6693 } 6694 } 6695 6696 @Override 6697 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 6698 synchronized(this) { 6699 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6700 if (owner == null) { 6701 throw new IllegalArgumentException("Unknown owner: " + token); 6702 } 6703 6704 if (uri == null) { 6705 owner.removeUriPermissionsLocked(mode); 6706 } else { 6707 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 6708 } 6709 } 6710 } 6711 6712 private void schedulePersistUriGrants() { 6713 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6714 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6715 10 * DateUtils.SECOND_IN_MILLIS); 6716 } 6717 } 6718 6719 private void writeGrantedUriPermissions() { 6720 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6721 6722 // Snapshot permissions so we can persist without lock 6723 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6724 synchronized (this) { 6725 final int size = mGrantedUriPermissions.size(); 6726 for (int i = 0; i < size; i++) { 6727 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6728 for (UriPermission perm : perms.values()) { 6729 if (perm.persistedModeFlags != 0) { 6730 persist.add(perm.snapshot()); 6731 } 6732 } 6733 } 6734 } 6735 6736 FileOutputStream fos = null; 6737 try { 6738 fos = mGrantFile.startWrite(); 6739 6740 XmlSerializer out = new FastXmlSerializer(); 6741 out.setOutput(fos, "utf-8"); 6742 out.startDocument(null, true); 6743 out.startTag(null, TAG_URI_GRANTS); 6744 for (UriPermission.Snapshot perm : persist) { 6745 out.startTag(null, TAG_URI_GRANT); 6746 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 6747 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 6748 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6749 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6750 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6751 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6752 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6753 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6754 out.endTag(null, TAG_URI_GRANT); 6755 } 6756 out.endTag(null, TAG_URI_GRANTS); 6757 out.endDocument(); 6758 6759 mGrantFile.finishWrite(fos); 6760 } catch (IOException e) { 6761 if (fos != null) { 6762 mGrantFile.failWrite(fos); 6763 } 6764 } 6765 } 6766 6767 private void readGrantedUriPermissionsLocked() { 6768 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6769 6770 final long now = System.currentTimeMillis(); 6771 6772 FileInputStream fis = null; 6773 try { 6774 fis = mGrantFile.openRead(); 6775 final XmlPullParser in = Xml.newPullParser(); 6776 in.setInput(fis, null); 6777 6778 int type; 6779 while ((type = in.next()) != END_DOCUMENT) { 6780 final String tag = in.getName(); 6781 if (type == START_TAG) { 6782 if (TAG_URI_GRANT.equals(tag)) { 6783 final int sourceUserId; 6784 final int targetUserId; 6785 final int userHandle = readIntAttribute(in, 6786 ATTR_USER_HANDLE, UserHandle.USER_NULL); 6787 if (userHandle != UserHandle.USER_NULL) { 6788 // For backwards compatibility. 6789 sourceUserId = userHandle; 6790 targetUserId = userHandle; 6791 } else { 6792 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 6793 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 6794 } 6795 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6796 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6797 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6798 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6799 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6800 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6801 6802 // Sanity check that provider still belongs to source package 6803 final ProviderInfo pi = getProviderInfoLocked( 6804 uri.getAuthority(), sourceUserId); 6805 if (pi != null && sourcePkg.equals(pi.packageName)) { 6806 int targetUid = -1; 6807 try { 6808 targetUid = AppGlobals.getPackageManager() 6809 .getPackageUid(targetPkg, targetUserId); 6810 } catch (RemoteException e) { 6811 } 6812 if (targetUid != -1) { 6813 final UriPermission perm = findOrCreateUriPermissionLocked( 6814 sourcePkg, targetPkg, targetUid, 6815 new GrantUri(sourceUserId, uri, prefix)); 6816 perm.initPersistedModes(modeFlags, createdTime); 6817 } 6818 } else { 6819 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6820 + " but instead found " + pi); 6821 } 6822 } 6823 } 6824 } 6825 } catch (FileNotFoundException e) { 6826 // Missing grants is okay 6827 } catch (IOException e) { 6828 Log.wtf(TAG, "Failed reading Uri grants", e); 6829 } catch (XmlPullParserException e) { 6830 Log.wtf(TAG, "Failed reading Uri grants", e); 6831 } finally { 6832 IoUtils.closeQuietly(fis); 6833 } 6834 } 6835 6836 @Override 6837 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6838 enforceNotIsolatedCaller("takePersistableUriPermission"); 6839 6840 Preconditions.checkFlagsArgument(modeFlags, 6841 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6842 6843 synchronized (this) { 6844 final int callingUid = Binder.getCallingUid(); 6845 boolean persistChanged = false; 6846 GrantUri grantUri = new GrantUri(userId, uri, false); 6847 6848 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6849 new GrantUri(userId, uri, false)); 6850 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6851 new GrantUri(userId, uri, true)); 6852 6853 final boolean exactValid = (exactPerm != null) 6854 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6855 final boolean prefixValid = (prefixPerm != null) 6856 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6857 6858 if (!(exactValid || prefixValid)) { 6859 throw new SecurityException("No persistable permission grants found for UID " 6860 + callingUid + " and Uri " + grantUri.toSafeString()); 6861 } 6862 6863 if (exactValid) { 6864 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6865 } 6866 if (prefixValid) { 6867 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6868 } 6869 6870 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6871 6872 if (persistChanged) { 6873 schedulePersistUriGrants(); 6874 } 6875 } 6876 } 6877 6878 @Override 6879 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6880 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6881 6882 Preconditions.checkFlagsArgument(modeFlags, 6883 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6884 6885 synchronized (this) { 6886 final int callingUid = Binder.getCallingUid(); 6887 boolean persistChanged = false; 6888 6889 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6890 new GrantUri(userId, uri, false)); 6891 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6892 new GrantUri(userId, uri, true)); 6893 if (exactPerm == null && prefixPerm == null) { 6894 throw new SecurityException("No permission grants found for UID " + callingUid 6895 + " and Uri " + uri.toSafeString()); 6896 } 6897 6898 if (exactPerm != null) { 6899 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6900 removeUriPermissionIfNeededLocked(exactPerm); 6901 } 6902 if (prefixPerm != null) { 6903 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6904 removeUriPermissionIfNeededLocked(prefixPerm); 6905 } 6906 6907 if (persistChanged) { 6908 schedulePersistUriGrants(); 6909 } 6910 } 6911 } 6912 6913 /** 6914 * Prune any older {@link UriPermission} for the given UID until outstanding 6915 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6916 * 6917 * @return if any mutations occured that require persisting. 6918 */ 6919 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6920 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6921 if (perms == null) return false; 6922 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6923 6924 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6925 for (UriPermission perm : perms.values()) { 6926 if (perm.persistedModeFlags != 0) { 6927 persisted.add(perm); 6928 } 6929 } 6930 6931 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6932 if (trimCount <= 0) return false; 6933 6934 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6935 for (int i = 0; i < trimCount; i++) { 6936 final UriPermission perm = persisted.get(i); 6937 6938 if (DEBUG_URI_PERMISSION) { 6939 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6940 } 6941 6942 perm.releasePersistableModes(~0); 6943 removeUriPermissionIfNeededLocked(perm); 6944 } 6945 6946 return true; 6947 } 6948 6949 @Override 6950 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6951 String packageName, boolean incoming) { 6952 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6953 Preconditions.checkNotNull(packageName, "packageName"); 6954 6955 final int callingUid = Binder.getCallingUid(); 6956 final IPackageManager pm = AppGlobals.getPackageManager(); 6957 try { 6958 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6959 if (packageUid != callingUid) { 6960 throw new SecurityException( 6961 "Package " + packageName + " does not belong to calling UID " + callingUid); 6962 } 6963 } catch (RemoteException e) { 6964 throw new SecurityException("Failed to verify package name ownership"); 6965 } 6966 6967 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6968 synchronized (this) { 6969 if (incoming) { 6970 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6971 callingUid); 6972 if (perms == null) { 6973 Slog.w(TAG, "No permission grants found for " + packageName); 6974 } else { 6975 for (UriPermission perm : perms.values()) { 6976 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6977 result.add(perm.buildPersistedPublicApiObject()); 6978 } 6979 } 6980 } 6981 } else { 6982 final int size = mGrantedUriPermissions.size(); 6983 for (int i = 0; i < size; i++) { 6984 final ArrayMap<GrantUri, UriPermission> perms = 6985 mGrantedUriPermissions.valueAt(i); 6986 for (UriPermission perm : perms.values()) { 6987 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6988 result.add(perm.buildPersistedPublicApiObject()); 6989 } 6990 } 6991 } 6992 } 6993 } 6994 return new ParceledListSlice<android.content.UriPermission>(result); 6995 } 6996 6997 @Override 6998 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6999 synchronized (this) { 7000 ProcessRecord app = 7001 who != null ? getRecordForAppLocked(who) : null; 7002 if (app == null) return; 7003 7004 Message msg = Message.obtain(); 7005 msg.what = WAIT_FOR_DEBUGGER_MSG; 7006 msg.obj = app; 7007 msg.arg1 = waiting ? 1 : 0; 7008 mHandler.sendMessage(msg); 7009 } 7010 } 7011 7012 @Override 7013 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7014 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7015 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7016 outInfo.availMem = Process.getFreeMemory(); 7017 outInfo.totalMem = Process.getTotalMemory(); 7018 outInfo.threshold = homeAppMem; 7019 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7020 outInfo.hiddenAppThreshold = cachedAppMem; 7021 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7022 ProcessList.SERVICE_ADJ); 7023 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7024 ProcessList.VISIBLE_APP_ADJ); 7025 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7026 ProcessList.FOREGROUND_APP_ADJ); 7027 } 7028 7029 // ========================================================= 7030 // TASK MANAGEMENT 7031 // ========================================================= 7032 7033 @Override 7034 public List<IAppTask> getAppTasks() { 7035 int callingUid = Binder.getCallingUid(); 7036 long ident = Binder.clearCallingIdentity(); 7037 synchronized(this) { 7038 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7039 try { 7040 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7041 7042 final int N = mRecentTasks.size(); 7043 for (int i = 0; i < N; i++) { 7044 TaskRecord tr = mRecentTasks.get(i); 7045 // Skip tasks that are not created by the caller 7046 if (tr.creatorUid == callingUid) { 7047 ActivityManager.RecentTaskInfo taskInfo = 7048 createRecentTaskInfoFromTaskRecord(tr); 7049 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7050 list.add(taskImpl); 7051 } 7052 } 7053 } finally { 7054 Binder.restoreCallingIdentity(ident); 7055 } 7056 return list; 7057 } 7058 } 7059 7060 @Override 7061 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7062 final int callingUid = Binder.getCallingUid(); 7063 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7064 7065 synchronized(this) { 7066 if (localLOGV) Slog.v( 7067 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7068 7069 final boolean allowed = checkCallingPermission( 7070 android.Manifest.permission.GET_TASKS) 7071 == PackageManager.PERMISSION_GRANTED; 7072 if (!allowed) { 7073 Slog.w(TAG, "getTasks: caller " + callingUid 7074 + " does not hold GET_TASKS; limiting output"); 7075 } 7076 7077 // TODO: Improve with MRU list from all ActivityStacks. 7078 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7079 } 7080 7081 return list; 7082 } 7083 7084 TaskRecord getMostRecentTask() { 7085 return mRecentTasks.get(0); 7086 } 7087 7088 /** 7089 * Creates a new RecentTaskInfo from a TaskRecord. 7090 */ 7091 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7092 ActivityManager.RecentTaskInfo rti 7093 = new ActivityManager.RecentTaskInfo(); 7094 rti.id = tr.mActivities.isEmpty() ? -1 : tr.taskId; 7095 rti.persistentId = tr.taskId; 7096 rti.baseIntent = new Intent(tr.getBaseIntent()); 7097 rti.origActivity = tr.origActivity; 7098 rti.description = tr.lastDescription; 7099 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 7100 rti.userId = tr.userId; 7101 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7102 return rti; 7103 } 7104 7105 @Override 7106 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7107 int flags, int userId) { 7108 final int callingUid = Binder.getCallingUid(); 7109 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7110 false, true, "getRecentTasks", null); 7111 7112 synchronized (this) { 7113 final boolean allowed = checkCallingPermission( 7114 android.Manifest.permission.GET_TASKS) 7115 == PackageManager.PERMISSION_GRANTED; 7116 if (!allowed) { 7117 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7118 + " does not hold GET_TASKS; limiting output"); 7119 } 7120 final boolean detailed = checkCallingPermission( 7121 android.Manifest.permission.GET_DETAILED_TASKS) 7122 == PackageManager.PERMISSION_GRANTED; 7123 7124 IPackageManager pm = AppGlobals.getPackageManager(); 7125 7126 final int N = mRecentTasks.size(); 7127 ArrayList<ActivityManager.RecentTaskInfo> res 7128 = new ArrayList<ActivityManager.RecentTaskInfo>( 7129 maxNum < N ? maxNum : N); 7130 7131 final Set<Integer> includedUsers; 7132 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7133 includedUsers = getProfileIdsLocked(userId); 7134 } else { 7135 includedUsers = new HashSet<Integer>(); 7136 } 7137 includedUsers.add(Integer.valueOf(userId)); 7138 for (int i=0; i<N && maxNum > 0; i++) { 7139 TaskRecord tr = mRecentTasks.get(i); 7140 // Only add calling user or related users recent tasks 7141 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7142 7143 // Return the entry if desired by the caller. We always return 7144 // the first entry, because callers always expect this to be the 7145 // foreground app. We may filter others if the caller has 7146 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7147 // we should exclude the entry. 7148 7149 if (i == 0 7150 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7151 || (tr.intent == null) 7152 || ((tr.intent.getFlags() 7153 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7154 if (!allowed) { 7155 // If the caller doesn't have the GET_TASKS permission, then only 7156 // allow them to see a small subset of tasks -- their own and home. 7157 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7158 continue; 7159 } 7160 } 7161 7162 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7163 if (!detailed) { 7164 rti.baseIntent.replaceExtras((Bundle)null); 7165 } 7166 7167 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7168 // Check whether this activity is currently available. 7169 try { 7170 if (rti.origActivity != null) { 7171 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7172 == null) { 7173 continue; 7174 } 7175 } else if (rti.baseIntent != null) { 7176 if (pm.queryIntentActivities(rti.baseIntent, 7177 null, 0, userId) == null) { 7178 continue; 7179 } 7180 } 7181 } catch (RemoteException e) { 7182 // Will never happen. 7183 } 7184 } 7185 7186 res.add(rti); 7187 maxNum--; 7188 } 7189 } 7190 return res; 7191 } 7192 } 7193 7194 private TaskRecord recentTaskForIdLocked(int id) { 7195 final int N = mRecentTasks.size(); 7196 for (int i=0; i<N; i++) { 7197 TaskRecord tr = mRecentTasks.get(i); 7198 if (tr.taskId == id) { 7199 return tr; 7200 } 7201 } 7202 return null; 7203 } 7204 7205 @Override 7206 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7207 synchronized (this) { 7208 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7209 "getTaskThumbnails()"); 7210 TaskRecord tr = recentTaskForIdLocked(id); 7211 if (tr != null) { 7212 return tr.getTaskThumbnailsLocked(); 7213 } 7214 } 7215 return null; 7216 } 7217 7218 @Override 7219 public Bitmap getTaskTopThumbnail(int id) { 7220 synchronized (this) { 7221 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7222 "getTaskTopThumbnail()"); 7223 TaskRecord tr = recentTaskForIdLocked(id); 7224 if (tr != null) { 7225 return tr.getTaskTopThumbnailLocked(); 7226 } 7227 } 7228 return null; 7229 } 7230 7231 @Override 7232 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 7233 synchronized (this) { 7234 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7235 if (r != null) { 7236 r.taskDescription = td; 7237 r.task.updateTaskDescription(); 7238 } 7239 } 7240 } 7241 7242 @Override 7243 public boolean removeSubTask(int taskId, int subTaskIndex) { 7244 synchronized (this) { 7245 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7246 "removeSubTask()"); 7247 long ident = Binder.clearCallingIdentity(); 7248 try { 7249 TaskRecord tr = recentTaskForIdLocked(taskId); 7250 if (tr != null) { 7251 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7252 } 7253 return false; 7254 } finally { 7255 Binder.restoreCallingIdentity(ident); 7256 } 7257 } 7258 } 7259 7260 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7261 if (!pr.killedByAm) { 7262 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7263 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7264 pr.processName, pr.setAdj, reason); 7265 pr.killedByAm = true; 7266 Process.killProcessQuiet(pr.pid); 7267 } 7268 } 7269 7270 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7271 tr.disposeThumbnail(); 7272 mRecentTasks.remove(tr); 7273 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7274 Intent baseIntent = new Intent( 7275 tr.intent != null ? tr.intent : tr.affinityIntent); 7276 ComponentName component = baseIntent.getComponent(); 7277 if (component == null) { 7278 Slog.w(TAG, "Now component for base intent of task: " + tr); 7279 return; 7280 } 7281 7282 // Find any running services associated with this app. 7283 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7284 7285 if (killProcesses) { 7286 // Find any running processes associated with this app. 7287 final String pkg = component.getPackageName(); 7288 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7289 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7290 for (int i=0; i<pmap.size(); i++) { 7291 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7292 for (int j=0; j<uids.size(); j++) { 7293 ProcessRecord proc = uids.valueAt(j); 7294 if (proc.userId != tr.userId) { 7295 continue; 7296 } 7297 if (!proc.pkgList.containsKey(pkg)) { 7298 continue; 7299 } 7300 procs.add(proc); 7301 } 7302 } 7303 7304 // Kill the running processes. 7305 for (int i=0; i<procs.size(); i++) { 7306 ProcessRecord pr = procs.get(i); 7307 if (pr == mHomeProcess) { 7308 // Don't kill the home process along with tasks from the same package. 7309 continue; 7310 } 7311 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7312 killUnneededProcessLocked(pr, "remove task"); 7313 } else { 7314 pr.waitingToKill = "remove task"; 7315 } 7316 } 7317 } 7318 } 7319 7320 /** 7321 * Removes the task with the specified task id. 7322 * 7323 * @param taskId Identifier of the task to be removed. 7324 * @param flags Additional operational flags. May be 0 or 7325 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7326 * @return Returns true if the given task was found and removed. 7327 */ 7328 private boolean removeTaskByIdLocked(int taskId, int flags) { 7329 TaskRecord tr = recentTaskForIdLocked(taskId); 7330 if (tr != null) { 7331 tr.removeTaskActivitiesLocked(-1, false); 7332 cleanUpRemovedTaskLocked(tr, flags); 7333 if (tr.isPersistable) { 7334 notifyTaskPersisterLocked(tr, true); 7335 } 7336 return true; 7337 } 7338 return false; 7339 } 7340 7341 @Override 7342 public boolean removeTask(int taskId, int flags) { 7343 synchronized (this) { 7344 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7345 "removeTask()"); 7346 long ident = Binder.clearCallingIdentity(); 7347 try { 7348 return removeTaskByIdLocked(taskId, flags); 7349 } finally { 7350 Binder.restoreCallingIdentity(ident); 7351 } 7352 } 7353 } 7354 7355 /** 7356 * TODO: Add mController hook 7357 */ 7358 @Override 7359 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7360 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7361 "moveTaskToFront()"); 7362 7363 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7364 synchronized(this) { 7365 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7366 Binder.getCallingUid(), "Task to front")) { 7367 ActivityOptions.abort(options); 7368 return; 7369 } 7370 final long origId = Binder.clearCallingIdentity(); 7371 try { 7372 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7373 if (task == null) { 7374 return; 7375 } 7376 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7377 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7378 return; 7379 } 7380 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7381 } finally { 7382 Binder.restoreCallingIdentity(origId); 7383 } 7384 ActivityOptions.abort(options); 7385 } 7386 } 7387 7388 @Override 7389 public void moveTaskToBack(int taskId) { 7390 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7391 "moveTaskToBack()"); 7392 7393 synchronized(this) { 7394 TaskRecord tr = recentTaskForIdLocked(taskId); 7395 if (tr != null) { 7396 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7397 ActivityStack stack = tr.stack; 7398 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7399 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7400 Binder.getCallingUid(), "Task to back")) { 7401 return; 7402 } 7403 } 7404 final long origId = Binder.clearCallingIdentity(); 7405 try { 7406 stack.moveTaskToBackLocked(taskId, null); 7407 } finally { 7408 Binder.restoreCallingIdentity(origId); 7409 } 7410 } 7411 } 7412 } 7413 7414 /** 7415 * Moves an activity, and all of the other activities within the same task, to the bottom 7416 * of the history stack. The activity's order within the task is unchanged. 7417 * 7418 * @param token A reference to the activity we wish to move 7419 * @param nonRoot If false then this only works if the activity is the root 7420 * of a task; if true it will work for any activity in a task. 7421 * @return Returns true if the move completed, false if not. 7422 */ 7423 @Override 7424 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7425 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7426 synchronized(this) { 7427 final long origId = Binder.clearCallingIdentity(); 7428 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7429 if (taskId >= 0) { 7430 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7431 } 7432 Binder.restoreCallingIdentity(origId); 7433 } 7434 return false; 7435 } 7436 7437 @Override 7438 public void moveTaskBackwards(int task) { 7439 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7440 "moveTaskBackwards()"); 7441 7442 synchronized(this) { 7443 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7444 Binder.getCallingUid(), "Task backwards")) { 7445 return; 7446 } 7447 final long origId = Binder.clearCallingIdentity(); 7448 moveTaskBackwardsLocked(task); 7449 Binder.restoreCallingIdentity(origId); 7450 } 7451 } 7452 7453 private final void moveTaskBackwardsLocked(int task) { 7454 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7455 } 7456 7457 @Override 7458 public IBinder getHomeActivityToken() throws RemoteException { 7459 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7460 "getHomeActivityToken()"); 7461 synchronized (this) { 7462 return mStackSupervisor.getHomeActivityToken(); 7463 } 7464 } 7465 7466 @Override 7467 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7468 IActivityContainerCallback callback) throws RemoteException { 7469 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7470 "createActivityContainer()"); 7471 synchronized (this) { 7472 if (parentActivityToken == null) { 7473 throw new IllegalArgumentException("parent token must not be null"); 7474 } 7475 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7476 if (r == null) { 7477 return null; 7478 } 7479 if (callback == null) { 7480 throw new IllegalArgumentException("callback must not be null"); 7481 } 7482 return mStackSupervisor.createActivityContainer(r, callback); 7483 } 7484 } 7485 7486 @Override 7487 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7488 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7489 "deleteActivityContainer()"); 7490 synchronized (this) { 7491 mStackSupervisor.deleteActivityContainer(container); 7492 } 7493 } 7494 7495 @Override 7496 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7497 throws RemoteException { 7498 synchronized (this) { 7499 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7500 if (stack != null) { 7501 return stack.mActivityContainer; 7502 } 7503 return null; 7504 } 7505 } 7506 7507 @Override 7508 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7509 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7510 "moveTaskToStack()"); 7511 if (stackId == HOME_STACK_ID) { 7512 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7513 new RuntimeException("here").fillInStackTrace()); 7514 } 7515 synchronized (this) { 7516 long ident = Binder.clearCallingIdentity(); 7517 try { 7518 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7519 + stackId + " toTop=" + toTop); 7520 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7521 } finally { 7522 Binder.restoreCallingIdentity(ident); 7523 } 7524 } 7525 } 7526 7527 @Override 7528 public void resizeStack(int stackBoxId, Rect bounds) { 7529 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7530 "resizeStackBox()"); 7531 long ident = Binder.clearCallingIdentity(); 7532 try { 7533 mWindowManager.resizeStack(stackBoxId, bounds); 7534 } finally { 7535 Binder.restoreCallingIdentity(ident); 7536 } 7537 } 7538 7539 @Override 7540 public List<StackInfo> getAllStackInfos() { 7541 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7542 "getAllStackInfos()"); 7543 long ident = Binder.clearCallingIdentity(); 7544 try { 7545 synchronized (this) { 7546 return mStackSupervisor.getAllStackInfosLocked(); 7547 } 7548 } finally { 7549 Binder.restoreCallingIdentity(ident); 7550 } 7551 } 7552 7553 @Override 7554 public StackInfo getStackInfo(int stackId) { 7555 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7556 "getStackInfo()"); 7557 long ident = Binder.clearCallingIdentity(); 7558 try { 7559 synchronized (this) { 7560 return mStackSupervisor.getStackInfoLocked(stackId); 7561 } 7562 } finally { 7563 Binder.restoreCallingIdentity(ident); 7564 } 7565 } 7566 7567 @Override 7568 public boolean isInHomeStack(int taskId) { 7569 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7570 "getStackInfo()"); 7571 long ident = Binder.clearCallingIdentity(); 7572 try { 7573 synchronized (this) { 7574 TaskRecord tr = recentTaskForIdLocked(taskId); 7575 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 7576 } 7577 } finally { 7578 Binder.restoreCallingIdentity(ident); 7579 } 7580 } 7581 7582 @Override 7583 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7584 synchronized(this) { 7585 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7586 } 7587 } 7588 7589 private boolean isLockTaskAuthorized(ComponentName name) { 7590 final DevicePolicyManager dpm = (DevicePolicyManager) 7591 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7592 return dpm != null && dpm.isLockTaskPermitted(name); 7593 } 7594 7595 private void startLockTaskMode(TaskRecord task) { 7596 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7597 return; 7598 } 7599 long ident = Binder.clearCallingIdentity(); 7600 try { 7601 synchronized (this) { 7602 // Since we lost lock on task, make sure it is still there. 7603 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7604 if (task != null) { 7605 mStackSupervisor.setLockTaskModeLocked(task); 7606 } 7607 } 7608 } finally { 7609 Binder.restoreCallingIdentity(ident); 7610 } 7611 } 7612 7613 @Override 7614 public void startLockTaskMode(int taskId) { 7615 long ident = Binder.clearCallingIdentity(); 7616 try { 7617 final TaskRecord task; 7618 synchronized (this) { 7619 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7620 } 7621 if (task != null) { 7622 startLockTaskMode(task); 7623 } 7624 } finally { 7625 Binder.restoreCallingIdentity(ident); 7626 } 7627 } 7628 7629 @Override 7630 public void startLockTaskMode(IBinder token) { 7631 long ident = Binder.clearCallingIdentity(); 7632 try { 7633 final TaskRecord task; 7634 synchronized (this) { 7635 final ActivityRecord r = ActivityRecord.forToken(token); 7636 if (r == null) { 7637 return; 7638 } 7639 task = r.task; 7640 } 7641 if (task != null) { 7642 startLockTaskMode(task); 7643 } 7644 } finally { 7645 Binder.restoreCallingIdentity(ident); 7646 } 7647 } 7648 7649 @Override 7650 public void stopLockTaskMode() { 7651 // Check if the calling task is eligible to use lock task 7652 final int uid = Binder.getCallingUid(); 7653 try { 7654 final String name = AppGlobals.getPackageManager().getNameForUid(uid); 7655 if (!isLockTaskAuthorized(new ComponentName(name, name))) { 7656 return; 7657 } 7658 } catch (RemoteException e) { 7659 Log.d(TAG, "stopLockTaskMode " + e); 7660 return; 7661 } 7662 // Stop lock task 7663 synchronized (this) { 7664 mStackSupervisor.setLockTaskModeLocked(null); 7665 } 7666 } 7667 7668 @Override 7669 public boolean isInLockTaskMode() { 7670 synchronized (this) { 7671 return mStackSupervisor.isInLockTaskMode(); 7672 } 7673 } 7674 7675 // ========================================================= 7676 // CONTENT PROVIDERS 7677 // ========================================================= 7678 7679 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7680 List<ProviderInfo> providers = null; 7681 try { 7682 providers = AppGlobals.getPackageManager(). 7683 queryContentProviders(app.processName, app.uid, 7684 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7685 } catch (RemoteException ex) { 7686 } 7687 if (DEBUG_MU) 7688 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7689 int userId = app.userId; 7690 if (providers != null) { 7691 int N = providers.size(); 7692 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7693 for (int i=0; i<N; i++) { 7694 ProviderInfo cpi = 7695 (ProviderInfo)providers.get(i); 7696 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7697 cpi.name, cpi.flags); 7698 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7699 // This is a singleton provider, but a user besides the 7700 // default user is asking to initialize a process it runs 7701 // in... well, no, it doesn't actually run in this process, 7702 // it runs in the process of the default user. Get rid of it. 7703 providers.remove(i); 7704 N--; 7705 i--; 7706 continue; 7707 } 7708 7709 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7710 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7711 if (cpr == null) { 7712 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7713 mProviderMap.putProviderByClass(comp, cpr); 7714 } 7715 if (DEBUG_MU) 7716 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7717 app.pubProviders.put(cpi.name, cpr); 7718 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7719 // Don't add this if it is a platform component that is marked 7720 // to run in multiple processes, because this is actually 7721 // part of the framework so doesn't make sense to track as a 7722 // separate apk in the process. 7723 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7724 } 7725 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7726 } 7727 } 7728 return providers; 7729 } 7730 7731 /** 7732 * Check if {@link ProcessRecord} has a possible chance at accessing the 7733 * given {@link ProviderInfo}. Final permission checking is always done 7734 * in {@link ContentProvider}. 7735 */ 7736 private final String checkContentProviderPermissionLocked( 7737 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 7738 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7739 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7740 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7741 // Looking for cross-user grants before to enforce the typical cross-users permissions 7742 if (userId != UserHandle.getUserId(callingUid)) { 7743 if (perms != null) { 7744 for (GrantUri grantUri : perms.keySet()) { 7745 if (grantUri.sourceUserId == userId) { 7746 String authority = grantUri.uri.getAuthority(); 7747 if (authority.equals(cpi.authority)) { 7748 return null; 7749 } 7750 } 7751 } 7752 } 7753 } 7754 if (checkUser) { 7755 userId = handleIncomingUser(callingPid, callingUid, userId, 7756 false, true, "checkContentProviderPermissionLocked " + cpi.authority, null); 7757 } 7758 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7759 cpi.applicationInfo.uid, cpi.exported) 7760 == PackageManager.PERMISSION_GRANTED) { 7761 return null; 7762 } 7763 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7764 cpi.applicationInfo.uid, cpi.exported) 7765 == PackageManager.PERMISSION_GRANTED) { 7766 return null; 7767 } 7768 7769 PathPermission[] pps = cpi.pathPermissions; 7770 if (pps != null) { 7771 int i = pps.length; 7772 while (i > 0) { 7773 i--; 7774 PathPermission pp = pps[i]; 7775 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7776 cpi.applicationInfo.uid, cpi.exported) 7777 == PackageManager.PERMISSION_GRANTED) { 7778 return null; 7779 } 7780 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7781 cpi.applicationInfo.uid, cpi.exported) 7782 == PackageManager.PERMISSION_GRANTED) { 7783 return null; 7784 } 7785 } 7786 } 7787 7788 if (perms != null) { 7789 for (GrantUri grantUri : perms.keySet()) { 7790 if (grantUri.uri.getAuthority().equals(cpi.authority)) { 7791 return null; 7792 } 7793 } 7794 } 7795 7796 String msg; 7797 if (!cpi.exported) { 7798 msg = "Permission Denial: opening provider " + cpi.name 7799 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7800 + ", uid=" + callingUid + ") that is not exported from uid " 7801 + cpi.applicationInfo.uid; 7802 } else { 7803 msg = "Permission Denial: opening provider " + cpi.name 7804 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7805 + ", uid=" + callingUid + ") requires " 7806 + cpi.readPermission + " or " + cpi.writePermission; 7807 } 7808 Slog.w(TAG, msg); 7809 return msg; 7810 } 7811 7812 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7813 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7814 if (r != null) { 7815 for (int i=0; i<r.conProviders.size(); i++) { 7816 ContentProviderConnection conn = r.conProviders.get(i); 7817 if (conn.provider == cpr) { 7818 if (DEBUG_PROVIDER) Slog.v(TAG, 7819 "Adding provider requested by " 7820 + r.processName + " from process " 7821 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7822 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7823 if (stable) { 7824 conn.stableCount++; 7825 conn.numStableIncs++; 7826 } else { 7827 conn.unstableCount++; 7828 conn.numUnstableIncs++; 7829 } 7830 return conn; 7831 } 7832 } 7833 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7834 if (stable) { 7835 conn.stableCount = 1; 7836 conn.numStableIncs = 1; 7837 } else { 7838 conn.unstableCount = 1; 7839 conn.numUnstableIncs = 1; 7840 } 7841 cpr.connections.add(conn); 7842 r.conProviders.add(conn); 7843 return conn; 7844 } 7845 cpr.addExternalProcessHandleLocked(externalProcessToken); 7846 return null; 7847 } 7848 7849 boolean decProviderCountLocked(ContentProviderConnection conn, 7850 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7851 if (conn != null) { 7852 cpr = conn.provider; 7853 if (DEBUG_PROVIDER) Slog.v(TAG, 7854 "Removing provider requested by " 7855 + conn.client.processName + " from process " 7856 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7857 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7858 if (stable) { 7859 conn.stableCount--; 7860 } else { 7861 conn.unstableCount--; 7862 } 7863 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7864 cpr.connections.remove(conn); 7865 conn.client.conProviders.remove(conn); 7866 return true; 7867 } 7868 return false; 7869 } 7870 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7871 return false; 7872 } 7873 7874 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7875 String name, IBinder token, boolean stable, int userId) { 7876 ContentProviderRecord cpr; 7877 ContentProviderConnection conn = null; 7878 ProviderInfo cpi = null; 7879 7880 synchronized(this) { 7881 ProcessRecord r = null; 7882 if (caller != null) { 7883 r = getRecordForAppLocked(caller); 7884 if (r == null) { 7885 throw new SecurityException( 7886 "Unable to find app for caller " + caller 7887 + " (pid=" + Binder.getCallingPid() 7888 + ") when getting content provider " + name); 7889 } 7890 } 7891 7892 boolean checkCrossUser = true; 7893 7894 // First check if this content provider has been published... 7895 cpr = mProviderMap.getProviderByName(name, userId); 7896 // If that didn't work, check if it exists for user 0 and then 7897 // verify that it's a singleton provider before using it. 7898 if (cpr == null && userId != UserHandle.USER_OWNER) { 7899 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 7900 if (cpr != null) { 7901 cpi = cpr.info; 7902 if (isSingleton(cpi.processName, cpi.applicationInfo, 7903 cpi.name, cpi.flags) 7904 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 7905 userId = UserHandle.USER_OWNER; 7906 checkCrossUser = false; 7907 } else { 7908 cpr = null; 7909 cpi = null; 7910 } 7911 } 7912 } 7913 7914 boolean providerRunning = cpr != null; 7915 if (providerRunning) { 7916 cpi = cpr.info; 7917 String msg; 7918 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 7919 != null) { 7920 throw new SecurityException(msg); 7921 } 7922 7923 if (r != null && cpr.canRunHere(r)) { 7924 // This provider has been published or is in the process 7925 // of being published... but it is also allowed to run 7926 // in the caller's process, so don't make a connection 7927 // and just let the caller instantiate its own instance. 7928 ContentProviderHolder holder = cpr.newHolder(null); 7929 // don't give caller the provider object, it needs 7930 // to make its own. 7931 holder.provider = null; 7932 return holder; 7933 } 7934 7935 final long origId = Binder.clearCallingIdentity(); 7936 7937 // In this case the provider instance already exists, so we can 7938 // return it right away. 7939 conn = incProviderCountLocked(r, cpr, token, stable); 7940 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7941 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7942 // If this is a perceptible app accessing the provider, 7943 // make sure to count it as being accessed and thus 7944 // back up on the LRU list. This is good because 7945 // content providers are often expensive to start. 7946 updateLruProcessLocked(cpr.proc, false, null); 7947 } 7948 } 7949 7950 if (cpr.proc != null) { 7951 if (false) { 7952 if (cpr.name.flattenToShortString().equals( 7953 "com.android.providers.calendar/.CalendarProvider2")) { 7954 Slog.v(TAG, "****************** KILLING " 7955 + cpr.name.flattenToShortString()); 7956 Process.killProcess(cpr.proc.pid); 7957 } 7958 } 7959 boolean success = updateOomAdjLocked(cpr.proc); 7960 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7961 // NOTE: there is still a race here where a signal could be 7962 // pending on the process even though we managed to update its 7963 // adj level. Not sure what to do about this, but at least 7964 // the race is now smaller. 7965 if (!success) { 7966 // Uh oh... it looks like the provider's process 7967 // has been killed on us. We need to wait for a new 7968 // process to be started, and make sure its death 7969 // doesn't kill our process. 7970 Slog.i(TAG, 7971 "Existing provider " + cpr.name.flattenToShortString() 7972 + " is crashing; detaching " + r); 7973 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7974 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7975 if (!lastRef) { 7976 // This wasn't the last ref our process had on 7977 // the provider... we have now been killed, bail. 7978 return null; 7979 } 7980 providerRunning = false; 7981 conn = null; 7982 } 7983 } 7984 7985 Binder.restoreCallingIdentity(origId); 7986 } 7987 7988 boolean singleton; 7989 if (!providerRunning) { 7990 try { 7991 cpi = AppGlobals.getPackageManager(). 7992 resolveContentProvider(name, 7993 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7994 } catch (RemoteException ex) { 7995 } 7996 if (cpi == null) { 7997 return null; 7998 } 7999 // If the provider is a singleton AND 8000 // (it's a call within the same user || the provider is a 8001 // privileged app) 8002 // Then allow connecting to the singleton provider 8003 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8004 cpi.name, cpi.flags) 8005 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 8006 if (singleton) { 8007 userId = UserHandle.USER_OWNER; 8008 } 8009 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 8010 8011 String msg; 8012 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 8013 != null) { 8014 throw new SecurityException(msg); 8015 } 8016 8017 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 8018 && !cpi.processName.equals("system")) { 8019 // If this content provider does not run in the system 8020 // process, and the system is not yet ready to run other 8021 // processes, then fail fast instead of hanging. 8022 throw new IllegalArgumentException( 8023 "Attempt to launch content provider before system ready"); 8024 } 8025 8026 // Make sure that the user who owns this provider is started. If not, 8027 // we don't want to allow it to run. 8028 if (mStartedUsers.get(userId) == null) { 8029 Slog.w(TAG, "Unable to launch app " 8030 + cpi.applicationInfo.packageName + "/" 8031 + cpi.applicationInfo.uid + " for provider " 8032 + name + ": user " + userId + " is stopped"); 8033 return null; 8034 } 8035 8036 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8037 cpr = mProviderMap.getProviderByClass(comp, userId); 8038 final boolean firstClass = cpr == null; 8039 if (firstClass) { 8040 try { 8041 ApplicationInfo ai = 8042 AppGlobals.getPackageManager(). 8043 getApplicationInfo( 8044 cpi.applicationInfo.packageName, 8045 STOCK_PM_FLAGS, userId); 8046 if (ai == null) { 8047 Slog.w(TAG, "No package info for content provider " 8048 + cpi.name); 8049 return null; 8050 } 8051 ai = getAppInfoForUser(ai, userId); 8052 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8053 } catch (RemoteException ex) { 8054 // pm is in same process, this will never happen. 8055 } 8056 } 8057 8058 if (r != null && cpr.canRunHere(r)) { 8059 // If this is a multiprocess provider, then just return its 8060 // info and allow the caller to instantiate it. Only do 8061 // this if the provider is the same user as the caller's 8062 // process, or can run as root (so can be in any process). 8063 return cpr.newHolder(null); 8064 } 8065 8066 if (DEBUG_PROVIDER) { 8067 RuntimeException e = new RuntimeException("here"); 8068 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8069 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8070 } 8071 8072 // This is single process, and our app is now connecting to it. 8073 // See if we are already in the process of launching this 8074 // provider. 8075 final int N = mLaunchingProviders.size(); 8076 int i; 8077 for (i=0; i<N; i++) { 8078 if (mLaunchingProviders.get(i) == cpr) { 8079 break; 8080 } 8081 } 8082 8083 // If the provider is not already being launched, then get it 8084 // started. 8085 if (i >= N) { 8086 final long origId = Binder.clearCallingIdentity(); 8087 8088 try { 8089 // Content provider is now in use, its package can't be stopped. 8090 try { 8091 AppGlobals.getPackageManager().setPackageStoppedState( 8092 cpr.appInfo.packageName, false, userId); 8093 } catch (RemoteException e) { 8094 } catch (IllegalArgumentException e) { 8095 Slog.w(TAG, "Failed trying to unstop package " 8096 + cpr.appInfo.packageName + ": " + e); 8097 } 8098 8099 // Use existing process if already started 8100 ProcessRecord proc = getProcessRecordLocked( 8101 cpi.processName, cpr.appInfo.uid, false); 8102 if (proc != null && proc.thread != null) { 8103 if (DEBUG_PROVIDER) { 8104 Slog.d(TAG, "Installing in existing process " + proc); 8105 } 8106 proc.pubProviders.put(cpi.name, cpr); 8107 try { 8108 proc.thread.scheduleInstallProvider(cpi); 8109 } catch (RemoteException e) { 8110 } 8111 } else { 8112 proc = startProcessLocked(cpi.processName, 8113 cpr.appInfo, false, 0, "content provider", 8114 new ComponentName(cpi.applicationInfo.packageName, 8115 cpi.name), false, false, false); 8116 if (proc == null) { 8117 Slog.w(TAG, "Unable to launch app " 8118 + cpi.applicationInfo.packageName + "/" 8119 + cpi.applicationInfo.uid + " for provider " 8120 + name + ": process is bad"); 8121 return null; 8122 } 8123 } 8124 cpr.launchingApp = proc; 8125 mLaunchingProviders.add(cpr); 8126 } finally { 8127 Binder.restoreCallingIdentity(origId); 8128 } 8129 } 8130 8131 // Make sure the provider is published (the same provider class 8132 // may be published under multiple names). 8133 if (firstClass) { 8134 mProviderMap.putProviderByClass(comp, cpr); 8135 } 8136 8137 mProviderMap.putProviderByName(name, cpr); 8138 conn = incProviderCountLocked(r, cpr, token, stable); 8139 if (conn != null) { 8140 conn.waiting = true; 8141 } 8142 } 8143 } 8144 8145 // Wait for the provider to be published... 8146 synchronized (cpr) { 8147 while (cpr.provider == null) { 8148 if (cpr.launchingApp == null) { 8149 Slog.w(TAG, "Unable to launch app " 8150 + cpi.applicationInfo.packageName + "/" 8151 + cpi.applicationInfo.uid + " for provider " 8152 + name + ": launching app became null"); 8153 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8154 UserHandle.getUserId(cpi.applicationInfo.uid), 8155 cpi.applicationInfo.packageName, 8156 cpi.applicationInfo.uid, name); 8157 return null; 8158 } 8159 try { 8160 if (DEBUG_MU) { 8161 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8162 + cpr.launchingApp); 8163 } 8164 if (conn != null) { 8165 conn.waiting = true; 8166 } 8167 cpr.wait(); 8168 } catch (InterruptedException ex) { 8169 } finally { 8170 if (conn != null) { 8171 conn.waiting = false; 8172 } 8173 } 8174 } 8175 } 8176 return cpr != null ? cpr.newHolder(conn) : null; 8177 } 8178 8179 @Override 8180 public final ContentProviderHolder getContentProvider( 8181 IApplicationThread caller, String name, int userId, boolean stable) { 8182 enforceNotIsolatedCaller("getContentProvider"); 8183 if (caller == null) { 8184 String msg = "null IApplicationThread when getting content provider " 8185 + name; 8186 Slog.w(TAG, msg); 8187 throw new SecurityException(msg); 8188 } 8189 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8190 // with cross-user grant. 8191 return getContentProviderImpl(caller, name, null, stable, userId); 8192 } 8193 8194 public ContentProviderHolder getContentProviderExternal( 8195 String name, int userId, IBinder token) { 8196 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8197 "Do not have permission in call getContentProviderExternal()"); 8198 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8199 false, true, "getContentProvider", null); 8200 return getContentProviderExternalUnchecked(name, token, userId); 8201 } 8202 8203 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8204 IBinder token, int userId) { 8205 return getContentProviderImpl(null, name, token, true, userId); 8206 } 8207 8208 /** 8209 * Drop a content provider from a ProcessRecord's bookkeeping 8210 */ 8211 public void removeContentProvider(IBinder connection, boolean stable) { 8212 enforceNotIsolatedCaller("removeContentProvider"); 8213 long ident = Binder.clearCallingIdentity(); 8214 try { 8215 synchronized (this) { 8216 ContentProviderConnection conn; 8217 try { 8218 conn = (ContentProviderConnection)connection; 8219 } catch (ClassCastException e) { 8220 String msg ="removeContentProvider: " + connection 8221 + " not a ContentProviderConnection"; 8222 Slog.w(TAG, msg); 8223 throw new IllegalArgumentException(msg); 8224 } 8225 if (conn == null) { 8226 throw new NullPointerException("connection is null"); 8227 } 8228 if (decProviderCountLocked(conn, null, null, stable)) { 8229 updateOomAdjLocked(); 8230 } 8231 } 8232 } finally { 8233 Binder.restoreCallingIdentity(ident); 8234 } 8235 } 8236 8237 public void removeContentProviderExternal(String name, IBinder token) { 8238 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8239 "Do not have permission in call removeContentProviderExternal()"); 8240 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8241 } 8242 8243 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8244 synchronized (this) { 8245 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8246 if(cpr == null) { 8247 //remove from mProvidersByClass 8248 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8249 return; 8250 } 8251 8252 //update content provider record entry info 8253 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8254 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8255 if (localCpr.hasExternalProcessHandles()) { 8256 if (localCpr.removeExternalProcessHandleLocked(token)) { 8257 updateOomAdjLocked(); 8258 } else { 8259 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8260 + " with no external reference for token: " 8261 + token + "."); 8262 } 8263 } else { 8264 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8265 + " with no external references."); 8266 } 8267 } 8268 } 8269 8270 public final void publishContentProviders(IApplicationThread caller, 8271 List<ContentProviderHolder> providers) { 8272 if (providers == null) { 8273 return; 8274 } 8275 8276 enforceNotIsolatedCaller("publishContentProviders"); 8277 synchronized (this) { 8278 final ProcessRecord r = getRecordForAppLocked(caller); 8279 if (DEBUG_MU) 8280 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8281 if (r == null) { 8282 throw new SecurityException( 8283 "Unable to find app for caller " + caller 8284 + " (pid=" + Binder.getCallingPid() 8285 + ") when publishing content providers"); 8286 } 8287 8288 final long origId = Binder.clearCallingIdentity(); 8289 8290 final int N = providers.size(); 8291 for (int i=0; i<N; i++) { 8292 ContentProviderHolder src = providers.get(i); 8293 if (src == null || src.info == null || src.provider == null) { 8294 continue; 8295 } 8296 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8297 if (DEBUG_MU) 8298 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8299 if (dst != null) { 8300 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8301 mProviderMap.putProviderByClass(comp, dst); 8302 String names[] = dst.info.authority.split(";"); 8303 for (int j = 0; j < names.length; j++) { 8304 mProviderMap.putProviderByName(names[j], dst); 8305 } 8306 8307 int NL = mLaunchingProviders.size(); 8308 int j; 8309 for (j=0; j<NL; j++) { 8310 if (mLaunchingProviders.get(j) == dst) { 8311 mLaunchingProviders.remove(j); 8312 j--; 8313 NL--; 8314 } 8315 } 8316 synchronized (dst) { 8317 dst.provider = src.provider; 8318 dst.proc = r; 8319 dst.notifyAll(); 8320 } 8321 updateOomAdjLocked(r); 8322 } 8323 } 8324 8325 Binder.restoreCallingIdentity(origId); 8326 } 8327 } 8328 8329 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8330 ContentProviderConnection conn; 8331 try { 8332 conn = (ContentProviderConnection)connection; 8333 } catch (ClassCastException e) { 8334 String msg ="refContentProvider: " + connection 8335 + " not a ContentProviderConnection"; 8336 Slog.w(TAG, msg); 8337 throw new IllegalArgumentException(msg); 8338 } 8339 if (conn == null) { 8340 throw new NullPointerException("connection is null"); 8341 } 8342 8343 synchronized (this) { 8344 if (stable > 0) { 8345 conn.numStableIncs += stable; 8346 } 8347 stable = conn.stableCount + stable; 8348 if (stable < 0) { 8349 throw new IllegalStateException("stableCount < 0: " + stable); 8350 } 8351 8352 if (unstable > 0) { 8353 conn.numUnstableIncs += unstable; 8354 } 8355 unstable = conn.unstableCount + unstable; 8356 if (unstable < 0) { 8357 throw new IllegalStateException("unstableCount < 0: " + unstable); 8358 } 8359 8360 if ((stable+unstable) <= 0) { 8361 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8362 + stable + " unstable=" + unstable); 8363 } 8364 conn.stableCount = stable; 8365 conn.unstableCount = unstable; 8366 return !conn.dead; 8367 } 8368 } 8369 8370 public void unstableProviderDied(IBinder connection) { 8371 ContentProviderConnection conn; 8372 try { 8373 conn = (ContentProviderConnection)connection; 8374 } catch (ClassCastException e) { 8375 String msg ="refContentProvider: " + connection 8376 + " not a ContentProviderConnection"; 8377 Slog.w(TAG, msg); 8378 throw new IllegalArgumentException(msg); 8379 } 8380 if (conn == null) { 8381 throw new NullPointerException("connection is null"); 8382 } 8383 8384 // Safely retrieve the content provider associated with the connection. 8385 IContentProvider provider; 8386 synchronized (this) { 8387 provider = conn.provider.provider; 8388 } 8389 8390 if (provider == null) { 8391 // Um, yeah, we're way ahead of you. 8392 return; 8393 } 8394 8395 // Make sure the caller is being honest with us. 8396 if (provider.asBinder().pingBinder()) { 8397 // Er, no, still looks good to us. 8398 synchronized (this) { 8399 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8400 + " says " + conn + " died, but we don't agree"); 8401 return; 8402 } 8403 } 8404 8405 // Well look at that! It's dead! 8406 synchronized (this) { 8407 if (conn.provider.provider != provider) { 8408 // But something changed... good enough. 8409 return; 8410 } 8411 8412 ProcessRecord proc = conn.provider.proc; 8413 if (proc == null || proc.thread == null) { 8414 // Seems like the process is already cleaned up. 8415 return; 8416 } 8417 8418 // As far as we're concerned, this is just like receiving a 8419 // death notification... just a bit prematurely. 8420 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8421 + ") early provider death"); 8422 final long ident = Binder.clearCallingIdentity(); 8423 try { 8424 appDiedLocked(proc, proc.pid, proc.thread); 8425 } finally { 8426 Binder.restoreCallingIdentity(ident); 8427 } 8428 } 8429 } 8430 8431 @Override 8432 public void appNotRespondingViaProvider(IBinder connection) { 8433 enforceCallingPermission( 8434 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8435 8436 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8437 if (conn == null) { 8438 Slog.w(TAG, "ContentProviderConnection is null"); 8439 return; 8440 } 8441 8442 final ProcessRecord host = conn.provider.proc; 8443 if (host == null) { 8444 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8445 return; 8446 } 8447 8448 final long token = Binder.clearCallingIdentity(); 8449 try { 8450 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8451 } finally { 8452 Binder.restoreCallingIdentity(token); 8453 } 8454 } 8455 8456 public final void installSystemProviders() { 8457 List<ProviderInfo> providers; 8458 synchronized (this) { 8459 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8460 providers = generateApplicationProvidersLocked(app); 8461 if (providers != null) { 8462 for (int i=providers.size()-1; i>=0; i--) { 8463 ProviderInfo pi = (ProviderInfo)providers.get(i); 8464 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8465 Slog.w(TAG, "Not installing system proc provider " + pi.name 8466 + ": not system .apk"); 8467 providers.remove(i); 8468 } 8469 } 8470 } 8471 } 8472 if (providers != null) { 8473 mSystemThread.installSystemProviders(providers); 8474 } 8475 8476 mCoreSettingsObserver = new CoreSettingsObserver(this); 8477 8478 mUsageStatsService.monitorPackages(); 8479 } 8480 8481 /** 8482 * Allows app to retrieve the MIME type of a URI without having permission 8483 * to access its content provider. 8484 * 8485 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8486 * 8487 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8488 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8489 */ 8490 public String getProviderMimeType(Uri uri, int userId) { 8491 enforceNotIsolatedCaller("getProviderMimeType"); 8492 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8493 userId, false, true, "getProviderMimeType", null); 8494 final String name = uri.getAuthority(); 8495 final long ident = Binder.clearCallingIdentity(); 8496 ContentProviderHolder holder = null; 8497 8498 try { 8499 holder = getContentProviderExternalUnchecked(name, null, userId); 8500 if (holder != null) { 8501 return holder.provider.getType(uri); 8502 } 8503 } catch (RemoteException e) { 8504 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8505 return null; 8506 } finally { 8507 if (holder != null) { 8508 removeContentProviderExternalUnchecked(name, null, userId); 8509 } 8510 Binder.restoreCallingIdentity(ident); 8511 } 8512 8513 return null; 8514 } 8515 8516 // ========================================================= 8517 // GLOBAL MANAGEMENT 8518 // ========================================================= 8519 8520 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8521 boolean isolated) { 8522 String proc = customProcess != null ? customProcess : info.processName; 8523 BatteryStatsImpl.Uid.Proc ps = null; 8524 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8525 int uid = info.uid; 8526 if (isolated) { 8527 int userId = UserHandle.getUserId(uid); 8528 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8529 while (true) { 8530 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8531 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8532 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8533 } 8534 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8535 mNextIsolatedProcessUid++; 8536 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8537 // No process for this uid, use it. 8538 break; 8539 } 8540 stepsLeft--; 8541 if (stepsLeft <= 0) { 8542 return null; 8543 } 8544 } 8545 } 8546 return new ProcessRecord(stats, info, proc, uid); 8547 } 8548 8549 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8550 ProcessRecord app; 8551 if (!isolated) { 8552 app = getProcessRecordLocked(info.processName, info.uid, true); 8553 } else { 8554 app = null; 8555 } 8556 8557 if (app == null) { 8558 app = newProcessRecordLocked(info, null, isolated); 8559 mProcessNames.put(info.processName, app.uid, app); 8560 if (isolated) { 8561 mIsolatedProcesses.put(app.uid, app); 8562 } 8563 updateLruProcessLocked(app, false, null); 8564 updateOomAdjLocked(); 8565 } 8566 8567 // This package really, really can not be stopped. 8568 try { 8569 AppGlobals.getPackageManager().setPackageStoppedState( 8570 info.packageName, false, UserHandle.getUserId(app.uid)); 8571 } catch (RemoteException e) { 8572 } catch (IllegalArgumentException e) { 8573 Slog.w(TAG, "Failed trying to unstop package " 8574 + info.packageName + ": " + e); 8575 } 8576 8577 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8578 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8579 app.persistent = true; 8580 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8581 } 8582 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8583 mPersistentStartingProcesses.add(app); 8584 startProcessLocked(app, "added application", app.processName); 8585 } 8586 8587 return app; 8588 } 8589 8590 public void unhandledBack() { 8591 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8592 "unhandledBack()"); 8593 8594 synchronized(this) { 8595 final long origId = Binder.clearCallingIdentity(); 8596 try { 8597 getFocusedStack().unhandledBackLocked(); 8598 } finally { 8599 Binder.restoreCallingIdentity(origId); 8600 } 8601 } 8602 } 8603 8604 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8605 enforceNotIsolatedCaller("openContentUri"); 8606 final int userId = UserHandle.getCallingUserId(); 8607 String name = uri.getAuthority(); 8608 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8609 ParcelFileDescriptor pfd = null; 8610 if (cph != null) { 8611 // We record the binder invoker's uid in thread-local storage before 8612 // going to the content provider to open the file. Later, in the code 8613 // that handles all permissions checks, we look for this uid and use 8614 // that rather than the Activity Manager's own uid. The effect is that 8615 // we do the check against the caller's permissions even though it looks 8616 // to the content provider like the Activity Manager itself is making 8617 // the request. 8618 sCallerIdentity.set(new Identity( 8619 Binder.getCallingPid(), Binder.getCallingUid())); 8620 try { 8621 pfd = cph.provider.openFile(null, uri, "r", null); 8622 } catch (FileNotFoundException e) { 8623 // do nothing; pfd will be returned null 8624 } finally { 8625 // Ensure that whatever happens, we clean up the identity state 8626 sCallerIdentity.remove(); 8627 } 8628 8629 // We've got the fd now, so we're done with the provider. 8630 removeContentProviderExternalUnchecked(name, null, userId); 8631 } else { 8632 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8633 } 8634 return pfd; 8635 } 8636 8637 // Actually is sleeping or shutting down or whatever else in the future 8638 // is an inactive state. 8639 public boolean isSleepingOrShuttingDown() { 8640 return mSleeping || mShuttingDown; 8641 } 8642 8643 public boolean isSleeping() { 8644 return mSleeping; 8645 } 8646 8647 void goingToSleep() { 8648 synchronized(this) { 8649 mWentToSleep = true; 8650 updateEventDispatchingLocked(); 8651 goToSleepIfNeededLocked(); 8652 } 8653 } 8654 8655 void finishRunningVoiceLocked() { 8656 if (mRunningVoice) { 8657 mRunningVoice = false; 8658 goToSleepIfNeededLocked(); 8659 } 8660 } 8661 8662 void goToSleepIfNeededLocked() { 8663 if (mWentToSleep && !mRunningVoice) { 8664 if (!mSleeping) { 8665 mSleeping = true; 8666 mStackSupervisor.goingToSleepLocked(); 8667 8668 // Initialize the wake times of all processes. 8669 checkExcessivePowerUsageLocked(false); 8670 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8671 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8672 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8673 } 8674 } 8675 } 8676 8677 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 8678 mTaskPersister.notify(task, flush); 8679 } 8680 8681 @Override 8682 public boolean shutdown(int timeout) { 8683 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8684 != PackageManager.PERMISSION_GRANTED) { 8685 throw new SecurityException("Requires permission " 8686 + android.Manifest.permission.SHUTDOWN); 8687 } 8688 8689 boolean timedout = false; 8690 8691 synchronized(this) { 8692 mShuttingDown = true; 8693 updateEventDispatchingLocked(); 8694 timedout = mStackSupervisor.shutdownLocked(timeout); 8695 } 8696 8697 mAppOpsService.shutdown(); 8698 mUsageStatsService.shutdown(); 8699 mBatteryStatsService.shutdown(); 8700 synchronized (this) { 8701 mProcessStats.shutdownLocked(); 8702 } 8703 notifyTaskPersisterLocked(null, true); 8704 8705 return timedout; 8706 } 8707 8708 public final void activitySlept(IBinder token) { 8709 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8710 8711 final long origId = Binder.clearCallingIdentity(); 8712 8713 synchronized (this) { 8714 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8715 if (r != null) { 8716 mStackSupervisor.activitySleptLocked(r); 8717 } 8718 } 8719 8720 Binder.restoreCallingIdentity(origId); 8721 } 8722 8723 void logLockScreen(String msg) { 8724 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8725 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8726 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8727 mStackSupervisor.mDismissKeyguardOnNextActivity); 8728 } 8729 8730 private void comeOutOfSleepIfNeededLocked() { 8731 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8732 if (mSleeping) { 8733 mSleeping = false; 8734 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8735 } 8736 } 8737 } 8738 8739 void wakingUp() { 8740 synchronized(this) { 8741 mWentToSleep = false; 8742 updateEventDispatchingLocked(); 8743 comeOutOfSleepIfNeededLocked(); 8744 } 8745 } 8746 8747 void startRunningVoiceLocked() { 8748 if (!mRunningVoice) { 8749 mRunningVoice = true; 8750 comeOutOfSleepIfNeededLocked(); 8751 } 8752 } 8753 8754 private void updateEventDispatchingLocked() { 8755 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8756 } 8757 8758 public void setLockScreenShown(boolean shown) { 8759 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8760 != PackageManager.PERMISSION_GRANTED) { 8761 throw new SecurityException("Requires permission " 8762 + android.Manifest.permission.DEVICE_POWER); 8763 } 8764 8765 synchronized(this) { 8766 long ident = Binder.clearCallingIdentity(); 8767 try { 8768 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8769 mLockScreenShown = shown; 8770 comeOutOfSleepIfNeededLocked(); 8771 } finally { 8772 Binder.restoreCallingIdentity(ident); 8773 } 8774 } 8775 } 8776 8777 public void stopAppSwitches() { 8778 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8779 != PackageManager.PERMISSION_GRANTED) { 8780 throw new SecurityException("Requires permission " 8781 + android.Manifest.permission.STOP_APP_SWITCHES); 8782 } 8783 8784 synchronized(this) { 8785 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8786 + APP_SWITCH_DELAY_TIME; 8787 mDidAppSwitch = false; 8788 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8789 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8790 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8791 } 8792 } 8793 8794 public void resumeAppSwitches() { 8795 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8796 != PackageManager.PERMISSION_GRANTED) { 8797 throw new SecurityException("Requires permission " 8798 + android.Manifest.permission.STOP_APP_SWITCHES); 8799 } 8800 8801 synchronized(this) { 8802 // Note that we don't execute any pending app switches... we will 8803 // let those wait until either the timeout, or the next start 8804 // activity request. 8805 mAppSwitchesAllowedTime = 0; 8806 } 8807 } 8808 8809 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8810 String name) { 8811 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8812 return true; 8813 } 8814 8815 final int perm = checkComponentPermission( 8816 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8817 callingUid, -1, true); 8818 if (perm == PackageManager.PERMISSION_GRANTED) { 8819 return true; 8820 } 8821 8822 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8823 return false; 8824 } 8825 8826 public void setDebugApp(String packageName, boolean waitForDebugger, 8827 boolean persistent) { 8828 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8829 "setDebugApp()"); 8830 8831 long ident = Binder.clearCallingIdentity(); 8832 try { 8833 // Note that this is not really thread safe if there are multiple 8834 // callers into it at the same time, but that's not a situation we 8835 // care about. 8836 if (persistent) { 8837 final ContentResolver resolver = mContext.getContentResolver(); 8838 Settings.Global.putString( 8839 resolver, Settings.Global.DEBUG_APP, 8840 packageName); 8841 Settings.Global.putInt( 8842 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8843 waitForDebugger ? 1 : 0); 8844 } 8845 8846 synchronized (this) { 8847 if (!persistent) { 8848 mOrigDebugApp = mDebugApp; 8849 mOrigWaitForDebugger = mWaitForDebugger; 8850 } 8851 mDebugApp = packageName; 8852 mWaitForDebugger = waitForDebugger; 8853 mDebugTransient = !persistent; 8854 if (packageName != null) { 8855 forceStopPackageLocked(packageName, -1, false, false, true, true, 8856 false, UserHandle.USER_ALL, "set debug app"); 8857 } 8858 } 8859 } finally { 8860 Binder.restoreCallingIdentity(ident); 8861 } 8862 } 8863 8864 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8865 synchronized (this) { 8866 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8867 if (!isDebuggable) { 8868 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8869 throw new SecurityException("Process not debuggable: " + app.packageName); 8870 } 8871 } 8872 8873 mOpenGlTraceApp = processName; 8874 } 8875 } 8876 8877 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8878 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8879 synchronized (this) { 8880 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8881 if (!isDebuggable) { 8882 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8883 throw new SecurityException("Process not debuggable: " + app.packageName); 8884 } 8885 } 8886 mProfileApp = processName; 8887 mProfileFile = profileFile; 8888 if (mProfileFd != null) { 8889 try { 8890 mProfileFd.close(); 8891 } catch (IOException e) { 8892 } 8893 mProfileFd = null; 8894 } 8895 mProfileFd = profileFd; 8896 mProfileType = 0; 8897 mAutoStopProfiler = autoStopProfiler; 8898 } 8899 } 8900 8901 @Override 8902 public void setAlwaysFinish(boolean enabled) { 8903 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8904 "setAlwaysFinish()"); 8905 8906 Settings.Global.putInt( 8907 mContext.getContentResolver(), 8908 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8909 8910 synchronized (this) { 8911 mAlwaysFinishActivities = enabled; 8912 } 8913 } 8914 8915 @Override 8916 public void setActivityController(IActivityController controller) { 8917 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8918 "setActivityController()"); 8919 synchronized (this) { 8920 mController = controller; 8921 Watchdog.getInstance().setActivityController(controller); 8922 } 8923 } 8924 8925 @Override 8926 public void setUserIsMonkey(boolean userIsMonkey) { 8927 synchronized (this) { 8928 synchronized (mPidsSelfLocked) { 8929 final int callingPid = Binder.getCallingPid(); 8930 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8931 if (precessRecord == null) { 8932 throw new SecurityException("Unknown process: " + callingPid); 8933 } 8934 if (precessRecord.instrumentationUiAutomationConnection == null) { 8935 throw new SecurityException("Only an instrumentation process " 8936 + "with a UiAutomation can call setUserIsMonkey"); 8937 } 8938 } 8939 mUserIsMonkey = userIsMonkey; 8940 } 8941 } 8942 8943 @Override 8944 public boolean isUserAMonkey() { 8945 synchronized (this) { 8946 // If there is a controller also implies the user is a monkey. 8947 return (mUserIsMonkey || mController != null); 8948 } 8949 } 8950 8951 public void requestBugReport() { 8952 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8953 SystemProperties.set("ctl.start", "bugreport"); 8954 } 8955 8956 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8957 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8958 } 8959 8960 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8961 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8962 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8963 } 8964 return KEY_DISPATCHING_TIMEOUT; 8965 } 8966 8967 @Override 8968 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8969 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8970 != PackageManager.PERMISSION_GRANTED) { 8971 throw new SecurityException("Requires permission " 8972 + android.Manifest.permission.FILTER_EVENTS); 8973 } 8974 ProcessRecord proc; 8975 long timeout; 8976 synchronized (this) { 8977 synchronized (mPidsSelfLocked) { 8978 proc = mPidsSelfLocked.get(pid); 8979 } 8980 timeout = getInputDispatchingTimeoutLocked(proc); 8981 } 8982 8983 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8984 return -1; 8985 } 8986 8987 return timeout; 8988 } 8989 8990 /** 8991 * Handle input dispatching timeouts. 8992 * Returns whether input dispatching should be aborted or not. 8993 */ 8994 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8995 final ActivityRecord activity, final ActivityRecord parent, 8996 final boolean aboveSystem, String reason) { 8997 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8998 != PackageManager.PERMISSION_GRANTED) { 8999 throw new SecurityException("Requires permission " 9000 + android.Manifest.permission.FILTER_EVENTS); 9001 } 9002 9003 final String annotation; 9004 if (reason == null) { 9005 annotation = "Input dispatching timed out"; 9006 } else { 9007 annotation = "Input dispatching timed out (" + reason + ")"; 9008 } 9009 9010 if (proc != null) { 9011 synchronized (this) { 9012 if (proc.debugging) { 9013 return false; 9014 } 9015 9016 if (mDidDexOpt) { 9017 // Give more time since we were dexopting. 9018 mDidDexOpt = false; 9019 return false; 9020 } 9021 9022 if (proc.instrumentationClass != null) { 9023 Bundle info = new Bundle(); 9024 info.putString("shortMsg", "keyDispatchingTimedOut"); 9025 info.putString("longMsg", annotation); 9026 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 9027 return true; 9028 } 9029 } 9030 mHandler.post(new Runnable() { 9031 @Override 9032 public void run() { 9033 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9034 } 9035 }); 9036 } 9037 9038 return true; 9039 } 9040 9041 public Bundle getAssistContextExtras(int requestType) { 9042 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9043 "getAssistContextExtras()"); 9044 PendingAssistExtras pae; 9045 Bundle extras = new Bundle(); 9046 synchronized (this) { 9047 ActivityRecord activity = getFocusedStack().mResumedActivity; 9048 if (activity == null) { 9049 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9050 return null; 9051 } 9052 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9053 if (activity.app == null || activity.app.thread == null) { 9054 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9055 return extras; 9056 } 9057 if (activity.app.pid == Binder.getCallingPid()) { 9058 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9059 return extras; 9060 } 9061 pae = new PendingAssistExtras(activity); 9062 try { 9063 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9064 requestType); 9065 mPendingAssistExtras.add(pae); 9066 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9067 } catch (RemoteException e) { 9068 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9069 return extras; 9070 } 9071 } 9072 synchronized (pae) { 9073 while (!pae.haveResult) { 9074 try { 9075 pae.wait(); 9076 } catch (InterruptedException e) { 9077 } 9078 } 9079 if (pae.result != null) { 9080 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9081 } 9082 } 9083 synchronized (this) { 9084 mPendingAssistExtras.remove(pae); 9085 mHandler.removeCallbacks(pae); 9086 } 9087 return extras; 9088 } 9089 9090 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9091 PendingAssistExtras pae = (PendingAssistExtras)token; 9092 synchronized (pae) { 9093 pae.result = extras; 9094 pae.haveResult = true; 9095 pae.notifyAll(); 9096 } 9097 } 9098 9099 public void registerProcessObserver(IProcessObserver observer) { 9100 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9101 "registerProcessObserver()"); 9102 synchronized (this) { 9103 mProcessObservers.register(observer); 9104 } 9105 } 9106 9107 @Override 9108 public void unregisterProcessObserver(IProcessObserver observer) { 9109 synchronized (this) { 9110 mProcessObservers.unregister(observer); 9111 } 9112 } 9113 9114 @Override 9115 public boolean convertFromTranslucent(IBinder token) { 9116 final long origId = Binder.clearCallingIdentity(); 9117 try { 9118 synchronized (this) { 9119 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9120 if (r == null) { 9121 return false; 9122 } 9123 if (r.changeWindowTranslucency(true)) { 9124 mWindowManager.setAppFullscreen(token, true); 9125 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9126 return true; 9127 } 9128 return false; 9129 } 9130 } finally { 9131 Binder.restoreCallingIdentity(origId); 9132 } 9133 } 9134 9135 @Override 9136 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9137 final long origId = Binder.clearCallingIdentity(); 9138 try { 9139 synchronized (this) { 9140 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9141 if (r == null) { 9142 return false; 9143 } 9144 if (r.changeWindowTranslucency(false)) { 9145 r.task.stack.convertToTranslucent(r, options); 9146 mWindowManager.setAppFullscreen(token, false); 9147 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9148 return true; 9149 } 9150 return false; 9151 } 9152 } finally { 9153 Binder.restoreCallingIdentity(origId); 9154 } 9155 } 9156 9157 @Override 9158 public ActivityOptions getActivityOptions(IBinder token) { 9159 final long origId = Binder.clearCallingIdentity(); 9160 try { 9161 synchronized (this) { 9162 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9163 if (r != null) { 9164 final ActivityOptions activityOptions = r.pendingOptions; 9165 r.pendingOptions = null; 9166 return activityOptions; 9167 } 9168 return null; 9169 } 9170 } finally { 9171 Binder.restoreCallingIdentity(origId); 9172 } 9173 } 9174 9175 @Override 9176 public void setImmersive(IBinder token, boolean immersive) { 9177 synchronized(this) { 9178 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9179 if (r == null) { 9180 throw new IllegalArgumentException(); 9181 } 9182 r.immersive = immersive; 9183 9184 // update associated state if we're frontmost 9185 if (r == mFocusedActivity) { 9186 if (DEBUG_IMMERSIVE) { 9187 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9188 } 9189 applyUpdateLockStateLocked(r); 9190 } 9191 } 9192 } 9193 9194 @Override 9195 public boolean isImmersive(IBinder token) { 9196 synchronized (this) { 9197 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9198 if (r == null) { 9199 throw new IllegalArgumentException(); 9200 } 9201 return r.immersive; 9202 } 9203 } 9204 9205 public boolean isTopActivityImmersive() { 9206 enforceNotIsolatedCaller("startActivity"); 9207 synchronized (this) { 9208 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9209 return (r != null) ? r.immersive : false; 9210 } 9211 } 9212 9213 public final void enterSafeMode() { 9214 synchronized(this) { 9215 // It only makes sense to do this before the system is ready 9216 // and started launching other packages. 9217 if (!mSystemReady) { 9218 try { 9219 AppGlobals.getPackageManager().enterSafeMode(); 9220 } catch (RemoteException e) { 9221 } 9222 } 9223 9224 mSafeMode = true; 9225 } 9226 } 9227 9228 public final void showSafeModeOverlay() { 9229 View v = LayoutInflater.from(mContext).inflate( 9230 com.android.internal.R.layout.safe_mode, null); 9231 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9232 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9233 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9234 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9235 lp.gravity = Gravity.BOTTOM | Gravity.START; 9236 lp.format = v.getBackground().getOpacity(); 9237 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9238 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9239 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9240 ((WindowManager)mContext.getSystemService( 9241 Context.WINDOW_SERVICE)).addView(v, lp); 9242 } 9243 9244 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9245 if (!(sender instanceof PendingIntentRecord)) { 9246 return; 9247 } 9248 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9249 synchronized (stats) { 9250 if (mBatteryStatsService.isOnBattery()) { 9251 mBatteryStatsService.enforceCallingPermission(); 9252 PendingIntentRecord rec = (PendingIntentRecord)sender; 9253 int MY_UID = Binder.getCallingUid(); 9254 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9255 BatteryStatsImpl.Uid.Pkg pkg = 9256 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9257 sourcePkg != null ? sourcePkg : rec.key.packageName); 9258 pkg.incWakeupsLocked(); 9259 } 9260 } 9261 } 9262 9263 public boolean killPids(int[] pids, String pReason, boolean secure) { 9264 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9265 throw new SecurityException("killPids only available to the system"); 9266 } 9267 String reason = (pReason == null) ? "Unknown" : pReason; 9268 // XXX Note: don't acquire main activity lock here, because the window 9269 // manager calls in with its locks held. 9270 9271 boolean killed = false; 9272 synchronized (mPidsSelfLocked) { 9273 int[] types = new int[pids.length]; 9274 int worstType = 0; 9275 for (int i=0; i<pids.length; i++) { 9276 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9277 if (proc != null) { 9278 int type = proc.setAdj; 9279 types[i] = type; 9280 if (type > worstType) { 9281 worstType = type; 9282 } 9283 } 9284 } 9285 9286 // If the worst oom_adj is somewhere in the cached proc LRU range, 9287 // then constrain it so we will kill all cached procs. 9288 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9289 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9290 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9291 } 9292 9293 // If this is not a secure call, don't let it kill processes that 9294 // are important. 9295 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9296 worstType = ProcessList.SERVICE_ADJ; 9297 } 9298 9299 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9300 for (int i=0; i<pids.length; i++) { 9301 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9302 if (proc == null) { 9303 continue; 9304 } 9305 int adj = proc.setAdj; 9306 if (adj >= worstType && !proc.killedByAm) { 9307 killUnneededProcessLocked(proc, reason); 9308 killed = true; 9309 } 9310 } 9311 } 9312 return killed; 9313 } 9314 9315 @Override 9316 public void killUid(int uid, String reason) { 9317 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9318 throw new SecurityException("killUid only available to the system"); 9319 } 9320 synchronized (this) { 9321 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9322 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9323 reason != null ? reason : "kill uid"); 9324 } 9325 } 9326 9327 @Override 9328 public boolean killProcessesBelowForeground(String reason) { 9329 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9330 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9331 } 9332 9333 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9334 } 9335 9336 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9337 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9338 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9339 } 9340 9341 boolean killed = false; 9342 synchronized (mPidsSelfLocked) { 9343 final int size = mPidsSelfLocked.size(); 9344 for (int i = 0; i < size; i++) { 9345 final int pid = mPidsSelfLocked.keyAt(i); 9346 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9347 if (proc == null) continue; 9348 9349 final int adj = proc.setAdj; 9350 if (adj > belowAdj && !proc.killedByAm) { 9351 killUnneededProcessLocked(proc, reason); 9352 killed = true; 9353 } 9354 } 9355 } 9356 return killed; 9357 } 9358 9359 @Override 9360 public void hang(final IBinder who, boolean allowRestart) { 9361 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9362 != PackageManager.PERMISSION_GRANTED) { 9363 throw new SecurityException("Requires permission " 9364 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9365 } 9366 9367 final IBinder.DeathRecipient death = new DeathRecipient() { 9368 @Override 9369 public void binderDied() { 9370 synchronized (this) { 9371 notifyAll(); 9372 } 9373 } 9374 }; 9375 9376 try { 9377 who.linkToDeath(death, 0); 9378 } catch (RemoteException e) { 9379 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9380 return; 9381 } 9382 9383 synchronized (this) { 9384 Watchdog.getInstance().setAllowRestart(allowRestart); 9385 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9386 synchronized (death) { 9387 while (who.isBinderAlive()) { 9388 try { 9389 death.wait(); 9390 } catch (InterruptedException e) { 9391 } 9392 } 9393 } 9394 Watchdog.getInstance().setAllowRestart(true); 9395 } 9396 } 9397 9398 @Override 9399 public void restart() { 9400 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9401 != PackageManager.PERMISSION_GRANTED) { 9402 throw new SecurityException("Requires permission " 9403 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9404 } 9405 9406 Log.i(TAG, "Sending shutdown broadcast..."); 9407 9408 BroadcastReceiver br = new BroadcastReceiver() { 9409 @Override public void onReceive(Context context, Intent intent) { 9410 // Now the broadcast is done, finish up the low-level shutdown. 9411 Log.i(TAG, "Shutting down activity manager..."); 9412 shutdown(10000); 9413 Log.i(TAG, "Shutdown complete, restarting!"); 9414 Process.killProcess(Process.myPid()); 9415 System.exit(10); 9416 } 9417 }; 9418 9419 // First send the high-level shut down broadcast. 9420 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9421 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9422 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9423 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9424 mContext.sendOrderedBroadcastAsUser(intent, 9425 UserHandle.ALL, null, br, mHandler, 0, null, null); 9426 */ 9427 br.onReceive(mContext, intent); 9428 } 9429 9430 private long getLowRamTimeSinceIdle(long now) { 9431 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9432 } 9433 9434 @Override 9435 public void performIdleMaintenance() { 9436 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9437 != PackageManager.PERMISSION_GRANTED) { 9438 throw new SecurityException("Requires permission " 9439 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9440 } 9441 9442 synchronized (this) { 9443 final long now = SystemClock.uptimeMillis(); 9444 final long timeSinceLastIdle = now - mLastIdleTime; 9445 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9446 mLastIdleTime = now; 9447 mLowRamTimeSinceLastIdle = 0; 9448 if (mLowRamStartTime != 0) { 9449 mLowRamStartTime = now; 9450 } 9451 9452 StringBuilder sb = new StringBuilder(128); 9453 sb.append("Idle maintenance over "); 9454 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9455 sb.append(" low RAM for "); 9456 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9457 Slog.i(TAG, sb.toString()); 9458 9459 // If at least 1/3 of our time since the last idle period has been spent 9460 // with RAM low, then we want to kill processes. 9461 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9462 9463 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9464 ProcessRecord proc = mLruProcesses.get(i); 9465 if (proc.notCachedSinceIdle) { 9466 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9467 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9468 if (doKilling && proc.initialIdlePss != 0 9469 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9470 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9471 + " from " + proc.initialIdlePss + ")"); 9472 } 9473 } 9474 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9475 proc.notCachedSinceIdle = true; 9476 proc.initialIdlePss = 0; 9477 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9478 isSleeping(), now); 9479 } 9480 } 9481 9482 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9483 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9484 } 9485 } 9486 9487 private void retrieveSettings() { 9488 final ContentResolver resolver = mContext.getContentResolver(); 9489 String debugApp = Settings.Global.getString( 9490 resolver, Settings.Global.DEBUG_APP); 9491 boolean waitForDebugger = Settings.Global.getInt( 9492 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9493 boolean alwaysFinishActivities = Settings.Global.getInt( 9494 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9495 boolean forceRtl = Settings.Global.getInt( 9496 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9497 // Transfer any global setting for forcing RTL layout, into a System Property 9498 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9499 9500 Configuration configuration = new Configuration(); 9501 Settings.System.getConfiguration(resolver, configuration); 9502 if (forceRtl) { 9503 // This will take care of setting the correct layout direction flags 9504 configuration.setLayoutDirection(configuration.locale); 9505 } 9506 9507 synchronized (this) { 9508 mDebugApp = mOrigDebugApp = debugApp; 9509 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9510 mAlwaysFinishActivities = alwaysFinishActivities; 9511 // This happens before any activities are started, so we can 9512 // change mConfiguration in-place. 9513 updateConfigurationLocked(configuration, null, false, true); 9514 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9515 } 9516 } 9517 9518 public boolean testIsSystemReady() { 9519 // no need to synchronize(this) just to read & return the value 9520 return mSystemReady; 9521 } 9522 9523 private static File getCalledPreBootReceiversFile() { 9524 File dataDir = Environment.getDataDirectory(); 9525 File systemDir = new File(dataDir, "system"); 9526 File fname = new File(systemDir, "called_pre_boots.dat"); 9527 return fname; 9528 } 9529 9530 static final int LAST_DONE_VERSION = 10000; 9531 9532 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9533 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9534 File file = getCalledPreBootReceiversFile(); 9535 FileInputStream fis = null; 9536 try { 9537 fis = new FileInputStream(file); 9538 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9539 int fvers = dis.readInt(); 9540 if (fvers == LAST_DONE_VERSION) { 9541 String vers = dis.readUTF(); 9542 String codename = dis.readUTF(); 9543 String build = dis.readUTF(); 9544 if (android.os.Build.VERSION.RELEASE.equals(vers) 9545 && android.os.Build.VERSION.CODENAME.equals(codename) 9546 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9547 int num = dis.readInt(); 9548 while (num > 0) { 9549 num--; 9550 String pkg = dis.readUTF(); 9551 String cls = dis.readUTF(); 9552 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9553 } 9554 } 9555 } 9556 } catch (FileNotFoundException e) { 9557 } catch (IOException e) { 9558 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9559 } finally { 9560 if (fis != null) { 9561 try { 9562 fis.close(); 9563 } catch (IOException e) { 9564 } 9565 } 9566 } 9567 return lastDoneReceivers; 9568 } 9569 9570 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9571 File file = getCalledPreBootReceiversFile(); 9572 FileOutputStream fos = null; 9573 DataOutputStream dos = null; 9574 try { 9575 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9576 fos = new FileOutputStream(file); 9577 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9578 dos.writeInt(LAST_DONE_VERSION); 9579 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9580 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9581 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9582 dos.writeInt(list.size()); 9583 for (int i=0; i<list.size(); i++) { 9584 dos.writeUTF(list.get(i).getPackageName()); 9585 dos.writeUTF(list.get(i).getClassName()); 9586 } 9587 } catch (IOException e) { 9588 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9589 file.delete(); 9590 } finally { 9591 FileUtils.sync(fos); 9592 if (dos != null) { 9593 try { 9594 dos.close(); 9595 } catch (IOException e) { 9596 // TODO Auto-generated catch block 9597 e.printStackTrace(); 9598 } 9599 } 9600 } 9601 } 9602 9603 public void systemReady(final Runnable goingCallback) { 9604 synchronized(this) { 9605 if (mSystemReady) { 9606 if (goingCallback != null) goingCallback.run(); 9607 return; 9608 } 9609 9610 if (mRecentTasks == null) { 9611 mRecentTasks = mTaskPersister.restoreTasksLocked(); 9612 if (!mRecentTasks.isEmpty()) { 9613 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 9614 } 9615 mTaskPersister.startPersisting(); 9616 } 9617 9618 // Check to see if there are any update receivers to run. 9619 if (!mDidUpdate) { 9620 if (mWaitingUpdate) { 9621 return; 9622 } 9623 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9624 List<ResolveInfo> ris = null; 9625 try { 9626 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9627 intent, null, 0, 0); 9628 } catch (RemoteException e) { 9629 } 9630 if (ris != null) { 9631 for (int i=ris.size()-1; i>=0; i--) { 9632 if ((ris.get(i).activityInfo.applicationInfo.flags 9633 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9634 ris.remove(i); 9635 } 9636 } 9637 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9638 9639 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9640 9641 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9642 for (int i=0; i<ris.size(); i++) { 9643 ActivityInfo ai = ris.get(i).activityInfo; 9644 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9645 if (lastDoneReceivers.contains(comp)) { 9646 // We already did the pre boot receiver for this app with the current 9647 // platform version, so don't do it again... 9648 ris.remove(i); 9649 i--; 9650 // ...however, do keep it as one that has been done, so we don't 9651 // forget about it when rewriting the file of last done receivers. 9652 doneReceivers.add(comp); 9653 } 9654 } 9655 9656 final int[] users = getUsersLocked(); 9657 for (int i=0; i<ris.size(); i++) { 9658 ActivityInfo ai = ris.get(i).activityInfo; 9659 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9660 doneReceivers.add(comp); 9661 intent.setComponent(comp); 9662 for (int j=0; j<users.length; j++) { 9663 IIntentReceiver finisher = null; 9664 if (i == ris.size()-1 && j == users.length-1) { 9665 finisher = new IIntentReceiver.Stub() { 9666 public void performReceive(Intent intent, int resultCode, 9667 String data, Bundle extras, boolean ordered, 9668 boolean sticky, int sendingUser) { 9669 // The raw IIntentReceiver interface is called 9670 // with the AM lock held, so redispatch to 9671 // execute our code without the lock. 9672 mHandler.post(new Runnable() { 9673 public void run() { 9674 synchronized (ActivityManagerService.this) { 9675 mDidUpdate = true; 9676 } 9677 writeLastDonePreBootReceivers(doneReceivers); 9678 showBootMessage(mContext.getText( 9679 R.string.android_upgrading_complete), 9680 false); 9681 systemReady(goingCallback); 9682 } 9683 }); 9684 } 9685 }; 9686 } 9687 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9688 + " for user " + users[j]); 9689 broadcastIntentLocked(null, null, intent, null, finisher, 9690 0, null, null, null, AppOpsManager.OP_NONE, 9691 true, false, MY_PID, Process.SYSTEM_UID, 9692 users[j]); 9693 if (finisher != null) { 9694 mWaitingUpdate = true; 9695 } 9696 } 9697 } 9698 } 9699 if (mWaitingUpdate) { 9700 return; 9701 } 9702 mDidUpdate = true; 9703 } 9704 9705 mAppOpsService.systemReady(); 9706 mUsageStatsService.systemReady(); 9707 mSystemReady = true; 9708 } 9709 9710 ArrayList<ProcessRecord> procsToKill = null; 9711 synchronized(mPidsSelfLocked) { 9712 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9713 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9714 if (!isAllowedWhileBooting(proc.info)){ 9715 if (procsToKill == null) { 9716 procsToKill = new ArrayList<ProcessRecord>(); 9717 } 9718 procsToKill.add(proc); 9719 } 9720 } 9721 } 9722 9723 synchronized(this) { 9724 if (procsToKill != null) { 9725 for (int i=procsToKill.size()-1; i>=0; i--) { 9726 ProcessRecord proc = procsToKill.get(i); 9727 Slog.i(TAG, "Removing system update proc: " + proc); 9728 removeProcessLocked(proc, true, false, "system update done"); 9729 } 9730 } 9731 9732 // Now that we have cleaned up any update processes, we 9733 // are ready to start launching real processes and know that 9734 // we won't trample on them any more. 9735 mProcessesReady = true; 9736 } 9737 9738 Slog.i(TAG, "System now ready"); 9739 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9740 SystemClock.uptimeMillis()); 9741 9742 synchronized(this) { 9743 // Make sure we have no pre-ready processes sitting around. 9744 9745 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9746 ResolveInfo ri = mContext.getPackageManager() 9747 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9748 STOCK_PM_FLAGS); 9749 CharSequence errorMsg = null; 9750 if (ri != null) { 9751 ActivityInfo ai = ri.activityInfo; 9752 ApplicationInfo app = ai.applicationInfo; 9753 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9754 mTopAction = Intent.ACTION_FACTORY_TEST; 9755 mTopData = null; 9756 mTopComponent = new ComponentName(app.packageName, 9757 ai.name); 9758 } else { 9759 errorMsg = mContext.getResources().getText( 9760 com.android.internal.R.string.factorytest_not_system); 9761 } 9762 } else { 9763 errorMsg = mContext.getResources().getText( 9764 com.android.internal.R.string.factorytest_no_action); 9765 } 9766 if (errorMsg != null) { 9767 mTopAction = null; 9768 mTopData = null; 9769 mTopComponent = null; 9770 Message msg = Message.obtain(); 9771 msg.what = SHOW_FACTORY_ERROR_MSG; 9772 msg.getData().putCharSequence("msg", errorMsg); 9773 mHandler.sendMessage(msg); 9774 } 9775 } 9776 } 9777 9778 retrieveSettings(); 9779 9780 synchronized (this) { 9781 readGrantedUriPermissionsLocked(); 9782 } 9783 9784 if (goingCallback != null) goingCallback.run(); 9785 9786 mSystemServiceManager.startUser(mCurrentUserId); 9787 9788 synchronized (this) { 9789 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9790 try { 9791 List apps = AppGlobals.getPackageManager(). 9792 getPersistentApplications(STOCK_PM_FLAGS); 9793 if (apps != null) { 9794 int N = apps.size(); 9795 int i; 9796 for (i=0; i<N; i++) { 9797 ApplicationInfo info 9798 = (ApplicationInfo)apps.get(i); 9799 if (info != null && 9800 !info.packageName.equals("android")) { 9801 addAppLocked(info, false); 9802 } 9803 } 9804 } 9805 } catch (RemoteException ex) { 9806 // pm is in same process, this will never happen. 9807 } 9808 } 9809 9810 // Start up initial activity. 9811 mBooting = true; 9812 9813 try { 9814 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9815 Message msg = Message.obtain(); 9816 msg.what = SHOW_UID_ERROR_MSG; 9817 mHandler.sendMessage(msg); 9818 } 9819 } catch (RemoteException e) { 9820 } 9821 9822 long ident = Binder.clearCallingIdentity(); 9823 try { 9824 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9825 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9826 | Intent.FLAG_RECEIVER_FOREGROUND); 9827 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9828 broadcastIntentLocked(null, null, intent, 9829 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9830 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9831 intent = new Intent(Intent.ACTION_USER_STARTING); 9832 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9833 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9834 broadcastIntentLocked(null, null, intent, 9835 null, new IIntentReceiver.Stub() { 9836 @Override 9837 public void performReceive(Intent intent, int resultCode, String data, 9838 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9839 throws RemoteException { 9840 } 9841 }, 0, null, null, 9842 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9843 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9844 } catch (Throwable t) { 9845 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 9846 } finally { 9847 Binder.restoreCallingIdentity(ident); 9848 } 9849 mStackSupervisor.resumeTopActivitiesLocked(); 9850 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9851 } 9852 } 9853 9854 private boolean makeAppCrashingLocked(ProcessRecord app, 9855 String shortMsg, String longMsg, String stackTrace) { 9856 app.crashing = true; 9857 app.crashingReport = generateProcessError(app, 9858 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9859 startAppProblemLocked(app); 9860 app.stopFreezingAllLocked(); 9861 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9862 } 9863 9864 private void makeAppNotRespondingLocked(ProcessRecord app, 9865 String activity, String shortMsg, String longMsg) { 9866 app.notResponding = true; 9867 app.notRespondingReport = generateProcessError(app, 9868 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9869 activity, shortMsg, longMsg, null); 9870 startAppProblemLocked(app); 9871 app.stopFreezingAllLocked(); 9872 } 9873 9874 /** 9875 * Generate a process error record, suitable for attachment to a ProcessRecord. 9876 * 9877 * @param app The ProcessRecord in which the error occurred. 9878 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9879 * ActivityManager.AppErrorStateInfo 9880 * @param activity The activity associated with the crash, if known. 9881 * @param shortMsg Short message describing the crash. 9882 * @param longMsg Long message describing the crash. 9883 * @param stackTrace Full crash stack trace, may be null. 9884 * 9885 * @return Returns a fully-formed AppErrorStateInfo record. 9886 */ 9887 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9888 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9889 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9890 9891 report.condition = condition; 9892 report.processName = app.processName; 9893 report.pid = app.pid; 9894 report.uid = app.info.uid; 9895 report.tag = activity; 9896 report.shortMsg = shortMsg; 9897 report.longMsg = longMsg; 9898 report.stackTrace = stackTrace; 9899 9900 return report; 9901 } 9902 9903 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9904 synchronized (this) { 9905 app.crashing = false; 9906 app.crashingReport = null; 9907 app.notResponding = false; 9908 app.notRespondingReport = null; 9909 if (app.anrDialog == fromDialog) { 9910 app.anrDialog = null; 9911 } 9912 if (app.waitDialog == fromDialog) { 9913 app.waitDialog = null; 9914 } 9915 if (app.pid > 0 && app.pid != MY_PID) { 9916 handleAppCrashLocked(app, null, null, null); 9917 killUnneededProcessLocked(app, "user request after error"); 9918 } 9919 } 9920 } 9921 9922 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9923 String stackTrace) { 9924 long now = SystemClock.uptimeMillis(); 9925 9926 Long crashTime; 9927 if (!app.isolated) { 9928 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9929 } else { 9930 crashTime = null; 9931 } 9932 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9933 // This process loses! 9934 Slog.w(TAG, "Process " + app.info.processName 9935 + " has crashed too many times: killing!"); 9936 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9937 app.userId, app.info.processName, app.uid); 9938 mStackSupervisor.handleAppCrashLocked(app); 9939 if (!app.persistent) { 9940 // We don't want to start this process again until the user 9941 // explicitly does so... but for persistent process, we really 9942 // need to keep it running. If a persistent process is actually 9943 // repeatedly crashing, then badness for everyone. 9944 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9945 app.info.processName); 9946 if (!app.isolated) { 9947 // XXX We don't have a way to mark isolated processes 9948 // as bad, since they don't have a peristent identity. 9949 mBadProcesses.put(app.info.processName, app.uid, 9950 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9951 mProcessCrashTimes.remove(app.info.processName, app.uid); 9952 } 9953 app.bad = true; 9954 app.removed = true; 9955 // Don't let services in this process be restarted and potentially 9956 // annoy the user repeatedly. Unless it is persistent, since those 9957 // processes run critical code. 9958 removeProcessLocked(app, false, false, "crash"); 9959 mStackSupervisor.resumeTopActivitiesLocked(); 9960 return false; 9961 } 9962 mStackSupervisor.resumeTopActivitiesLocked(); 9963 } else { 9964 mStackSupervisor.finishTopRunningActivityLocked(app); 9965 } 9966 9967 // Bump up the crash count of any services currently running in the proc. 9968 for (int i=app.services.size()-1; i>=0; i--) { 9969 // Any services running in the application need to be placed 9970 // back in the pending list. 9971 ServiceRecord sr = app.services.valueAt(i); 9972 sr.crashCount++; 9973 } 9974 9975 // If the crashing process is what we consider to be the "home process" and it has been 9976 // replaced by a third-party app, clear the package preferred activities from packages 9977 // with a home activity running in the process to prevent a repeatedly crashing app 9978 // from blocking the user to manually clear the list. 9979 final ArrayList<ActivityRecord> activities = app.activities; 9980 if (app == mHomeProcess && activities.size() > 0 9981 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9982 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9983 final ActivityRecord r = activities.get(activityNdx); 9984 if (r.isHomeActivity()) { 9985 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9986 try { 9987 ActivityThread.getPackageManager() 9988 .clearPackagePreferredActivities(r.packageName); 9989 } catch (RemoteException c) { 9990 // pm is in same process, this will never happen. 9991 } 9992 } 9993 } 9994 } 9995 9996 if (!app.isolated) { 9997 // XXX Can't keep track of crash times for isolated processes, 9998 // because they don't have a perisistent identity. 9999 mProcessCrashTimes.put(app.info.processName, app.uid, now); 10000 } 10001 10002 return true; 10003 } 10004 10005 void startAppProblemLocked(ProcessRecord app) { 10006 if (app.userId == mCurrentUserId) { 10007 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 10008 mContext, app.info.packageName, app.info.flags); 10009 } else { 10010 // If this app is not running under the current user, then we 10011 // can't give it a report button because that would require 10012 // launching the report UI under a different user. 10013 app.errorReportReceiver = null; 10014 } 10015 skipCurrentReceiverLocked(app); 10016 } 10017 10018 void skipCurrentReceiverLocked(ProcessRecord app) { 10019 for (BroadcastQueue queue : mBroadcastQueues) { 10020 queue.skipCurrentReceiverLocked(app); 10021 } 10022 } 10023 10024 /** 10025 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 10026 * The application process will exit immediately after this call returns. 10027 * @param app object of the crashing app, null for the system server 10028 * @param crashInfo describing the exception 10029 */ 10030 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 10031 ProcessRecord r = findAppProcess(app, "Crash"); 10032 final String processName = app == null ? "system_server" 10033 : (r == null ? "unknown" : r.processName); 10034 10035 handleApplicationCrashInner("crash", r, processName, crashInfo); 10036 } 10037 10038 /* Native crash reporting uses this inner version because it needs to be somewhat 10039 * decoupled from the AM-managed cleanup lifecycle 10040 */ 10041 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 10042 ApplicationErrorReport.CrashInfo crashInfo) { 10043 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10044 UserHandle.getUserId(Binder.getCallingUid()), processName, 10045 r == null ? -1 : r.info.flags, 10046 crashInfo.exceptionClassName, 10047 crashInfo.exceptionMessage, 10048 crashInfo.throwFileName, 10049 crashInfo.throwLineNumber); 10050 10051 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10052 10053 crashApplication(r, crashInfo); 10054 } 10055 10056 public void handleApplicationStrictModeViolation( 10057 IBinder app, 10058 int violationMask, 10059 StrictMode.ViolationInfo info) { 10060 ProcessRecord r = findAppProcess(app, "StrictMode"); 10061 if (r == null) { 10062 return; 10063 } 10064 10065 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10066 Integer stackFingerprint = info.hashCode(); 10067 boolean logIt = true; 10068 synchronized (mAlreadyLoggedViolatedStacks) { 10069 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10070 logIt = false; 10071 // TODO: sub-sample into EventLog for these, with 10072 // the info.durationMillis? Then we'd get 10073 // the relative pain numbers, without logging all 10074 // the stack traces repeatedly. We'd want to do 10075 // likewise in the client code, which also does 10076 // dup suppression, before the Binder call. 10077 } else { 10078 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10079 mAlreadyLoggedViolatedStacks.clear(); 10080 } 10081 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10082 } 10083 } 10084 if (logIt) { 10085 logStrictModeViolationToDropBox(r, info); 10086 } 10087 } 10088 10089 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10090 AppErrorResult result = new AppErrorResult(); 10091 synchronized (this) { 10092 final long origId = Binder.clearCallingIdentity(); 10093 10094 Message msg = Message.obtain(); 10095 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10096 HashMap<String, Object> data = new HashMap<String, Object>(); 10097 data.put("result", result); 10098 data.put("app", r); 10099 data.put("violationMask", violationMask); 10100 data.put("info", info); 10101 msg.obj = data; 10102 mHandler.sendMessage(msg); 10103 10104 Binder.restoreCallingIdentity(origId); 10105 } 10106 int res = result.get(); 10107 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10108 } 10109 } 10110 10111 // Depending on the policy in effect, there could be a bunch of 10112 // these in quick succession so we try to batch these together to 10113 // minimize disk writes, number of dropbox entries, and maximize 10114 // compression, by having more fewer, larger records. 10115 private void logStrictModeViolationToDropBox( 10116 ProcessRecord process, 10117 StrictMode.ViolationInfo info) { 10118 if (info == null) { 10119 return; 10120 } 10121 final boolean isSystemApp = process == null || 10122 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10123 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10124 final String processName = process == null ? "unknown" : process.processName; 10125 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10126 final DropBoxManager dbox = (DropBoxManager) 10127 mContext.getSystemService(Context.DROPBOX_SERVICE); 10128 10129 // Exit early if the dropbox isn't configured to accept this report type. 10130 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10131 10132 boolean bufferWasEmpty; 10133 boolean needsFlush; 10134 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10135 synchronized (sb) { 10136 bufferWasEmpty = sb.length() == 0; 10137 appendDropBoxProcessHeaders(process, processName, sb); 10138 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10139 sb.append("System-App: ").append(isSystemApp).append("\n"); 10140 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10141 if (info.violationNumThisLoop != 0) { 10142 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10143 } 10144 if (info.numAnimationsRunning != 0) { 10145 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10146 } 10147 if (info.broadcastIntentAction != null) { 10148 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10149 } 10150 if (info.durationMillis != -1) { 10151 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10152 } 10153 if (info.numInstances != -1) { 10154 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10155 } 10156 if (info.tags != null) { 10157 for (String tag : info.tags) { 10158 sb.append("Span-Tag: ").append(tag).append("\n"); 10159 } 10160 } 10161 sb.append("\n"); 10162 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10163 sb.append(info.crashInfo.stackTrace); 10164 } 10165 sb.append("\n"); 10166 10167 // Only buffer up to ~64k. Various logging bits truncate 10168 // things at 128k. 10169 needsFlush = (sb.length() > 64 * 1024); 10170 } 10171 10172 // Flush immediately if the buffer's grown too large, or this 10173 // is a non-system app. Non-system apps are isolated with a 10174 // different tag & policy and not batched. 10175 // 10176 // Batching is useful during internal testing with 10177 // StrictMode settings turned up high. Without batching, 10178 // thousands of separate files could be created on boot. 10179 if (!isSystemApp || needsFlush) { 10180 new Thread("Error dump: " + dropboxTag) { 10181 @Override 10182 public void run() { 10183 String report; 10184 synchronized (sb) { 10185 report = sb.toString(); 10186 sb.delete(0, sb.length()); 10187 sb.trimToSize(); 10188 } 10189 if (report.length() != 0) { 10190 dbox.addText(dropboxTag, report); 10191 } 10192 } 10193 }.start(); 10194 return; 10195 } 10196 10197 // System app batching: 10198 if (!bufferWasEmpty) { 10199 // An existing dropbox-writing thread is outstanding, so 10200 // we don't need to start it up. The existing thread will 10201 // catch the buffer appends we just did. 10202 return; 10203 } 10204 10205 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10206 // (After this point, we shouldn't access AMS internal data structures.) 10207 new Thread("Error dump: " + dropboxTag) { 10208 @Override 10209 public void run() { 10210 // 5 second sleep to let stacks arrive and be batched together 10211 try { 10212 Thread.sleep(5000); // 5 seconds 10213 } catch (InterruptedException e) {} 10214 10215 String errorReport; 10216 synchronized (mStrictModeBuffer) { 10217 errorReport = mStrictModeBuffer.toString(); 10218 if (errorReport.length() == 0) { 10219 return; 10220 } 10221 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10222 mStrictModeBuffer.trimToSize(); 10223 } 10224 dbox.addText(dropboxTag, errorReport); 10225 } 10226 }.start(); 10227 } 10228 10229 /** 10230 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10231 * @param app object of the crashing app, null for the system server 10232 * @param tag reported by the caller 10233 * @param crashInfo describing the context of the error 10234 * @return true if the process should exit immediately (WTF is fatal) 10235 */ 10236 public boolean handleApplicationWtf(IBinder app, String tag, 10237 ApplicationErrorReport.CrashInfo crashInfo) { 10238 ProcessRecord r = findAppProcess(app, "WTF"); 10239 final String processName = app == null ? "system_server" 10240 : (r == null ? "unknown" : r.processName); 10241 10242 EventLog.writeEvent(EventLogTags.AM_WTF, 10243 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10244 processName, 10245 r == null ? -1 : r.info.flags, 10246 tag, crashInfo.exceptionMessage); 10247 10248 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10249 10250 if (r != null && r.pid != Process.myPid() && 10251 Settings.Global.getInt(mContext.getContentResolver(), 10252 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10253 crashApplication(r, crashInfo); 10254 return true; 10255 } else { 10256 return false; 10257 } 10258 } 10259 10260 /** 10261 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10262 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10263 */ 10264 private ProcessRecord findAppProcess(IBinder app, String reason) { 10265 if (app == null) { 10266 return null; 10267 } 10268 10269 synchronized (this) { 10270 final int NP = mProcessNames.getMap().size(); 10271 for (int ip=0; ip<NP; ip++) { 10272 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10273 final int NA = apps.size(); 10274 for (int ia=0; ia<NA; ia++) { 10275 ProcessRecord p = apps.valueAt(ia); 10276 if (p.thread != null && p.thread.asBinder() == app) { 10277 return p; 10278 } 10279 } 10280 } 10281 10282 Slog.w(TAG, "Can't find mystery application for " + reason 10283 + " from pid=" + Binder.getCallingPid() 10284 + " uid=" + Binder.getCallingUid() + ": " + app); 10285 return null; 10286 } 10287 } 10288 10289 /** 10290 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10291 * to append various headers to the dropbox log text. 10292 */ 10293 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10294 StringBuilder sb) { 10295 // Watchdog thread ends up invoking this function (with 10296 // a null ProcessRecord) to add the stack file to dropbox. 10297 // Do not acquire a lock on this (am) in such cases, as it 10298 // could cause a potential deadlock, if and when watchdog 10299 // is invoked due to unavailability of lock on am and it 10300 // would prevent watchdog from killing system_server. 10301 if (process == null) { 10302 sb.append("Process: ").append(processName).append("\n"); 10303 return; 10304 } 10305 // Note: ProcessRecord 'process' is guarded by the service 10306 // instance. (notably process.pkgList, which could otherwise change 10307 // concurrently during execution of this method) 10308 synchronized (this) { 10309 sb.append("Process: ").append(processName).append("\n"); 10310 int flags = process.info.flags; 10311 IPackageManager pm = AppGlobals.getPackageManager(); 10312 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10313 for (int ip=0; ip<process.pkgList.size(); ip++) { 10314 String pkg = process.pkgList.keyAt(ip); 10315 sb.append("Package: ").append(pkg); 10316 try { 10317 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10318 if (pi != null) { 10319 sb.append(" v").append(pi.versionCode); 10320 if (pi.versionName != null) { 10321 sb.append(" (").append(pi.versionName).append(")"); 10322 } 10323 } 10324 } catch (RemoteException e) { 10325 Slog.e(TAG, "Error getting package info: " + pkg, e); 10326 } 10327 sb.append("\n"); 10328 } 10329 } 10330 } 10331 10332 private static String processClass(ProcessRecord process) { 10333 if (process == null || process.pid == MY_PID) { 10334 return "system_server"; 10335 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10336 return "system_app"; 10337 } else { 10338 return "data_app"; 10339 } 10340 } 10341 10342 /** 10343 * Write a description of an error (crash, WTF, ANR) to the drop box. 10344 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10345 * @param process which caused the error, null means the system server 10346 * @param activity which triggered the error, null if unknown 10347 * @param parent activity related to the error, null if unknown 10348 * @param subject line related to the error, null if absent 10349 * @param report in long form describing the error, null if absent 10350 * @param logFile to include in the report, null if none 10351 * @param crashInfo giving an application stack trace, null if absent 10352 */ 10353 public void addErrorToDropBox(String eventType, 10354 ProcessRecord process, String processName, ActivityRecord activity, 10355 ActivityRecord parent, String subject, 10356 final String report, final File logFile, 10357 final ApplicationErrorReport.CrashInfo crashInfo) { 10358 // NOTE -- this must never acquire the ActivityManagerService lock, 10359 // otherwise the watchdog may be prevented from resetting the system. 10360 10361 final String dropboxTag = processClass(process) + "_" + eventType; 10362 final DropBoxManager dbox = (DropBoxManager) 10363 mContext.getSystemService(Context.DROPBOX_SERVICE); 10364 10365 // Exit early if the dropbox isn't configured to accept this report type. 10366 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10367 10368 final StringBuilder sb = new StringBuilder(1024); 10369 appendDropBoxProcessHeaders(process, processName, sb); 10370 if (activity != null) { 10371 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10372 } 10373 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10374 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10375 } 10376 if (parent != null && parent != activity) { 10377 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10378 } 10379 if (subject != null) { 10380 sb.append("Subject: ").append(subject).append("\n"); 10381 } 10382 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10383 if (Debug.isDebuggerConnected()) { 10384 sb.append("Debugger: Connected\n"); 10385 } 10386 sb.append("\n"); 10387 10388 // Do the rest in a worker thread to avoid blocking the caller on I/O 10389 // (After this point, we shouldn't access AMS internal data structures.) 10390 Thread worker = new Thread("Error dump: " + dropboxTag) { 10391 @Override 10392 public void run() { 10393 if (report != null) { 10394 sb.append(report); 10395 } 10396 if (logFile != null) { 10397 try { 10398 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10399 "\n\n[[TRUNCATED]]")); 10400 } catch (IOException e) { 10401 Slog.e(TAG, "Error reading " + logFile, e); 10402 } 10403 } 10404 if (crashInfo != null && crashInfo.stackTrace != null) { 10405 sb.append(crashInfo.stackTrace); 10406 } 10407 10408 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10409 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10410 if (lines > 0) { 10411 sb.append("\n"); 10412 10413 // Merge several logcat streams, and take the last N lines 10414 InputStreamReader input = null; 10415 try { 10416 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10417 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10418 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10419 10420 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10421 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10422 input = new InputStreamReader(logcat.getInputStream()); 10423 10424 int num; 10425 char[] buf = new char[8192]; 10426 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10427 } catch (IOException e) { 10428 Slog.e(TAG, "Error running logcat", e); 10429 } finally { 10430 if (input != null) try { input.close(); } catch (IOException e) {} 10431 } 10432 } 10433 10434 dbox.addText(dropboxTag, sb.toString()); 10435 } 10436 }; 10437 10438 if (process == null) { 10439 // If process is null, we are being called from some internal code 10440 // and may be about to die -- run this synchronously. 10441 worker.run(); 10442 } else { 10443 worker.start(); 10444 } 10445 } 10446 10447 /** 10448 * Bring up the "unexpected error" dialog box for a crashing app. 10449 * Deal with edge cases (intercepts from instrumented applications, 10450 * ActivityController, error intent receivers, that sort of thing). 10451 * @param r the application crashing 10452 * @param crashInfo describing the failure 10453 */ 10454 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10455 long timeMillis = System.currentTimeMillis(); 10456 String shortMsg = crashInfo.exceptionClassName; 10457 String longMsg = crashInfo.exceptionMessage; 10458 String stackTrace = crashInfo.stackTrace; 10459 if (shortMsg != null && longMsg != null) { 10460 longMsg = shortMsg + ": " + longMsg; 10461 } else if (shortMsg != null) { 10462 longMsg = shortMsg; 10463 } 10464 10465 AppErrorResult result = new AppErrorResult(); 10466 synchronized (this) { 10467 if (mController != null) { 10468 try { 10469 String name = r != null ? r.processName : null; 10470 int pid = r != null ? r.pid : Binder.getCallingPid(); 10471 if (!mController.appCrashed(name, pid, 10472 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10473 Slog.w(TAG, "Force-killing crashed app " + name 10474 + " at watcher's request"); 10475 Process.killProcess(pid); 10476 return; 10477 } 10478 } catch (RemoteException e) { 10479 mController = null; 10480 Watchdog.getInstance().setActivityController(null); 10481 } 10482 } 10483 10484 final long origId = Binder.clearCallingIdentity(); 10485 10486 // If this process is running instrumentation, finish it. 10487 if (r != null && r.instrumentationClass != null) { 10488 Slog.w(TAG, "Error in app " + r.processName 10489 + " running instrumentation " + r.instrumentationClass + ":"); 10490 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10491 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10492 Bundle info = new Bundle(); 10493 info.putString("shortMsg", shortMsg); 10494 info.putString("longMsg", longMsg); 10495 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10496 Binder.restoreCallingIdentity(origId); 10497 return; 10498 } 10499 10500 // If we can't identify the process or it's already exceeded its crash quota, 10501 // quit right away without showing a crash dialog. 10502 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10503 Binder.restoreCallingIdentity(origId); 10504 return; 10505 } 10506 10507 Message msg = Message.obtain(); 10508 msg.what = SHOW_ERROR_MSG; 10509 HashMap data = new HashMap(); 10510 data.put("result", result); 10511 data.put("app", r); 10512 msg.obj = data; 10513 mHandler.sendMessage(msg); 10514 10515 Binder.restoreCallingIdentity(origId); 10516 } 10517 10518 int res = result.get(); 10519 10520 Intent appErrorIntent = null; 10521 synchronized (this) { 10522 if (r != null && !r.isolated) { 10523 // XXX Can't keep track of crash time for isolated processes, 10524 // since they don't have a persistent identity. 10525 mProcessCrashTimes.put(r.info.processName, r.uid, 10526 SystemClock.uptimeMillis()); 10527 } 10528 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10529 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10530 } 10531 } 10532 10533 if (appErrorIntent != null) { 10534 try { 10535 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10536 } catch (ActivityNotFoundException e) { 10537 Slog.w(TAG, "bug report receiver dissappeared", e); 10538 } 10539 } 10540 } 10541 10542 Intent createAppErrorIntentLocked(ProcessRecord r, 10543 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10544 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10545 if (report == null) { 10546 return null; 10547 } 10548 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10549 result.setComponent(r.errorReportReceiver); 10550 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10551 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10552 return result; 10553 } 10554 10555 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10556 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10557 if (r.errorReportReceiver == null) { 10558 return null; 10559 } 10560 10561 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10562 return null; 10563 } 10564 10565 ApplicationErrorReport report = new ApplicationErrorReport(); 10566 report.packageName = r.info.packageName; 10567 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10568 report.processName = r.processName; 10569 report.time = timeMillis; 10570 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10571 10572 if (r.crashing || r.forceCrashReport) { 10573 report.type = ApplicationErrorReport.TYPE_CRASH; 10574 report.crashInfo = crashInfo; 10575 } else if (r.notResponding) { 10576 report.type = ApplicationErrorReport.TYPE_ANR; 10577 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10578 10579 report.anrInfo.activity = r.notRespondingReport.tag; 10580 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10581 report.anrInfo.info = r.notRespondingReport.longMsg; 10582 } 10583 10584 return report; 10585 } 10586 10587 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10588 enforceNotIsolatedCaller("getProcessesInErrorState"); 10589 // assume our apps are happy - lazy create the list 10590 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10591 10592 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 10593 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10594 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10595 10596 synchronized (this) { 10597 10598 // iterate across all processes 10599 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10600 ProcessRecord app = mLruProcesses.get(i); 10601 if (!allUsers && app.userId != userId) { 10602 continue; 10603 } 10604 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10605 // This one's in trouble, so we'll generate a report for it 10606 // crashes are higher priority (in case there's a crash *and* an anr) 10607 ActivityManager.ProcessErrorStateInfo report = null; 10608 if (app.crashing) { 10609 report = app.crashingReport; 10610 } else if (app.notResponding) { 10611 report = app.notRespondingReport; 10612 } 10613 10614 if (report != null) { 10615 if (errList == null) { 10616 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10617 } 10618 errList.add(report); 10619 } else { 10620 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10621 " crashing = " + app.crashing + 10622 " notResponding = " + app.notResponding); 10623 } 10624 } 10625 } 10626 } 10627 10628 return errList; 10629 } 10630 10631 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10632 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10633 if (currApp != null) { 10634 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10635 } 10636 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10637 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10638 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10639 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10640 if (currApp != null) { 10641 currApp.lru = 0; 10642 } 10643 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10644 } else if (adj >= ProcessList.SERVICE_ADJ) { 10645 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10646 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10647 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10648 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10649 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10650 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10651 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10652 } else { 10653 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10654 } 10655 } 10656 10657 private void fillInProcMemInfo(ProcessRecord app, 10658 ActivityManager.RunningAppProcessInfo outInfo) { 10659 outInfo.pid = app.pid; 10660 outInfo.uid = app.info.uid; 10661 if (mHeavyWeightProcess == app) { 10662 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10663 } 10664 if (app.persistent) { 10665 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10666 } 10667 if (app.activities.size() > 0) { 10668 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10669 } 10670 outInfo.lastTrimLevel = app.trimMemoryLevel; 10671 int adj = app.curAdj; 10672 outInfo.importance = oomAdjToImportance(adj, outInfo); 10673 outInfo.importanceReasonCode = app.adjTypeCode; 10674 outInfo.processState = app.curProcState; 10675 } 10676 10677 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10678 enforceNotIsolatedCaller("getRunningAppProcesses"); 10679 // Lazy instantiation of list 10680 List<ActivityManager.RunningAppProcessInfo> runList = null; 10681 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 10682 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10683 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10684 synchronized (this) { 10685 // Iterate across all processes 10686 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10687 ProcessRecord app = mLruProcesses.get(i); 10688 if (!allUsers && app.userId != userId) { 10689 continue; 10690 } 10691 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10692 // Generate process state info for running application 10693 ActivityManager.RunningAppProcessInfo currApp = 10694 new ActivityManager.RunningAppProcessInfo(app.processName, 10695 app.pid, app.getPackageList()); 10696 fillInProcMemInfo(app, currApp); 10697 if (app.adjSource instanceof ProcessRecord) { 10698 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10699 currApp.importanceReasonImportance = oomAdjToImportance( 10700 app.adjSourceOom, null); 10701 } else if (app.adjSource instanceof ActivityRecord) { 10702 ActivityRecord r = (ActivityRecord)app.adjSource; 10703 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10704 } 10705 if (app.adjTarget instanceof ComponentName) { 10706 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10707 } 10708 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10709 // + " lru=" + currApp.lru); 10710 if (runList == null) { 10711 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10712 } 10713 runList.add(currApp); 10714 } 10715 } 10716 } 10717 return runList; 10718 } 10719 10720 public List<ApplicationInfo> getRunningExternalApplications() { 10721 enforceNotIsolatedCaller("getRunningExternalApplications"); 10722 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10723 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10724 if (runningApps != null && runningApps.size() > 0) { 10725 Set<String> extList = new HashSet<String>(); 10726 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10727 if (app.pkgList != null) { 10728 for (String pkg : app.pkgList) { 10729 extList.add(pkg); 10730 } 10731 } 10732 } 10733 IPackageManager pm = AppGlobals.getPackageManager(); 10734 for (String pkg : extList) { 10735 try { 10736 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10737 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10738 retList.add(info); 10739 } 10740 } catch (RemoteException e) { 10741 } 10742 } 10743 } 10744 return retList; 10745 } 10746 10747 @Override 10748 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10749 enforceNotIsolatedCaller("getMyMemoryState"); 10750 synchronized (this) { 10751 ProcessRecord proc; 10752 synchronized (mPidsSelfLocked) { 10753 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10754 } 10755 fillInProcMemInfo(proc, outInfo); 10756 } 10757 } 10758 10759 @Override 10760 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10761 if (checkCallingPermission(android.Manifest.permission.DUMP) 10762 != PackageManager.PERMISSION_GRANTED) { 10763 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10764 + Binder.getCallingPid() 10765 + ", uid=" + Binder.getCallingUid() 10766 + " without permission " 10767 + android.Manifest.permission.DUMP); 10768 return; 10769 } 10770 10771 boolean dumpAll = false; 10772 boolean dumpClient = false; 10773 String dumpPackage = null; 10774 10775 int opti = 0; 10776 while (opti < args.length) { 10777 String opt = args[opti]; 10778 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10779 break; 10780 } 10781 opti++; 10782 if ("-a".equals(opt)) { 10783 dumpAll = true; 10784 } else if ("-c".equals(opt)) { 10785 dumpClient = true; 10786 } else if ("-h".equals(opt)) { 10787 pw.println("Activity manager dump options:"); 10788 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10789 pw.println(" cmd may be one of:"); 10790 pw.println(" a[ctivities]: activity stack state"); 10791 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10792 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10793 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10794 pw.println(" o[om]: out of memory management"); 10795 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10796 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10797 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10798 pw.println(" service [COMP_SPEC]: service client-side state"); 10799 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10800 pw.println(" all: dump all activities"); 10801 pw.println(" top: dump the top activity"); 10802 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10803 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10804 pw.println(" a partial substring in a component name, a"); 10805 pw.println(" hex object identifier."); 10806 pw.println(" -a: include all available server state."); 10807 pw.println(" -c: include client state."); 10808 return; 10809 } else { 10810 pw.println("Unknown argument: " + opt + "; use -h for help"); 10811 } 10812 } 10813 10814 long origId = Binder.clearCallingIdentity(); 10815 boolean more = false; 10816 // Is the caller requesting to dump a particular piece of data? 10817 if (opti < args.length) { 10818 String cmd = args[opti]; 10819 opti++; 10820 if ("activities".equals(cmd) || "a".equals(cmd)) { 10821 synchronized (this) { 10822 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10823 } 10824 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10825 String[] newArgs; 10826 String name; 10827 if (opti >= args.length) { 10828 name = null; 10829 newArgs = EMPTY_STRING_ARRAY; 10830 } else { 10831 name = args[opti]; 10832 opti++; 10833 newArgs = new String[args.length - opti]; 10834 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10835 args.length - opti); 10836 } 10837 synchronized (this) { 10838 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10839 } 10840 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10841 String[] newArgs; 10842 String name; 10843 if (opti >= args.length) { 10844 name = null; 10845 newArgs = EMPTY_STRING_ARRAY; 10846 } else { 10847 name = args[opti]; 10848 opti++; 10849 newArgs = new String[args.length - opti]; 10850 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10851 args.length - opti); 10852 } 10853 synchronized (this) { 10854 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10855 } 10856 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10857 String[] newArgs; 10858 String name; 10859 if (opti >= args.length) { 10860 name = null; 10861 newArgs = EMPTY_STRING_ARRAY; 10862 } else { 10863 name = args[opti]; 10864 opti++; 10865 newArgs = new String[args.length - opti]; 10866 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10867 args.length - opti); 10868 } 10869 synchronized (this) { 10870 dumpProcessesLocked(fd, pw, args, opti, true, name); 10871 } 10872 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10873 synchronized (this) { 10874 dumpOomLocked(fd, pw, args, opti, true); 10875 } 10876 } else if ("provider".equals(cmd)) { 10877 String[] newArgs; 10878 String name; 10879 if (opti >= args.length) { 10880 name = null; 10881 newArgs = EMPTY_STRING_ARRAY; 10882 } else { 10883 name = args[opti]; 10884 opti++; 10885 newArgs = new String[args.length - opti]; 10886 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10887 } 10888 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10889 pw.println("No providers match: " + name); 10890 pw.println("Use -h for help."); 10891 } 10892 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10893 synchronized (this) { 10894 dumpProvidersLocked(fd, pw, args, opti, true, null); 10895 } 10896 } else if ("service".equals(cmd)) { 10897 String[] newArgs; 10898 String name; 10899 if (opti >= args.length) { 10900 name = null; 10901 newArgs = EMPTY_STRING_ARRAY; 10902 } else { 10903 name = args[opti]; 10904 opti++; 10905 newArgs = new String[args.length - opti]; 10906 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10907 args.length - opti); 10908 } 10909 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10910 pw.println("No services match: " + name); 10911 pw.println("Use -h for help."); 10912 } 10913 } else if ("package".equals(cmd)) { 10914 String[] newArgs; 10915 if (opti >= args.length) { 10916 pw.println("package: no package name specified"); 10917 pw.println("Use -h for help."); 10918 } else { 10919 dumpPackage = args[opti]; 10920 opti++; 10921 newArgs = new String[args.length - opti]; 10922 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10923 args.length - opti); 10924 args = newArgs; 10925 opti = 0; 10926 more = true; 10927 } 10928 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10929 synchronized (this) { 10930 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10931 } 10932 } else { 10933 // Dumping a single activity? 10934 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10935 pw.println("Bad activity command, or no activities match: " + cmd); 10936 pw.println("Use -h for help."); 10937 } 10938 } 10939 if (!more) { 10940 Binder.restoreCallingIdentity(origId); 10941 return; 10942 } 10943 } 10944 10945 // No piece of data specified, dump everything. 10946 synchronized (this) { 10947 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10948 pw.println(); 10949 if (dumpAll) { 10950 pw.println("-------------------------------------------------------------------------------"); 10951 } 10952 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10953 pw.println(); 10954 if (dumpAll) { 10955 pw.println("-------------------------------------------------------------------------------"); 10956 } 10957 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10958 pw.println(); 10959 if (dumpAll) { 10960 pw.println("-------------------------------------------------------------------------------"); 10961 } 10962 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10963 pw.println(); 10964 if (dumpAll) { 10965 pw.println("-------------------------------------------------------------------------------"); 10966 } 10967 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10968 pw.println(); 10969 if (dumpAll) { 10970 pw.println("-------------------------------------------------------------------------------"); 10971 } 10972 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10973 } 10974 Binder.restoreCallingIdentity(origId); 10975 } 10976 10977 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10978 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10979 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10980 10981 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10982 dumpPackage); 10983 boolean needSep = printedAnything; 10984 10985 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10986 dumpPackage, needSep, " mFocusedActivity: "); 10987 if (printed) { 10988 printedAnything = true; 10989 needSep = false; 10990 } 10991 10992 if (dumpPackage == null) { 10993 if (needSep) { 10994 pw.println(); 10995 } 10996 needSep = true; 10997 printedAnything = true; 10998 mStackSupervisor.dump(pw, " "); 10999 } 11000 11001 if (mRecentTasks.size() > 0) { 11002 boolean printedHeader = false; 11003 11004 final int N = mRecentTasks.size(); 11005 for (int i=0; i<N; i++) { 11006 TaskRecord tr = mRecentTasks.get(i); 11007 if (dumpPackage != null) { 11008 if (tr.realActivity == null || 11009 !dumpPackage.equals(tr.realActivity)) { 11010 continue; 11011 } 11012 } 11013 if (!printedHeader) { 11014 if (needSep) { 11015 pw.println(); 11016 } 11017 pw.println(" Recent tasks:"); 11018 printedHeader = true; 11019 printedAnything = true; 11020 } 11021 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 11022 pw.println(tr); 11023 if (dumpAll) { 11024 mRecentTasks.get(i).dump(pw, " "); 11025 } 11026 } 11027 } 11028 11029 if (!printedAnything) { 11030 pw.println(" (nothing)"); 11031 } 11032 } 11033 11034 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11035 int opti, boolean dumpAll, String dumpPackage) { 11036 boolean needSep = false; 11037 boolean printedAnything = false; 11038 int numPers = 0; 11039 11040 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11041 11042 if (dumpAll) { 11043 final int NP = mProcessNames.getMap().size(); 11044 for (int ip=0; ip<NP; ip++) { 11045 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11046 final int NA = procs.size(); 11047 for (int ia=0; ia<NA; ia++) { 11048 ProcessRecord r = procs.valueAt(ia); 11049 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11050 continue; 11051 } 11052 if (!needSep) { 11053 pw.println(" All known processes:"); 11054 needSep = true; 11055 printedAnything = true; 11056 } 11057 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11058 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11059 pw.print(" "); pw.println(r); 11060 r.dump(pw, " "); 11061 if (r.persistent) { 11062 numPers++; 11063 } 11064 } 11065 } 11066 } 11067 11068 if (mIsolatedProcesses.size() > 0) { 11069 boolean printed = false; 11070 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11071 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11072 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11073 continue; 11074 } 11075 if (!printed) { 11076 if (needSep) { 11077 pw.println(); 11078 } 11079 pw.println(" Isolated process list (sorted by uid):"); 11080 printedAnything = true; 11081 printed = true; 11082 needSep = true; 11083 } 11084 pw.println(String.format("%sIsolated #%2d: %s", 11085 " ", i, r.toString())); 11086 } 11087 } 11088 11089 if (mLruProcesses.size() > 0) { 11090 if (needSep) { 11091 pw.println(); 11092 } 11093 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11094 pw.print(" total, non-act at "); 11095 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11096 pw.print(", non-svc at "); 11097 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11098 pw.println("):"); 11099 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11100 needSep = true; 11101 printedAnything = true; 11102 } 11103 11104 if (dumpAll || dumpPackage != null) { 11105 synchronized (mPidsSelfLocked) { 11106 boolean printed = false; 11107 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11108 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11109 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11110 continue; 11111 } 11112 if (!printed) { 11113 if (needSep) pw.println(); 11114 needSep = true; 11115 pw.println(" PID mappings:"); 11116 printed = true; 11117 printedAnything = true; 11118 } 11119 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11120 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11121 } 11122 } 11123 } 11124 11125 if (mForegroundProcesses.size() > 0) { 11126 synchronized (mPidsSelfLocked) { 11127 boolean printed = false; 11128 for (int i=0; i<mForegroundProcesses.size(); i++) { 11129 ProcessRecord r = mPidsSelfLocked.get( 11130 mForegroundProcesses.valueAt(i).pid); 11131 if (dumpPackage != null && (r == null 11132 || !r.pkgList.containsKey(dumpPackage))) { 11133 continue; 11134 } 11135 if (!printed) { 11136 if (needSep) pw.println(); 11137 needSep = true; 11138 pw.println(" Foreground Processes:"); 11139 printed = true; 11140 printedAnything = true; 11141 } 11142 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11143 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11144 } 11145 } 11146 } 11147 11148 if (mPersistentStartingProcesses.size() > 0) { 11149 if (needSep) pw.println(); 11150 needSep = true; 11151 printedAnything = true; 11152 pw.println(" Persisent processes that are starting:"); 11153 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11154 "Starting Norm", "Restarting PERS", dumpPackage); 11155 } 11156 11157 if (mRemovedProcesses.size() > 0) { 11158 if (needSep) pw.println(); 11159 needSep = true; 11160 printedAnything = true; 11161 pw.println(" Processes that are being removed:"); 11162 dumpProcessList(pw, this, mRemovedProcesses, " ", 11163 "Removed Norm", "Removed PERS", dumpPackage); 11164 } 11165 11166 if (mProcessesOnHold.size() > 0) { 11167 if (needSep) pw.println(); 11168 needSep = true; 11169 printedAnything = true; 11170 pw.println(" Processes that are on old until the system is ready:"); 11171 dumpProcessList(pw, this, mProcessesOnHold, " ", 11172 "OnHold Norm", "OnHold PERS", dumpPackage); 11173 } 11174 11175 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11176 11177 if (mProcessCrashTimes.getMap().size() > 0) { 11178 boolean printed = false; 11179 long now = SystemClock.uptimeMillis(); 11180 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11181 final int NP = pmap.size(); 11182 for (int ip=0; ip<NP; ip++) { 11183 String pname = pmap.keyAt(ip); 11184 SparseArray<Long> uids = pmap.valueAt(ip); 11185 final int N = uids.size(); 11186 for (int i=0; i<N; i++) { 11187 int puid = uids.keyAt(i); 11188 ProcessRecord r = mProcessNames.get(pname, puid); 11189 if (dumpPackage != null && (r == null 11190 || !r.pkgList.containsKey(dumpPackage))) { 11191 continue; 11192 } 11193 if (!printed) { 11194 if (needSep) pw.println(); 11195 needSep = true; 11196 pw.println(" Time since processes crashed:"); 11197 printed = true; 11198 printedAnything = true; 11199 } 11200 pw.print(" Process "); pw.print(pname); 11201 pw.print(" uid "); pw.print(puid); 11202 pw.print(": last crashed "); 11203 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11204 pw.println(" ago"); 11205 } 11206 } 11207 } 11208 11209 if (mBadProcesses.getMap().size() > 0) { 11210 boolean printed = false; 11211 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11212 final int NP = pmap.size(); 11213 for (int ip=0; ip<NP; ip++) { 11214 String pname = pmap.keyAt(ip); 11215 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11216 final int N = uids.size(); 11217 for (int i=0; i<N; i++) { 11218 int puid = uids.keyAt(i); 11219 ProcessRecord r = mProcessNames.get(pname, puid); 11220 if (dumpPackage != null && (r == null 11221 || !r.pkgList.containsKey(dumpPackage))) { 11222 continue; 11223 } 11224 if (!printed) { 11225 if (needSep) pw.println(); 11226 needSep = true; 11227 pw.println(" Bad processes:"); 11228 printedAnything = true; 11229 } 11230 BadProcessInfo info = uids.valueAt(i); 11231 pw.print(" Bad process "); pw.print(pname); 11232 pw.print(" uid "); pw.print(puid); 11233 pw.print(": crashed at time "); pw.println(info.time); 11234 if (info.shortMsg != null) { 11235 pw.print(" Short msg: "); pw.println(info.shortMsg); 11236 } 11237 if (info.longMsg != null) { 11238 pw.print(" Long msg: "); pw.println(info.longMsg); 11239 } 11240 if (info.stack != null) { 11241 pw.println(" Stack:"); 11242 int lastPos = 0; 11243 for (int pos=0; pos<info.stack.length(); pos++) { 11244 if (info.stack.charAt(pos) == '\n') { 11245 pw.print(" "); 11246 pw.write(info.stack, lastPos, pos-lastPos); 11247 pw.println(); 11248 lastPos = pos+1; 11249 } 11250 } 11251 if (lastPos < info.stack.length()) { 11252 pw.print(" "); 11253 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11254 pw.println(); 11255 } 11256 } 11257 } 11258 } 11259 } 11260 11261 if (dumpPackage == null) { 11262 pw.println(); 11263 needSep = false; 11264 pw.println(" mStartedUsers:"); 11265 for (int i=0; i<mStartedUsers.size(); i++) { 11266 UserStartedState uss = mStartedUsers.valueAt(i); 11267 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11268 pw.print(": "); uss.dump("", pw); 11269 } 11270 pw.print(" mStartedUserArray: ["); 11271 for (int i=0; i<mStartedUserArray.length; i++) { 11272 if (i > 0) pw.print(", "); 11273 pw.print(mStartedUserArray[i]); 11274 } 11275 pw.println("]"); 11276 pw.print(" mUserLru: ["); 11277 for (int i=0; i<mUserLru.size(); i++) { 11278 if (i > 0) pw.print(", "); 11279 pw.print(mUserLru.get(i)); 11280 } 11281 pw.println("]"); 11282 if (dumpAll) { 11283 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11284 } 11285 } 11286 if (mHomeProcess != null && (dumpPackage == null 11287 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11288 if (needSep) { 11289 pw.println(); 11290 needSep = false; 11291 } 11292 pw.println(" mHomeProcess: " + mHomeProcess); 11293 } 11294 if (mPreviousProcess != null && (dumpPackage == null 11295 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11296 if (needSep) { 11297 pw.println(); 11298 needSep = false; 11299 } 11300 pw.println(" mPreviousProcess: " + mPreviousProcess); 11301 } 11302 if (dumpAll) { 11303 StringBuilder sb = new StringBuilder(128); 11304 sb.append(" mPreviousProcessVisibleTime: "); 11305 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11306 pw.println(sb); 11307 } 11308 if (mHeavyWeightProcess != null && (dumpPackage == null 11309 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11310 if (needSep) { 11311 pw.println(); 11312 needSep = false; 11313 } 11314 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11315 } 11316 if (dumpPackage == null) { 11317 pw.println(" mConfiguration: " + mConfiguration); 11318 } 11319 if (dumpAll) { 11320 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11321 if (mCompatModePackages.getPackages().size() > 0) { 11322 boolean printed = false; 11323 for (Map.Entry<String, Integer> entry 11324 : mCompatModePackages.getPackages().entrySet()) { 11325 String pkg = entry.getKey(); 11326 int mode = entry.getValue(); 11327 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11328 continue; 11329 } 11330 if (!printed) { 11331 pw.println(" mScreenCompatPackages:"); 11332 printed = true; 11333 } 11334 pw.print(" "); pw.print(pkg); pw.print(": "); 11335 pw.print(mode); pw.println(); 11336 } 11337 } 11338 } 11339 if (dumpPackage == null) { 11340 if (mSleeping || mWentToSleep || mLockScreenShown) { 11341 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11342 + " mLockScreenShown " + mLockScreenShown); 11343 } 11344 if (mShuttingDown || mRunningVoice) { 11345 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11346 } 11347 } 11348 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11349 || mOrigWaitForDebugger) { 11350 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11351 || dumpPackage.equals(mOrigDebugApp)) { 11352 if (needSep) { 11353 pw.println(); 11354 needSep = false; 11355 } 11356 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11357 + " mDebugTransient=" + mDebugTransient 11358 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11359 } 11360 } 11361 if (mOpenGlTraceApp != null) { 11362 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11363 if (needSep) { 11364 pw.println(); 11365 needSep = false; 11366 } 11367 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11368 } 11369 } 11370 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11371 || mProfileFd != null) { 11372 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11373 if (needSep) { 11374 pw.println(); 11375 needSep = false; 11376 } 11377 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11378 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11379 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11380 + mAutoStopProfiler); 11381 } 11382 } 11383 if (dumpPackage == null) { 11384 if (mAlwaysFinishActivities || mController != null) { 11385 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11386 + " mController=" + mController); 11387 } 11388 if (dumpAll) { 11389 pw.println(" Total persistent processes: " + numPers); 11390 pw.println(" mProcessesReady=" + mProcessesReady 11391 + " mSystemReady=" + mSystemReady); 11392 pw.println(" mBooting=" + mBooting 11393 + " mBooted=" + mBooted 11394 + " mFactoryTest=" + mFactoryTest); 11395 pw.print(" mLastPowerCheckRealtime="); 11396 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11397 pw.println(""); 11398 pw.print(" mLastPowerCheckUptime="); 11399 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11400 pw.println(""); 11401 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11402 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11403 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11404 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11405 + " (" + mLruProcesses.size() + " total)" 11406 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11407 + " mNumServiceProcs=" + mNumServiceProcs 11408 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11409 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11410 + " mLastMemoryLevel" + mLastMemoryLevel 11411 + " mLastNumProcesses" + mLastNumProcesses); 11412 long now = SystemClock.uptimeMillis(); 11413 pw.print(" mLastIdleTime="); 11414 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11415 pw.print(" mLowRamSinceLastIdle="); 11416 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11417 pw.println(); 11418 } 11419 } 11420 11421 if (!printedAnything) { 11422 pw.println(" (nothing)"); 11423 } 11424 } 11425 11426 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11427 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11428 if (mProcessesToGc.size() > 0) { 11429 boolean printed = false; 11430 long now = SystemClock.uptimeMillis(); 11431 for (int i=0; i<mProcessesToGc.size(); i++) { 11432 ProcessRecord proc = mProcessesToGc.get(i); 11433 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11434 continue; 11435 } 11436 if (!printed) { 11437 if (needSep) pw.println(); 11438 needSep = true; 11439 pw.println(" Processes that are waiting to GC:"); 11440 printed = true; 11441 } 11442 pw.print(" Process "); pw.println(proc); 11443 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11444 pw.print(", last gced="); 11445 pw.print(now-proc.lastRequestedGc); 11446 pw.print(" ms ago, last lowMem="); 11447 pw.print(now-proc.lastLowMemory); 11448 pw.println(" ms ago"); 11449 11450 } 11451 } 11452 return needSep; 11453 } 11454 11455 void printOomLevel(PrintWriter pw, String name, int adj) { 11456 pw.print(" "); 11457 if (adj >= 0) { 11458 pw.print(' '); 11459 if (adj < 10) pw.print(' '); 11460 } else { 11461 if (adj > -10) pw.print(' '); 11462 } 11463 pw.print(adj); 11464 pw.print(": "); 11465 pw.print(name); 11466 pw.print(" ("); 11467 pw.print(mProcessList.getMemLevel(adj)/1024); 11468 pw.println(" kB)"); 11469 } 11470 11471 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11472 int opti, boolean dumpAll) { 11473 boolean needSep = false; 11474 11475 if (mLruProcesses.size() > 0) { 11476 if (needSep) pw.println(); 11477 needSep = true; 11478 pw.println(" OOM levels:"); 11479 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11480 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11481 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11482 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11483 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11484 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11485 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11486 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11487 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11488 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11489 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11490 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11491 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11492 11493 if (needSep) pw.println(); 11494 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11495 pw.print(" total, non-act at "); 11496 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11497 pw.print(", non-svc at "); 11498 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11499 pw.println("):"); 11500 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11501 needSep = true; 11502 } 11503 11504 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11505 11506 pw.println(); 11507 pw.println(" mHomeProcess: " + mHomeProcess); 11508 pw.println(" mPreviousProcess: " + mPreviousProcess); 11509 if (mHeavyWeightProcess != null) { 11510 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11511 } 11512 11513 return true; 11514 } 11515 11516 /** 11517 * There are three ways to call this: 11518 * - no provider specified: dump all the providers 11519 * - a flattened component name that matched an existing provider was specified as the 11520 * first arg: dump that one provider 11521 * - the first arg isn't the flattened component name of an existing provider: 11522 * dump all providers whose component contains the first arg as a substring 11523 */ 11524 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11525 int opti, boolean dumpAll) { 11526 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11527 } 11528 11529 static class ItemMatcher { 11530 ArrayList<ComponentName> components; 11531 ArrayList<String> strings; 11532 ArrayList<Integer> objects; 11533 boolean all; 11534 11535 ItemMatcher() { 11536 all = true; 11537 } 11538 11539 void build(String name) { 11540 ComponentName componentName = ComponentName.unflattenFromString(name); 11541 if (componentName != null) { 11542 if (components == null) { 11543 components = new ArrayList<ComponentName>(); 11544 } 11545 components.add(componentName); 11546 all = false; 11547 } else { 11548 int objectId = 0; 11549 // Not a '/' separated full component name; maybe an object ID? 11550 try { 11551 objectId = Integer.parseInt(name, 16); 11552 if (objects == null) { 11553 objects = new ArrayList<Integer>(); 11554 } 11555 objects.add(objectId); 11556 all = false; 11557 } catch (RuntimeException e) { 11558 // Not an integer; just do string match. 11559 if (strings == null) { 11560 strings = new ArrayList<String>(); 11561 } 11562 strings.add(name); 11563 all = false; 11564 } 11565 } 11566 } 11567 11568 int build(String[] args, int opti) { 11569 for (; opti<args.length; opti++) { 11570 String name = args[opti]; 11571 if ("--".equals(name)) { 11572 return opti+1; 11573 } 11574 build(name); 11575 } 11576 return opti; 11577 } 11578 11579 boolean match(Object object, ComponentName comp) { 11580 if (all) { 11581 return true; 11582 } 11583 if (components != null) { 11584 for (int i=0; i<components.size(); i++) { 11585 if (components.get(i).equals(comp)) { 11586 return true; 11587 } 11588 } 11589 } 11590 if (objects != null) { 11591 for (int i=0; i<objects.size(); i++) { 11592 if (System.identityHashCode(object) == objects.get(i)) { 11593 return true; 11594 } 11595 } 11596 } 11597 if (strings != null) { 11598 String flat = comp.flattenToString(); 11599 for (int i=0; i<strings.size(); i++) { 11600 if (flat.contains(strings.get(i))) { 11601 return true; 11602 } 11603 } 11604 } 11605 return false; 11606 } 11607 } 11608 11609 /** 11610 * There are three things that cmd can be: 11611 * - a flattened component name that matches an existing activity 11612 * - the cmd arg isn't the flattened component name of an existing activity: 11613 * dump all activity whose component contains the cmd as a substring 11614 * - A hex number of the ActivityRecord object instance. 11615 */ 11616 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11617 int opti, boolean dumpAll) { 11618 ArrayList<ActivityRecord> activities; 11619 11620 synchronized (this) { 11621 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11622 } 11623 11624 if (activities.size() <= 0) { 11625 return false; 11626 } 11627 11628 String[] newArgs = new String[args.length - opti]; 11629 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11630 11631 TaskRecord lastTask = null; 11632 boolean needSep = false; 11633 for (int i=activities.size()-1; i>=0; i--) { 11634 ActivityRecord r = activities.get(i); 11635 if (needSep) { 11636 pw.println(); 11637 } 11638 needSep = true; 11639 synchronized (this) { 11640 if (lastTask != r.task) { 11641 lastTask = r.task; 11642 pw.print("TASK "); pw.print(lastTask.affinity); 11643 pw.print(" id="); pw.println(lastTask.taskId); 11644 if (dumpAll) { 11645 lastTask.dump(pw, " "); 11646 } 11647 } 11648 } 11649 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11650 } 11651 return true; 11652 } 11653 11654 /** 11655 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11656 * there is a thread associated with the activity. 11657 */ 11658 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11659 final ActivityRecord r, String[] args, boolean dumpAll) { 11660 String innerPrefix = prefix + " "; 11661 synchronized (this) { 11662 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11663 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11664 pw.print(" pid="); 11665 if (r.app != null) pw.println(r.app.pid); 11666 else pw.println("(not running)"); 11667 if (dumpAll) { 11668 r.dump(pw, innerPrefix); 11669 } 11670 } 11671 if (r.app != null && r.app.thread != null) { 11672 // flush anything that is already in the PrintWriter since the thread is going 11673 // to write to the file descriptor directly 11674 pw.flush(); 11675 try { 11676 TransferPipe tp = new TransferPipe(); 11677 try { 11678 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11679 r.appToken, innerPrefix, args); 11680 tp.go(fd); 11681 } finally { 11682 tp.kill(); 11683 } 11684 } catch (IOException e) { 11685 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11686 } catch (RemoteException e) { 11687 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11688 } 11689 } 11690 } 11691 11692 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11693 int opti, boolean dumpAll, String dumpPackage) { 11694 boolean needSep = false; 11695 boolean onlyHistory = false; 11696 boolean printedAnything = false; 11697 11698 if ("history".equals(dumpPackage)) { 11699 if (opti < args.length && "-s".equals(args[opti])) { 11700 dumpAll = false; 11701 } 11702 onlyHistory = true; 11703 dumpPackage = null; 11704 } 11705 11706 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11707 if (!onlyHistory && dumpAll) { 11708 if (mRegisteredReceivers.size() > 0) { 11709 boolean printed = false; 11710 Iterator it = mRegisteredReceivers.values().iterator(); 11711 while (it.hasNext()) { 11712 ReceiverList r = (ReceiverList)it.next(); 11713 if (dumpPackage != null && (r.app == null || 11714 !dumpPackage.equals(r.app.info.packageName))) { 11715 continue; 11716 } 11717 if (!printed) { 11718 pw.println(" Registered Receivers:"); 11719 needSep = true; 11720 printed = true; 11721 printedAnything = true; 11722 } 11723 pw.print(" * "); pw.println(r); 11724 r.dump(pw, " "); 11725 } 11726 } 11727 11728 if (mReceiverResolver.dump(pw, needSep ? 11729 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11730 " ", dumpPackage, false)) { 11731 needSep = true; 11732 printedAnything = true; 11733 } 11734 } 11735 11736 for (BroadcastQueue q : mBroadcastQueues) { 11737 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11738 printedAnything |= needSep; 11739 } 11740 11741 needSep = true; 11742 11743 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11744 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11745 if (needSep) { 11746 pw.println(); 11747 } 11748 needSep = true; 11749 printedAnything = true; 11750 pw.print(" Sticky broadcasts for user "); 11751 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11752 StringBuilder sb = new StringBuilder(128); 11753 for (Map.Entry<String, ArrayList<Intent>> ent 11754 : mStickyBroadcasts.valueAt(user).entrySet()) { 11755 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11756 if (dumpAll) { 11757 pw.println(":"); 11758 ArrayList<Intent> intents = ent.getValue(); 11759 final int N = intents.size(); 11760 for (int i=0; i<N; i++) { 11761 sb.setLength(0); 11762 sb.append(" Intent: "); 11763 intents.get(i).toShortString(sb, false, true, false, false); 11764 pw.println(sb.toString()); 11765 Bundle bundle = intents.get(i).getExtras(); 11766 if (bundle != null) { 11767 pw.print(" "); 11768 pw.println(bundle.toString()); 11769 } 11770 } 11771 } else { 11772 pw.println(""); 11773 } 11774 } 11775 } 11776 } 11777 11778 if (!onlyHistory && dumpAll) { 11779 pw.println(); 11780 for (BroadcastQueue queue : mBroadcastQueues) { 11781 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11782 + queue.mBroadcastsScheduled); 11783 } 11784 pw.println(" mHandler:"); 11785 mHandler.dump(new PrintWriterPrinter(pw), " "); 11786 needSep = true; 11787 printedAnything = true; 11788 } 11789 11790 if (!printedAnything) { 11791 pw.println(" (nothing)"); 11792 } 11793 } 11794 11795 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11796 int opti, boolean dumpAll, String dumpPackage) { 11797 boolean needSep; 11798 boolean printedAnything = false; 11799 11800 ItemMatcher matcher = new ItemMatcher(); 11801 matcher.build(args, opti); 11802 11803 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11804 11805 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11806 printedAnything |= needSep; 11807 11808 if (mLaunchingProviders.size() > 0) { 11809 boolean printed = false; 11810 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11811 ContentProviderRecord r = mLaunchingProviders.get(i); 11812 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11813 continue; 11814 } 11815 if (!printed) { 11816 if (needSep) pw.println(); 11817 needSep = true; 11818 pw.println(" Launching content providers:"); 11819 printed = true; 11820 printedAnything = true; 11821 } 11822 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11823 pw.println(r); 11824 } 11825 } 11826 11827 if (mGrantedUriPermissions.size() > 0) { 11828 boolean printed = false; 11829 int dumpUid = -2; 11830 if (dumpPackage != null) { 11831 try { 11832 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11833 } catch (NameNotFoundException e) { 11834 dumpUid = -1; 11835 } 11836 } 11837 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11838 int uid = mGrantedUriPermissions.keyAt(i); 11839 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11840 continue; 11841 } 11842 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11843 if (!printed) { 11844 if (needSep) pw.println(); 11845 needSep = true; 11846 pw.println(" Granted Uri Permissions:"); 11847 printed = true; 11848 printedAnything = true; 11849 } 11850 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11851 for (UriPermission perm : perms.values()) { 11852 pw.print(" "); pw.println(perm); 11853 if (dumpAll) { 11854 perm.dump(pw, " "); 11855 } 11856 } 11857 } 11858 } 11859 11860 if (!printedAnything) { 11861 pw.println(" (nothing)"); 11862 } 11863 } 11864 11865 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11866 int opti, boolean dumpAll, String dumpPackage) { 11867 boolean printed = false; 11868 11869 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11870 11871 if (mIntentSenderRecords.size() > 0) { 11872 Iterator<WeakReference<PendingIntentRecord>> it 11873 = mIntentSenderRecords.values().iterator(); 11874 while (it.hasNext()) { 11875 WeakReference<PendingIntentRecord> ref = it.next(); 11876 PendingIntentRecord rec = ref != null ? ref.get(): null; 11877 if (dumpPackage != null && (rec == null 11878 || !dumpPackage.equals(rec.key.packageName))) { 11879 continue; 11880 } 11881 printed = true; 11882 if (rec != null) { 11883 pw.print(" * "); pw.println(rec); 11884 if (dumpAll) { 11885 rec.dump(pw, " "); 11886 } 11887 } else { 11888 pw.print(" * "); pw.println(ref); 11889 } 11890 } 11891 } 11892 11893 if (!printed) { 11894 pw.println(" (nothing)"); 11895 } 11896 } 11897 11898 private static final int dumpProcessList(PrintWriter pw, 11899 ActivityManagerService service, List list, 11900 String prefix, String normalLabel, String persistentLabel, 11901 String dumpPackage) { 11902 int numPers = 0; 11903 final int N = list.size()-1; 11904 for (int i=N; i>=0; i--) { 11905 ProcessRecord r = (ProcessRecord)list.get(i); 11906 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11907 continue; 11908 } 11909 pw.println(String.format("%s%s #%2d: %s", 11910 prefix, (r.persistent ? persistentLabel : normalLabel), 11911 i, r.toString())); 11912 if (r.persistent) { 11913 numPers++; 11914 } 11915 } 11916 return numPers; 11917 } 11918 11919 private static final boolean dumpProcessOomList(PrintWriter pw, 11920 ActivityManagerService service, List<ProcessRecord> origList, 11921 String prefix, String normalLabel, String persistentLabel, 11922 boolean inclDetails, String dumpPackage) { 11923 11924 ArrayList<Pair<ProcessRecord, Integer>> list 11925 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11926 for (int i=0; i<origList.size(); i++) { 11927 ProcessRecord r = origList.get(i); 11928 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11929 continue; 11930 } 11931 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11932 } 11933 11934 if (list.size() <= 0) { 11935 return false; 11936 } 11937 11938 Comparator<Pair<ProcessRecord, Integer>> comparator 11939 = new Comparator<Pair<ProcessRecord, Integer>>() { 11940 @Override 11941 public int compare(Pair<ProcessRecord, Integer> object1, 11942 Pair<ProcessRecord, Integer> object2) { 11943 if (object1.first.setAdj != object2.first.setAdj) { 11944 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11945 } 11946 if (object1.second.intValue() != object2.second.intValue()) { 11947 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11948 } 11949 return 0; 11950 } 11951 }; 11952 11953 Collections.sort(list, comparator); 11954 11955 final long curRealtime = SystemClock.elapsedRealtime(); 11956 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11957 final long curUptime = SystemClock.uptimeMillis(); 11958 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11959 11960 for (int i=list.size()-1; i>=0; i--) { 11961 ProcessRecord r = list.get(i).first; 11962 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11963 char schedGroup; 11964 switch (r.setSchedGroup) { 11965 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11966 schedGroup = 'B'; 11967 break; 11968 case Process.THREAD_GROUP_DEFAULT: 11969 schedGroup = 'F'; 11970 break; 11971 default: 11972 schedGroup = '?'; 11973 break; 11974 } 11975 char foreground; 11976 if (r.foregroundActivities) { 11977 foreground = 'A'; 11978 } else if (r.foregroundServices) { 11979 foreground = 'S'; 11980 } else { 11981 foreground = ' '; 11982 } 11983 String procState = ProcessList.makeProcStateString(r.curProcState); 11984 pw.print(prefix); 11985 pw.print(r.persistent ? persistentLabel : normalLabel); 11986 pw.print(" #"); 11987 int num = (origList.size()-1)-list.get(i).second; 11988 if (num < 10) pw.print(' '); 11989 pw.print(num); 11990 pw.print(": "); 11991 pw.print(oomAdj); 11992 pw.print(' '); 11993 pw.print(schedGroup); 11994 pw.print('/'); 11995 pw.print(foreground); 11996 pw.print('/'); 11997 pw.print(procState); 11998 pw.print(" trm:"); 11999 if (r.trimMemoryLevel < 10) pw.print(' '); 12000 pw.print(r.trimMemoryLevel); 12001 pw.print(' '); 12002 pw.print(r.toShortString()); 12003 pw.print(" ("); 12004 pw.print(r.adjType); 12005 pw.println(')'); 12006 if (r.adjSource != null || r.adjTarget != null) { 12007 pw.print(prefix); 12008 pw.print(" "); 12009 if (r.adjTarget instanceof ComponentName) { 12010 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 12011 } else if (r.adjTarget != null) { 12012 pw.print(r.adjTarget.toString()); 12013 } else { 12014 pw.print("{null}"); 12015 } 12016 pw.print("<="); 12017 if (r.adjSource instanceof ProcessRecord) { 12018 pw.print("Proc{"); 12019 pw.print(((ProcessRecord)r.adjSource).toShortString()); 12020 pw.println("}"); 12021 } else if (r.adjSource != null) { 12022 pw.println(r.adjSource.toString()); 12023 } else { 12024 pw.println("{null}"); 12025 } 12026 } 12027 if (inclDetails) { 12028 pw.print(prefix); 12029 pw.print(" "); 12030 pw.print("oom: max="); pw.print(r.maxAdj); 12031 pw.print(" curRaw="); pw.print(r.curRawAdj); 12032 pw.print(" setRaw="); pw.print(r.setRawAdj); 12033 pw.print(" cur="); pw.print(r.curAdj); 12034 pw.print(" set="); pw.println(r.setAdj); 12035 pw.print(prefix); 12036 pw.print(" "); 12037 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 12038 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 12039 pw.print(" lastPss="); pw.print(r.lastPss); 12040 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12041 pw.print(prefix); 12042 pw.print(" "); 12043 pw.print("keeping="); pw.print(r.keeping); 12044 pw.print(" cached="); pw.print(r.cached); 12045 pw.print(" empty="); pw.print(r.empty); 12046 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12047 12048 if (!r.keeping) { 12049 if (r.lastWakeTime != 0) { 12050 long wtime; 12051 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12052 synchronized (stats) { 12053 wtime = stats.getProcessWakeTime(r.info.uid, 12054 r.pid, curRealtime); 12055 } 12056 long timeUsed = wtime - r.lastWakeTime; 12057 pw.print(prefix); 12058 pw.print(" "); 12059 pw.print("keep awake over "); 12060 TimeUtils.formatDuration(realtimeSince, pw); 12061 pw.print(" used "); 12062 TimeUtils.formatDuration(timeUsed, pw); 12063 pw.print(" ("); 12064 pw.print((timeUsed*100)/realtimeSince); 12065 pw.println("%)"); 12066 } 12067 if (r.lastCpuTime != 0) { 12068 long timeUsed = r.curCpuTime - r.lastCpuTime; 12069 pw.print(prefix); 12070 pw.print(" "); 12071 pw.print("run cpu over "); 12072 TimeUtils.formatDuration(uptimeSince, pw); 12073 pw.print(" used "); 12074 TimeUtils.formatDuration(timeUsed, pw); 12075 pw.print(" ("); 12076 pw.print((timeUsed*100)/uptimeSince); 12077 pw.println("%)"); 12078 } 12079 } 12080 } 12081 } 12082 return true; 12083 } 12084 12085 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12086 ArrayList<ProcessRecord> procs; 12087 synchronized (this) { 12088 if (args != null && args.length > start 12089 && args[start].charAt(0) != '-') { 12090 procs = new ArrayList<ProcessRecord>(); 12091 int pid = -1; 12092 try { 12093 pid = Integer.parseInt(args[start]); 12094 } catch (NumberFormatException e) { 12095 } 12096 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12097 ProcessRecord proc = mLruProcesses.get(i); 12098 if (proc.pid == pid) { 12099 procs.add(proc); 12100 } else if (proc.processName.equals(args[start])) { 12101 procs.add(proc); 12102 } 12103 } 12104 if (procs.size() <= 0) { 12105 return null; 12106 } 12107 } else { 12108 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12109 } 12110 } 12111 return procs; 12112 } 12113 12114 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12115 PrintWriter pw, String[] args) { 12116 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12117 if (procs == null) { 12118 pw.println("No process found for: " + args[0]); 12119 return; 12120 } 12121 12122 long uptime = SystemClock.uptimeMillis(); 12123 long realtime = SystemClock.elapsedRealtime(); 12124 pw.println("Applications Graphics Acceleration Info:"); 12125 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12126 12127 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12128 ProcessRecord r = procs.get(i); 12129 if (r.thread != null) { 12130 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12131 pw.flush(); 12132 try { 12133 TransferPipe tp = new TransferPipe(); 12134 try { 12135 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12136 tp.go(fd); 12137 } finally { 12138 tp.kill(); 12139 } 12140 } catch (IOException e) { 12141 pw.println("Failure while dumping the app: " + r); 12142 pw.flush(); 12143 } catch (RemoteException e) { 12144 pw.println("Got a RemoteException while dumping the app " + r); 12145 pw.flush(); 12146 } 12147 } 12148 } 12149 } 12150 12151 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12152 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12153 if (procs == null) { 12154 pw.println("No process found for: " + args[0]); 12155 return; 12156 } 12157 12158 pw.println("Applications Database Info:"); 12159 12160 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12161 ProcessRecord r = procs.get(i); 12162 if (r.thread != null) { 12163 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12164 pw.flush(); 12165 try { 12166 TransferPipe tp = new TransferPipe(); 12167 try { 12168 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12169 tp.go(fd); 12170 } finally { 12171 tp.kill(); 12172 } 12173 } catch (IOException e) { 12174 pw.println("Failure while dumping the app: " + r); 12175 pw.flush(); 12176 } catch (RemoteException e) { 12177 pw.println("Got a RemoteException while dumping the app " + r); 12178 pw.flush(); 12179 } 12180 } 12181 } 12182 } 12183 12184 final static class MemItem { 12185 final boolean isProc; 12186 final String label; 12187 final String shortLabel; 12188 final long pss; 12189 final int id; 12190 final boolean hasActivities; 12191 ArrayList<MemItem> subitems; 12192 12193 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12194 boolean _hasActivities) { 12195 isProc = true; 12196 label = _label; 12197 shortLabel = _shortLabel; 12198 pss = _pss; 12199 id = _id; 12200 hasActivities = _hasActivities; 12201 } 12202 12203 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12204 isProc = false; 12205 label = _label; 12206 shortLabel = _shortLabel; 12207 pss = _pss; 12208 id = _id; 12209 hasActivities = false; 12210 } 12211 } 12212 12213 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12214 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12215 if (sort && !isCompact) { 12216 Collections.sort(items, new Comparator<MemItem>() { 12217 @Override 12218 public int compare(MemItem lhs, MemItem rhs) { 12219 if (lhs.pss < rhs.pss) { 12220 return 1; 12221 } else if (lhs.pss > rhs.pss) { 12222 return -1; 12223 } 12224 return 0; 12225 } 12226 }); 12227 } 12228 12229 for (int i=0; i<items.size(); i++) { 12230 MemItem mi = items.get(i); 12231 if (!isCompact) { 12232 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12233 } else if (mi.isProc) { 12234 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12235 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12236 pw.println(mi.hasActivities ? ",a" : ",e"); 12237 } else { 12238 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12239 pw.println(mi.pss); 12240 } 12241 if (mi.subitems != null) { 12242 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12243 true, isCompact); 12244 } 12245 } 12246 } 12247 12248 // These are in KB. 12249 static final long[] DUMP_MEM_BUCKETS = new long[] { 12250 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12251 120*1024, 160*1024, 200*1024, 12252 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12253 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12254 }; 12255 12256 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12257 boolean stackLike) { 12258 int start = label.lastIndexOf('.'); 12259 if (start >= 0) start++; 12260 else start = 0; 12261 int end = label.length(); 12262 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12263 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12264 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12265 out.append(bucket); 12266 out.append(stackLike ? "MB." : "MB "); 12267 out.append(label, start, end); 12268 return; 12269 } 12270 } 12271 out.append(memKB/1024); 12272 out.append(stackLike ? "MB." : "MB "); 12273 out.append(label, start, end); 12274 } 12275 12276 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12277 ProcessList.NATIVE_ADJ, 12278 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12279 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12280 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12281 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12282 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12283 }; 12284 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12285 "Native", 12286 "System", "Persistent", "Foreground", 12287 "Visible", "Perceptible", 12288 "Heavy Weight", "Backup", 12289 "A Services", "Home", 12290 "Previous", "B Services", "Cached" 12291 }; 12292 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12293 "native", 12294 "sys", "pers", "fore", 12295 "vis", "percept", 12296 "heavy", "backup", 12297 "servicea", "home", 12298 "prev", "serviceb", "cached" 12299 }; 12300 12301 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12302 long realtime, boolean isCheckinRequest, boolean isCompact) { 12303 if (isCheckinRequest || isCompact) { 12304 // short checkin version 12305 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12306 } else { 12307 pw.println("Applications Memory Usage (kB):"); 12308 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12309 } 12310 } 12311 12312 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12313 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12314 boolean dumpDetails = false; 12315 boolean dumpFullDetails = false; 12316 boolean dumpDalvik = false; 12317 boolean oomOnly = false; 12318 boolean isCompact = false; 12319 boolean localOnly = false; 12320 12321 int opti = 0; 12322 while (opti < args.length) { 12323 String opt = args[opti]; 12324 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12325 break; 12326 } 12327 opti++; 12328 if ("-a".equals(opt)) { 12329 dumpDetails = true; 12330 dumpFullDetails = true; 12331 dumpDalvik = true; 12332 } else if ("-d".equals(opt)) { 12333 dumpDalvik = true; 12334 } else if ("-c".equals(opt)) { 12335 isCompact = true; 12336 } else if ("--oom".equals(opt)) { 12337 oomOnly = true; 12338 } else if ("--local".equals(opt)) { 12339 localOnly = true; 12340 } else if ("-h".equals(opt)) { 12341 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12342 pw.println(" -a: include all available information for each process."); 12343 pw.println(" -d: include dalvik details when dumping process details."); 12344 pw.println(" -c: dump in a compact machine-parseable representation."); 12345 pw.println(" --oom: only show processes organized by oom adj."); 12346 pw.println(" --local: only collect details locally, don't call process."); 12347 pw.println("If [process] is specified it can be the name or "); 12348 pw.println("pid of a specific process to dump."); 12349 return; 12350 } else { 12351 pw.println("Unknown argument: " + opt + "; use -h for help"); 12352 } 12353 } 12354 12355 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12356 long uptime = SystemClock.uptimeMillis(); 12357 long realtime = SystemClock.elapsedRealtime(); 12358 final long[] tmpLong = new long[1]; 12359 12360 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12361 if (procs == null) { 12362 // No Java processes. Maybe they want to print a native process. 12363 if (args != null && args.length > opti 12364 && args[opti].charAt(0) != '-') { 12365 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12366 = new ArrayList<ProcessCpuTracker.Stats>(); 12367 updateCpuStatsNow(); 12368 int findPid = -1; 12369 try { 12370 findPid = Integer.parseInt(args[opti]); 12371 } catch (NumberFormatException e) { 12372 } 12373 synchronized (mProcessCpuThread) { 12374 final int N = mProcessCpuTracker.countStats(); 12375 for (int i=0; i<N; i++) { 12376 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12377 if (st.pid == findPid || (st.baseName != null 12378 && st.baseName.equals(args[opti]))) { 12379 nativeProcs.add(st); 12380 } 12381 } 12382 } 12383 if (nativeProcs.size() > 0) { 12384 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12385 isCompact); 12386 Debug.MemoryInfo mi = null; 12387 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12388 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12389 final int pid = r.pid; 12390 if (!isCheckinRequest && dumpDetails) { 12391 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12392 } 12393 if (mi == null) { 12394 mi = new Debug.MemoryInfo(); 12395 } 12396 if (dumpDetails || (!brief && !oomOnly)) { 12397 Debug.getMemoryInfo(pid, mi); 12398 } else { 12399 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12400 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12401 } 12402 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12403 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12404 if (isCheckinRequest) { 12405 pw.println(); 12406 } 12407 } 12408 return; 12409 } 12410 } 12411 pw.println("No process found for: " + args[opti]); 12412 return; 12413 } 12414 12415 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12416 dumpDetails = true; 12417 } 12418 12419 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12420 12421 String[] innerArgs = new String[args.length-opti]; 12422 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12423 12424 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12425 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12426 long nativePss=0, dalvikPss=0, otherPss=0; 12427 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12428 12429 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12430 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12431 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12432 12433 long totalPss = 0; 12434 long cachedPss = 0; 12435 12436 Debug.MemoryInfo mi = null; 12437 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12438 final ProcessRecord r = procs.get(i); 12439 final IApplicationThread thread; 12440 final int pid; 12441 final int oomAdj; 12442 final boolean hasActivities; 12443 synchronized (this) { 12444 thread = r.thread; 12445 pid = r.pid; 12446 oomAdj = r.getSetAdjWithServices(); 12447 hasActivities = r.activities.size() > 0; 12448 } 12449 if (thread != null) { 12450 if (!isCheckinRequest && dumpDetails) { 12451 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12452 } 12453 if (mi == null) { 12454 mi = new Debug.MemoryInfo(); 12455 } 12456 if (dumpDetails || (!brief && !oomOnly)) { 12457 Debug.getMemoryInfo(pid, mi); 12458 } else { 12459 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12460 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12461 } 12462 if (dumpDetails) { 12463 if (localOnly) { 12464 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12465 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12466 if (isCheckinRequest) { 12467 pw.println(); 12468 } 12469 } else { 12470 try { 12471 pw.flush(); 12472 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12473 dumpDalvik, innerArgs); 12474 } catch (RemoteException e) { 12475 if (!isCheckinRequest) { 12476 pw.println("Got RemoteException!"); 12477 pw.flush(); 12478 } 12479 } 12480 } 12481 } 12482 12483 final long myTotalPss = mi.getTotalPss(); 12484 final long myTotalUss = mi.getTotalUss(); 12485 12486 synchronized (this) { 12487 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12488 // Record this for posterity if the process has been stable. 12489 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12490 } 12491 } 12492 12493 if (!isCheckinRequest && mi != null) { 12494 totalPss += myTotalPss; 12495 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12496 (hasActivities ? " / activities)" : ")"), 12497 r.processName, myTotalPss, pid, hasActivities); 12498 procMems.add(pssItem); 12499 procMemsMap.put(pid, pssItem); 12500 12501 nativePss += mi.nativePss; 12502 dalvikPss += mi.dalvikPss; 12503 otherPss += mi.otherPss; 12504 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12505 long mem = mi.getOtherPss(j); 12506 miscPss[j] += mem; 12507 otherPss -= mem; 12508 } 12509 12510 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12511 cachedPss += myTotalPss; 12512 } 12513 12514 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12515 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12516 || oomIndex == (oomPss.length-1)) { 12517 oomPss[oomIndex] += myTotalPss; 12518 if (oomProcs[oomIndex] == null) { 12519 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12520 } 12521 oomProcs[oomIndex].add(pssItem); 12522 break; 12523 } 12524 } 12525 } 12526 } 12527 } 12528 12529 if (!isCheckinRequest && procs.size() > 1) { 12530 // If we are showing aggregations, also look for native processes to 12531 // include so that our aggregations are more accurate. 12532 updateCpuStatsNow(); 12533 synchronized (mProcessCpuThread) { 12534 final int N = mProcessCpuTracker.countStats(); 12535 for (int i=0; i<N; i++) { 12536 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12537 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12538 if (mi == null) { 12539 mi = new Debug.MemoryInfo(); 12540 } 12541 if (!brief && !oomOnly) { 12542 Debug.getMemoryInfo(st.pid, mi); 12543 } else { 12544 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12545 mi.nativePrivateDirty = (int)tmpLong[0]; 12546 } 12547 12548 final long myTotalPss = mi.getTotalPss(); 12549 totalPss += myTotalPss; 12550 12551 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12552 st.name, myTotalPss, st.pid, false); 12553 procMems.add(pssItem); 12554 12555 nativePss += mi.nativePss; 12556 dalvikPss += mi.dalvikPss; 12557 otherPss += mi.otherPss; 12558 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12559 long mem = mi.getOtherPss(j); 12560 miscPss[j] += mem; 12561 otherPss -= mem; 12562 } 12563 oomPss[0] += myTotalPss; 12564 if (oomProcs[0] == null) { 12565 oomProcs[0] = new ArrayList<MemItem>(); 12566 } 12567 oomProcs[0].add(pssItem); 12568 } 12569 } 12570 } 12571 12572 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12573 12574 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12575 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12576 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12577 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12578 String label = Debug.MemoryInfo.getOtherLabel(j); 12579 catMems.add(new MemItem(label, label, miscPss[j], j)); 12580 } 12581 12582 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12583 for (int j=0; j<oomPss.length; j++) { 12584 if (oomPss[j] != 0) { 12585 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12586 : DUMP_MEM_OOM_LABEL[j]; 12587 MemItem item = new MemItem(label, label, oomPss[j], 12588 DUMP_MEM_OOM_ADJ[j]); 12589 item.subitems = oomProcs[j]; 12590 oomMems.add(item); 12591 } 12592 } 12593 12594 if (!brief && !oomOnly && !isCompact) { 12595 pw.println(); 12596 pw.println("Total PSS by process:"); 12597 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12598 pw.println(); 12599 } 12600 if (!isCompact) { 12601 pw.println("Total PSS by OOM adjustment:"); 12602 } 12603 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12604 if (!brief && !oomOnly) { 12605 PrintWriter out = categoryPw != null ? categoryPw : pw; 12606 if (!isCompact) { 12607 out.println(); 12608 out.println("Total PSS by category:"); 12609 } 12610 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12611 } 12612 if (!isCompact) { 12613 pw.println(); 12614 } 12615 MemInfoReader memInfo = new MemInfoReader(); 12616 memInfo.readMemInfo(); 12617 if (!brief) { 12618 if (!isCompact) { 12619 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12620 pw.print(" kB (status "); 12621 switch (mLastMemoryLevel) { 12622 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12623 pw.println("normal)"); 12624 break; 12625 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12626 pw.println("moderate)"); 12627 break; 12628 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12629 pw.println("low)"); 12630 break; 12631 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12632 pw.println("critical)"); 12633 break; 12634 default: 12635 pw.print(mLastMemoryLevel); 12636 pw.println(")"); 12637 break; 12638 } 12639 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12640 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12641 pw.print(cachedPss); pw.print(" cached pss + "); 12642 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12643 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12644 } else { 12645 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12646 pw.print(cachedPss + memInfo.getCachedSizeKb() 12647 + memInfo.getFreeSizeKb()); pw.print(","); 12648 pw.println(totalPss - cachedPss); 12649 } 12650 } 12651 if (!isCompact) { 12652 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12653 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12654 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12655 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12656 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12657 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12658 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12659 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12660 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12661 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12662 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12663 } 12664 if (!brief) { 12665 if (memInfo.getZramTotalSizeKb() != 0) { 12666 if (!isCompact) { 12667 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12668 pw.print(" kB physical used for "); 12669 pw.print(memInfo.getSwapTotalSizeKb() 12670 - memInfo.getSwapFreeSizeKb()); 12671 pw.print(" kB in swap ("); 12672 pw.print(memInfo.getSwapTotalSizeKb()); 12673 pw.println(" kB total swap)"); 12674 } else { 12675 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12676 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12677 pw.println(memInfo.getSwapFreeSizeKb()); 12678 } 12679 } 12680 final int[] SINGLE_LONG_FORMAT = new int[] { 12681 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12682 }; 12683 long[] longOut = new long[1]; 12684 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12685 SINGLE_LONG_FORMAT, null, longOut, null); 12686 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12687 longOut[0] = 0; 12688 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12689 SINGLE_LONG_FORMAT, null, longOut, null); 12690 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12691 longOut[0] = 0; 12692 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12693 SINGLE_LONG_FORMAT, null, longOut, null); 12694 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12695 longOut[0] = 0; 12696 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12697 SINGLE_LONG_FORMAT, null, longOut, null); 12698 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12699 if (!isCompact) { 12700 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12701 pw.print(" KSM: "); pw.print(sharing); 12702 pw.print(" kB saved from shared "); 12703 pw.print(shared); pw.println(" kB"); 12704 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12705 pw.print(voltile); pw.println(" kB volatile"); 12706 } 12707 pw.print(" Tuning: "); 12708 pw.print(ActivityManager.staticGetMemoryClass()); 12709 pw.print(" (large "); 12710 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12711 pw.print("), oom "); 12712 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12713 pw.print(" kB"); 12714 pw.print(", restore limit "); 12715 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12716 pw.print(" kB"); 12717 if (ActivityManager.isLowRamDeviceStatic()) { 12718 pw.print(" (low-ram)"); 12719 } 12720 if (ActivityManager.isHighEndGfx()) { 12721 pw.print(" (high-end-gfx)"); 12722 } 12723 pw.println(); 12724 } else { 12725 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12726 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12727 pw.println(voltile); 12728 pw.print("tuning,"); 12729 pw.print(ActivityManager.staticGetMemoryClass()); 12730 pw.print(','); 12731 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12732 pw.print(','); 12733 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12734 if (ActivityManager.isLowRamDeviceStatic()) { 12735 pw.print(",low-ram"); 12736 } 12737 if (ActivityManager.isHighEndGfx()) { 12738 pw.print(",high-end-gfx"); 12739 } 12740 pw.println(); 12741 } 12742 } 12743 } 12744 } 12745 12746 /** 12747 * Searches array of arguments for the specified string 12748 * @param args array of argument strings 12749 * @param value value to search for 12750 * @return true if the value is contained in the array 12751 */ 12752 private static boolean scanArgs(String[] args, String value) { 12753 if (args != null) { 12754 for (String arg : args) { 12755 if (value.equals(arg)) { 12756 return true; 12757 } 12758 } 12759 } 12760 return false; 12761 } 12762 12763 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12764 ContentProviderRecord cpr, boolean always) { 12765 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12766 12767 if (!inLaunching || always) { 12768 synchronized (cpr) { 12769 cpr.launchingApp = null; 12770 cpr.notifyAll(); 12771 } 12772 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12773 String names[] = cpr.info.authority.split(";"); 12774 for (int j = 0; j < names.length; j++) { 12775 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12776 } 12777 } 12778 12779 for (int i=0; i<cpr.connections.size(); i++) { 12780 ContentProviderConnection conn = cpr.connections.get(i); 12781 if (conn.waiting) { 12782 // If this connection is waiting for the provider, then we don't 12783 // need to mess with its process unless we are always removing 12784 // or for some reason the provider is not currently launching. 12785 if (inLaunching && !always) { 12786 continue; 12787 } 12788 } 12789 ProcessRecord capp = conn.client; 12790 conn.dead = true; 12791 if (conn.stableCount > 0) { 12792 if (!capp.persistent && capp.thread != null 12793 && capp.pid != 0 12794 && capp.pid != MY_PID) { 12795 killUnneededProcessLocked(capp, "depends on provider " 12796 + cpr.name.flattenToShortString() 12797 + " in dying proc " + (proc != null ? proc.processName : "??")); 12798 } 12799 } else if (capp.thread != null && conn.provider.provider != null) { 12800 try { 12801 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12802 } catch (RemoteException e) { 12803 } 12804 // In the protocol here, we don't expect the client to correctly 12805 // clean up this connection, we'll just remove it. 12806 cpr.connections.remove(i); 12807 conn.client.conProviders.remove(conn); 12808 } 12809 } 12810 12811 if (inLaunching && always) { 12812 mLaunchingProviders.remove(cpr); 12813 } 12814 return inLaunching; 12815 } 12816 12817 /** 12818 * Main code for cleaning up a process when it has gone away. This is 12819 * called both as a result of the process dying, or directly when stopping 12820 * a process when running in single process mode. 12821 */ 12822 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12823 boolean restarting, boolean allowRestart, int index) { 12824 if (index >= 0) { 12825 removeLruProcessLocked(app); 12826 ProcessList.remove(app.pid); 12827 } 12828 12829 mProcessesToGc.remove(app); 12830 mPendingPssProcesses.remove(app); 12831 12832 // Dismiss any open dialogs. 12833 if (app.crashDialog != null && !app.forceCrashReport) { 12834 app.crashDialog.dismiss(); 12835 app.crashDialog = null; 12836 } 12837 if (app.anrDialog != null) { 12838 app.anrDialog.dismiss(); 12839 app.anrDialog = null; 12840 } 12841 if (app.waitDialog != null) { 12842 app.waitDialog.dismiss(); 12843 app.waitDialog = null; 12844 } 12845 12846 app.crashing = false; 12847 app.notResponding = false; 12848 12849 app.resetPackageList(mProcessStats); 12850 app.unlinkDeathRecipient(); 12851 app.makeInactive(mProcessStats); 12852 app.forcingToForeground = null; 12853 updateProcessForegroundLocked(app, false, false); 12854 app.foregroundActivities = false; 12855 app.hasShownUi = false; 12856 app.treatLikeActivity = false; 12857 app.hasAboveClient = false; 12858 app.hasClientActivities = false; 12859 12860 mServices.killServicesLocked(app, allowRestart); 12861 12862 boolean restart = false; 12863 12864 // Remove published content providers. 12865 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12866 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12867 final boolean always = app.bad || !allowRestart; 12868 if (removeDyingProviderLocked(app, cpr, always) || always) { 12869 // We left the provider in the launching list, need to 12870 // restart it. 12871 restart = true; 12872 } 12873 12874 cpr.provider = null; 12875 cpr.proc = null; 12876 } 12877 app.pubProviders.clear(); 12878 12879 // Take care of any launching providers waiting for this process. 12880 if (checkAppInLaunchingProvidersLocked(app, false)) { 12881 restart = true; 12882 } 12883 12884 // Unregister from connected content providers. 12885 if (!app.conProviders.isEmpty()) { 12886 for (int i=0; i<app.conProviders.size(); i++) { 12887 ContentProviderConnection conn = app.conProviders.get(i); 12888 conn.provider.connections.remove(conn); 12889 } 12890 app.conProviders.clear(); 12891 } 12892 12893 // At this point there may be remaining entries in mLaunchingProviders 12894 // where we were the only one waiting, so they are no longer of use. 12895 // Look for these and clean up if found. 12896 // XXX Commented out for now. Trying to figure out a way to reproduce 12897 // the actual situation to identify what is actually going on. 12898 if (false) { 12899 for (int i=0; i<mLaunchingProviders.size(); i++) { 12900 ContentProviderRecord cpr = (ContentProviderRecord) 12901 mLaunchingProviders.get(i); 12902 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12903 synchronized (cpr) { 12904 cpr.launchingApp = null; 12905 cpr.notifyAll(); 12906 } 12907 } 12908 } 12909 } 12910 12911 skipCurrentReceiverLocked(app); 12912 12913 // Unregister any receivers. 12914 for (int i=app.receivers.size()-1; i>=0; i--) { 12915 removeReceiverLocked(app.receivers.valueAt(i)); 12916 } 12917 app.receivers.clear(); 12918 12919 // If the app is undergoing backup, tell the backup manager about it 12920 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12921 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12922 + mBackupTarget.appInfo + " died during backup"); 12923 try { 12924 IBackupManager bm = IBackupManager.Stub.asInterface( 12925 ServiceManager.getService(Context.BACKUP_SERVICE)); 12926 bm.agentDisconnected(app.info.packageName); 12927 } catch (RemoteException e) { 12928 // can't happen; backup manager is local 12929 } 12930 } 12931 12932 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12933 ProcessChangeItem item = mPendingProcessChanges.get(i); 12934 if (item.pid == app.pid) { 12935 mPendingProcessChanges.remove(i); 12936 mAvailProcessChanges.add(item); 12937 } 12938 } 12939 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12940 12941 // If the caller is restarting this app, then leave it in its 12942 // current lists and let the caller take care of it. 12943 if (restarting) { 12944 return; 12945 } 12946 12947 if (!app.persistent || app.isolated) { 12948 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12949 "Removing non-persistent process during cleanup: " + app); 12950 mProcessNames.remove(app.processName, app.uid); 12951 mIsolatedProcesses.remove(app.uid); 12952 if (mHeavyWeightProcess == app) { 12953 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12954 mHeavyWeightProcess.userId, 0)); 12955 mHeavyWeightProcess = null; 12956 } 12957 } else if (!app.removed) { 12958 // This app is persistent, so we need to keep its record around. 12959 // If it is not already on the pending app list, add it there 12960 // and start a new process for it. 12961 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12962 mPersistentStartingProcesses.add(app); 12963 restart = true; 12964 } 12965 } 12966 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12967 "Clean-up removing on hold: " + app); 12968 mProcessesOnHold.remove(app); 12969 12970 if (app == mHomeProcess) { 12971 mHomeProcess = null; 12972 } 12973 if (app == mPreviousProcess) { 12974 mPreviousProcess = null; 12975 } 12976 12977 if (restart && !app.isolated) { 12978 // We have components that still need to be running in the 12979 // process, so re-launch it. 12980 mProcessNames.put(app.processName, app.uid, app); 12981 startProcessLocked(app, "restart", app.processName); 12982 } else if (app.pid > 0 && app.pid != MY_PID) { 12983 // Goodbye! 12984 boolean removed; 12985 synchronized (mPidsSelfLocked) { 12986 mPidsSelfLocked.remove(app.pid); 12987 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12988 } 12989 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12990 app.processName, app.info.uid); 12991 if (app.isolated) { 12992 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12993 } 12994 app.setPid(0); 12995 } 12996 } 12997 12998 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12999 // Look through the content providers we are waiting to have launched, 13000 // and if any run in this process then either schedule a restart of 13001 // the process or kill the client waiting for it if this process has 13002 // gone bad. 13003 int NL = mLaunchingProviders.size(); 13004 boolean restart = false; 13005 for (int i=0; i<NL; i++) { 13006 ContentProviderRecord cpr = mLaunchingProviders.get(i); 13007 if (cpr.launchingApp == app) { 13008 if (!alwaysBad && !app.bad) { 13009 restart = true; 13010 } else { 13011 removeDyingProviderLocked(app, cpr, true); 13012 // cpr should have been removed from mLaunchingProviders 13013 NL = mLaunchingProviders.size(); 13014 i--; 13015 } 13016 } 13017 } 13018 return restart; 13019 } 13020 13021 // ========================================================= 13022 // SERVICES 13023 // ========================================================= 13024 13025 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 13026 int flags) { 13027 enforceNotIsolatedCaller("getServices"); 13028 synchronized (this) { 13029 return mServices.getRunningServiceInfoLocked(maxNum, flags); 13030 } 13031 } 13032 13033 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 13034 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 13035 synchronized (this) { 13036 return mServices.getRunningServiceControlPanelLocked(name); 13037 } 13038 } 13039 13040 public ComponentName startService(IApplicationThread caller, Intent service, 13041 String resolvedType, int userId) { 13042 enforceNotIsolatedCaller("startService"); 13043 // Refuse possible leaked file descriptors 13044 if (service != null && service.hasFileDescriptors() == true) { 13045 throw new IllegalArgumentException("File descriptors passed in Intent"); 13046 } 13047 13048 if (DEBUG_SERVICE) 13049 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13050 synchronized(this) { 13051 final int callingPid = Binder.getCallingPid(); 13052 final int callingUid = Binder.getCallingUid(); 13053 final long origId = Binder.clearCallingIdentity(); 13054 ComponentName res = mServices.startServiceLocked(caller, service, 13055 resolvedType, callingPid, callingUid, userId); 13056 Binder.restoreCallingIdentity(origId); 13057 return res; 13058 } 13059 } 13060 13061 ComponentName startServiceInPackage(int uid, 13062 Intent service, String resolvedType, int userId) { 13063 synchronized(this) { 13064 if (DEBUG_SERVICE) 13065 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13066 final long origId = Binder.clearCallingIdentity(); 13067 ComponentName res = mServices.startServiceLocked(null, service, 13068 resolvedType, -1, uid, userId); 13069 Binder.restoreCallingIdentity(origId); 13070 return res; 13071 } 13072 } 13073 13074 public int stopService(IApplicationThread caller, Intent service, 13075 String resolvedType, int userId) { 13076 enforceNotIsolatedCaller("stopService"); 13077 // Refuse possible leaked file descriptors 13078 if (service != null && service.hasFileDescriptors() == true) { 13079 throw new IllegalArgumentException("File descriptors passed in Intent"); 13080 } 13081 13082 synchronized(this) { 13083 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13084 } 13085 } 13086 13087 public IBinder peekService(Intent service, String resolvedType) { 13088 enforceNotIsolatedCaller("peekService"); 13089 // Refuse possible leaked file descriptors 13090 if (service != null && service.hasFileDescriptors() == true) { 13091 throw new IllegalArgumentException("File descriptors passed in Intent"); 13092 } 13093 synchronized(this) { 13094 return mServices.peekServiceLocked(service, resolvedType); 13095 } 13096 } 13097 13098 public boolean stopServiceToken(ComponentName className, IBinder token, 13099 int startId) { 13100 synchronized(this) { 13101 return mServices.stopServiceTokenLocked(className, token, startId); 13102 } 13103 } 13104 13105 public void setServiceForeground(ComponentName className, IBinder token, 13106 int id, Notification notification, boolean removeNotification) { 13107 synchronized(this) { 13108 mServices.setServiceForegroundLocked(className, token, id, notification, 13109 removeNotification); 13110 } 13111 } 13112 13113 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13114 boolean requireFull, String name, String callerPackage) { 13115 final int callingUserId = UserHandle.getUserId(callingUid); 13116 if (callingUserId != userId) { 13117 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13118 if ((requireFull || checkComponentPermission( 13119 android.Manifest.permission.INTERACT_ACROSS_USERS, 13120 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 13121 && checkComponentPermission(INTERACT_ACROSS_USERS_FULL, 13122 callingPid, callingUid, -1, true) 13123 != PackageManager.PERMISSION_GRANTED) { 13124 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13125 // In this case, they would like to just execute as their 13126 // owner user instead of failing. 13127 userId = callingUserId; 13128 } else { 13129 StringBuilder builder = new StringBuilder(128); 13130 builder.append("Permission Denial: "); 13131 builder.append(name); 13132 if (callerPackage != null) { 13133 builder.append(" from "); 13134 builder.append(callerPackage); 13135 } 13136 builder.append(" asks to run as user "); 13137 builder.append(userId); 13138 builder.append(" but is calling from user "); 13139 builder.append(UserHandle.getUserId(callingUid)); 13140 builder.append("; this requires "); 13141 builder.append(INTERACT_ACROSS_USERS_FULL); 13142 if (!requireFull) { 13143 builder.append(" or "); 13144 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13145 } 13146 String msg = builder.toString(); 13147 Slog.w(TAG, msg); 13148 throw new SecurityException(msg); 13149 } 13150 } 13151 } 13152 if (userId == UserHandle.USER_CURRENT 13153 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13154 // Note that we may be accessing this outside of a lock... 13155 // shouldn't be a big deal, if this is being called outside 13156 // of a locked context there is intrinsically a race with 13157 // the value the caller will receive and someone else changing it. 13158 userId = mCurrentUserId; 13159 } 13160 if (!allowAll && userId < 0) { 13161 throw new IllegalArgumentException( 13162 "Call does not support special user #" + userId); 13163 } 13164 } 13165 return userId; 13166 } 13167 13168 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13169 String className, int flags) { 13170 boolean result = false; 13171 // For apps that don't have pre-defined UIDs, check for permission 13172 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13173 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 13174 if (ActivityManager.checkUidPermission( 13175 android.Manifest.permission.INTERACT_ACROSS_USERS, 13176 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13177 ComponentName comp = new ComponentName(aInfo.packageName, className); 13178 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13179 + " requests FLAG_SINGLE_USER, but app does not hold " 13180 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13181 Slog.w(TAG, msg); 13182 throw new SecurityException(msg); 13183 } 13184 // Permission passed 13185 result = true; 13186 } 13187 } else if ("system".equals(componentProcessName)) { 13188 result = true; 13189 } else { 13190 // App with pre-defined UID, check if it's a persistent app 13191 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13192 } 13193 if (DEBUG_MU) { 13194 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13195 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13196 } 13197 return result; 13198 } 13199 13200 /** 13201 * Checks to see if the caller is in the same app as the singleton 13202 * component, or the component is in a special app. It allows special apps 13203 * to export singleton components but prevents exporting singleton 13204 * components for regular apps. 13205 */ 13206 boolean isValidSingletonCall(int callingUid, int componentUid) { 13207 int componentAppId = UserHandle.getAppId(componentUid); 13208 return UserHandle.isSameApp(callingUid, componentUid) 13209 || componentAppId == Process.SYSTEM_UID 13210 || componentAppId == Process.PHONE_UID 13211 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 13212 == PackageManager.PERMISSION_GRANTED; 13213 } 13214 13215 public int bindService(IApplicationThread caller, IBinder token, 13216 Intent service, String resolvedType, 13217 IServiceConnection connection, int flags, int userId) { 13218 enforceNotIsolatedCaller("bindService"); 13219 // Refuse possible leaked file descriptors 13220 if (service != null && service.hasFileDescriptors() == true) { 13221 throw new IllegalArgumentException("File descriptors passed in Intent"); 13222 } 13223 13224 synchronized(this) { 13225 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13226 connection, flags, userId); 13227 } 13228 } 13229 13230 public boolean unbindService(IServiceConnection connection) { 13231 synchronized (this) { 13232 return mServices.unbindServiceLocked(connection); 13233 } 13234 } 13235 13236 public void publishService(IBinder token, Intent intent, IBinder service) { 13237 // Refuse possible leaked file descriptors 13238 if (intent != null && intent.hasFileDescriptors() == true) { 13239 throw new IllegalArgumentException("File descriptors passed in Intent"); 13240 } 13241 13242 synchronized(this) { 13243 if (!(token instanceof ServiceRecord)) { 13244 throw new IllegalArgumentException("Invalid service token"); 13245 } 13246 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13247 } 13248 } 13249 13250 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13251 // Refuse possible leaked file descriptors 13252 if (intent != null && intent.hasFileDescriptors() == true) { 13253 throw new IllegalArgumentException("File descriptors passed in Intent"); 13254 } 13255 13256 synchronized(this) { 13257 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13258 } 13259 } 13260 13261 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13262 synchronized(this) { 13263 if (!(token instanceof ServiceRecord)) { 13264 throw new IllegalArgumentException("Invalid service token"); 13265 } 13266 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13267 } 13268 } 13269 13270 // ========================================================= 13271 // BACKUP AND RESTORE 13272 // ========================================================= 13273 13274 // Cause the target app to be launched if necessary and its backup agent 13275 // instantiated. The backup agent will invoke backupAgentCreated() on the 13276 // activity manager to announce its creation. 13277 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13278 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13279 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13280 13281 synchronized(this) { 13282 // !!! TODO: currently no check here that we're already bound 13283 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13284 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13285 synchronized (stats) { 13286 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13287 } 13288 13289 // Backup agent is now in use, its package can't be stopped. 13290 try { 13291 AppGlobals.getPackageManager().setPackageStoppedState( 13292 app.packageName, false, UserHandle.getUserId(app.uid)); 13293 } catch (RemoteException e) { 13294 } catch (IllegalArgumentException e) { 13295 Slog.w(TAG, "Failed trying to unstop package " 13296 + app.packageName + ": " + e); 13297 } 13298 13299 BackupRecord r = new BackupRecord(ss, app, backupMode); 13300 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13301 ? new ComponentName(app.packageName, app.backupAgentName) 13302 : new ComponentName("android", "FullBackupAgent"); 13303 // startProcessLocked() returns existing proc's record if it's already running 13304 ProcessRecord proc = startProcessLocked(app.processName, app, 13305 false, 0, "backup", hostingName, false, false, false); 13306 if (proc == null) { 13307 Slog.e(TAG, "Unable to start backup agent process " + r); 13308 return false; 13309 } 13310 13311 r.app = proc; 13312 mBackupTarget = r; 13313 mBackupAppName = app.packageName; 13314 13315 // Try not to kill the process during backup 13316 updateOomAdjLocked(proc); 13317 13318 // If the process is already attached, schedule the creation of the backup agent now. 13319 // If it is not yet live, this will be done when it attaches to the framework. 13320 if (proc.thread != null) { 13321 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13322 try { 13323 proc.thread.scheduleCreateBackupAgent(app, 13324 compatibilityInfoForPackageLocked(app), backupMode); 13325 } catch (RemoteException e) { 13326 // Will time out on the backup manager side 13327 } 13328 } else { 13329 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13330 } 13331 // Invariants: at this point, the target app process exists and the application 13332 // is either already running or in the process of coming up. mBackupTarget and 13333 // mBackupAppName describe the app, so that when it binds back to the AM we 13334 // know that it's scheduled for a backup-agent operation. 13335 } 13336 13337 return true; 13338 } 13339 13340 @Override 13341 public void clearPendingBackup() { 13342 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13343 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13344 13345 synchronized (this) { 13346 mBackupTarget = null; 13347 mBackupAppName = null; 13348 } 13349 } 13350 13351 // A backup agent has just come up 13352 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13353 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13354 + " = " + agent); 13355 13356 synchronized(this) { 13357 if (!agentPackageName.equals(mBackupAppName)) { 13358 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13359 return; 13360 } 13361 } 13362 13363 long oldIdent = Binder.clearCallingIdentity(); 13364 try { 13365 IBackupManager bm = IBackupManager.Stub.asInterface( 13366 ServiceManager.getService(Context.BACKUP_SERVICE)); 13367 bm.agentConnected(agentPackageName, agent); 13368 } catch (RemoteException e) { 13369 // can't happen; the backup manager service is local 13370 } catch (Exception e) { 13371 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13372 e.printStackTrace(); 13373 } finally { 13374 Binder.restoreCallingIdentity(oldIdent); 13375 } 13376 } 13377 13378 // done with this agent 13379 public void unbindBackupAgent(ApplicationInfo appInfo) { 13380 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13381 if (appInfo == null) { 13382 Slog.w(TAG, "unbind backup agent for null app"); 13383 return; 13384 } 13385 13386 synchronized(this) { 13387 try { 13388 if (mBackupAppName == null) { 13389 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13390 return; 13391 } 13392 13393 if (!mBackupAppName.equals(appInfo.packageName)) { 13394 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13395 return; 13396 } 13397 13398 // Not backing this app up any more; reset its OOM adjustment 13399 final ProcessRecord proc = mBackupTarget.app; 13400 updateOomAdjLocked(proc); 13401 13402 // If the app crashed during backup, 'thread' will be null here 13403 if (proc.thread != null) { 13404 try { 13405 proc.thread.scheduleDestroyBackupAgent(appInfo, 13406 compatibilityInfoForPackageLocked(appInfo)); 13407 } catch (Exception e) { 13408 Slog.e(TAG, "Exception when unbinding backup agent:"); 13409 e.printStackTrace(); 13410 } 13411 } 13412 } finally { 13413 mBackupTarget = null; 13414 mBackupAppName = null; 13415 } 13416 } 13417 } 13418 // ========================================================= 13419 // BROADCASTS 13420 // ========================================================= 13421 13422 private final List getStickiesLocked(String action, IntentFilter filter, 13423 List cur, int userId) { 13424 final ContentResolver resolver = mContext.getContentResolver(); 13425 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13426 if (stickies == null) { 13427 return cur; 13428 } 13429 final ArrayList<Intent> list = stickies.get(action); 13430 if (list == null) { 13431 return cur; 13432 } 13433 int N = list.size(); 13434 for (int i=0; i<N; i++) { 13435 Intent intent = list.get(i); 13436 if (filter.match(resolver, intent, true, TAG) >= 0) { 13437 if (cur == null) { 13438 cur = new ArrayList<Intent>(); 13439 } 13440 cur.add(intent); 13441 } 13442 } 13443 return cur; 13444 } 13445 13446 boolean isPendingBroadcastProcessLocked(int pid) { 13447 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13448 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13449 } 13450 13451 void skipPendingBroadcastLocked(int pid) { 13452 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13453 for (BroadcastQueue queue : mBroadcastQueues) { 13454 queue.skipPendingBroadcastLocked(pid); 13455 } 13456 } 13457 13458 // The app just attached; send any pending broadcasts that it should receive 13459 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13460 boolean didSomething = false; 13461 for (BroadcastQueue queue : mBroadcastQueues) { 13462 didSomething |= queue.sendPendingBroadcastsLocked(app); 13463 } 13464 return didSomething; 13465 } 13466 13467 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13468 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13469 enforceNotIsolatedCaller("registerReceiver"); 13470 int callingUid; 13471 int callingPid; 13472 synchronized(this) { 13473 ProcessRecord callerApp = null; 13474 if (caller != null) { 13475 callerApp = getRecordForAppLocked(caller); 13476 if (callerApp == null) { 13477 throw new SecurityException( 13478 "Unable to find app for caller " + caller 13479 + " (pid=" + Binder.getCallingPid() 13480 + ") when registering receiver " + receiver); 13481 } 13482 if (callerApp.info.uid != Process.SYSTEM_UID && 13483 !callerApp.pkgList.containsKey(callerPackage) && 13484 !"android".equals(callerPackage)) { 13485 throw new SecurityException("Given caller package " + callerPackage 13486 + " is not running in process " + callerApp); 13487 } 13488 callingUid = callerApp.info.uid; 13489 callingPid = callerApp.pid; 13490 } else { 13491 callerPackage = null; 13492 callingUid = Binder.getCallingUid(); 13493 callingPid = Binder.getCallingPid(); 13494 } 13495 13496 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13497 true, true, "registerReceiver", callerPackage); 13498 13499 List allSticky = null; 13500 13501 // Look for any matching sticky broadcasts... 13502 Iterator actions = filter.actionsIterator(); 13503 if (actions != null) { 13504 while (actions.hasNext()) { 13505 String action = (String)actions.next(); 13506 allSticky = getStickiesLocked(action, filter, allSticky, 13507 UserHandle.USER_ALL); 13508 allSticky = getStickiesLocked(action, filter, allSticky, 13509 UserHandle.getUserId(callingUid)); 13510 } 13511 } else { 13512 allSticky = getStickiesLocked(null, filter, allSticky, 13513 UserHandle.USER_ALL); 13514 allSticky = getStickiesLocked(null, filter, allSticky, 13515 UserHandle.getUserId(callingUid)); 13516 } 13517 13518 // The first sticky in the list is returned directly back to 13519 // the client. 13520 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13521 13522 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13523 + ": " + sticky); 13524 13525 if (receiver == null) { 13526 return sticky; 13527 } 13528 13529 ReceiverList rl 13530 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13531 if (rl == null) { 13532 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13533 userId, receiver); 13534 if (rl.app != null) { 13535 rl.app.receivers.add(rl); 13536 } else { 13537 try { 13538 receiver.asBinder().linkToDeath(rl, 0); 13539 } catch (RemoteException e) { 13540 return sticky; 13541 } 13542 rl.linkedToDeath = true; 13543 } 13544 mRegisteredReceivers.put(receiver.asBinder(), rl); 13545 } else if (rl.uid != callingUid) { 13546 throw new IllegalArgumentException( 13547 "Receiver requested to register for uid " + callingUid 13548 + " was previously registered for uid " + rl.uid); 13549 } else if (rl.pid != callingPid) { 13550 throw new IllegalArgumentException( 13551 "Receiver requested to register for pid " + callingPid 13552 + " was previously registered for pid " + rl.pid); 13553 } else if (rl.userId != userId) { 13554 throw new IllegalArgumentException( 13555 "Receiver requested to register for user " + userId 13556 + " was previously registered for user " + rl.userId); 13557 } 13558 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13559 permission, callingUid, userId); 13560 rl.add(bf); 13561 if (!bf.debugCheck()) { 13562 Slog.w(TAG, "==> For Dynamic broadast"); 13563 } 13564 mReceiverResolver.addFilter(bf); 13565 13566 // Enqueue broadcasts for all existing stickies that match 13567 // this filter. 13568 if (allSticky != null) { 13569 ArrayList receivers = new ArrayList(); 13570 receivers.add(bf); 13571 13572 int N = allSticky.size(); 13573 for (int i=0; i<N; i++) { 13574 Intent intent = (Intent)allSticky.get(i); 13575 BroadcastQueue queue = broadcastQueueForIntent(intent); 13576 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13577 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13578 null, null, false, true, true, -1); 13579 queue.enqueueParallelBroadcastLocked(r); 13580 queue.scheduleBroadcastsLocked(); 13581 } 13582 } 13583 13584 return sticky; 13585 } 13586 } 13587 13588 public void unregisterReceiver(IIntentReceiver receiver) { 13589 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13590 13591 final long origId = Binder.clearCallingIdentity(); 13592 try { 13593 boolean doTrim = false; 13594 13595 synchronized(this) { 13596 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13597 if (rl != null) { 13598 if (rl.curBroadcast != null) { 13599 BroadcastRecord r = rl.curBroadcast; 13600 final boolean doNext = finishReceiverLocked( 13601 receiver.asBinder(), r.resultCode, r.resultData, 13602 r.resultExtras, r.resultAbort); 13603 if (doNext) { 13604 doTrim = true; 13605 r.queue.processNextBroadcast(false); 13606 } 13607 } 13608 13609 if (rl.app != null) { 13610 rl.app.receivers.remove(rl); 13611 } 13612 removeReceiverLocked(rl); 13613 if (rl.linkedToDeath) { 13614 rl.linkedToDeath = false; 13615 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13616 } 13617 } 13618 } 13619 13620 // If we actually concluded any broadcasts, we might now be able 13621 // to trim the recipients' apps from our working set 13622 if (doTrim) { 13623 trimApplications(); 13624 return; 13625 } 13626 13627 } finally { 13628 Binder.restoreCallingIdentity(origId); 13629 } 13630 } 13631 13632 void removeReceiverLocked(ReceiverList rl) { 13633 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13634 int N = rl.size(); 13635 for (int i=0; i<N; i++) { 13636 mReceiverResolver.removeFilter(rl.get(i)); 13637 } 13638 } 13639 13640 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13641 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13642 ProcessRecord r = mLruProcesses.get(i); 13643 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13644 try { 13645 r.thread.dispatchPackageBroadcast(cmd, packages); 13646 } catch (RemoteException ex) { 13647 } 13648 } 13649 } 13650 } 13651 13652 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13653 int[] users) { 13654 List<ResolveInfo> receivers = null; 13655 try { 13656 HashSet<ComponentName> singleUserReceivers = null; 13657 boolean scannedFirstReceivers = false; 13658 for (int user : users) { 13659 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13660 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13661 if (user != 0 && newReceivers != null) { 13662 // If this is not the primary user, we need to check for 13663 // any receivers that should be filtered out. 13664 for (int i=0; i<newReceivers.size(); i++) { 13665 ResolveInfo ri = newReceivers.get(i); 13666 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13667 newReceivers.remove(i); 13668 i--; 13669 } 13670 } 13671 } 13672 if (newReceivers != null && newReceivers.size() == 0) { 13673 newReceivers = null; 13674 } 13675 if (receivers == null) { 13676 receivers = newReceivers; 13677 } else if (newReceivers != null) { 13678 // We need to concatenate the additional receivers 13679 // found with what we have do far. This would be easy, 13680 // but we also need to de-dup any receivers that are 13681 // singleUser. 13682 if (!scannedFirstReceivers) { 13683 // Collect any single user receivers we had already retrieved. 13684 scannedFirstReceivers = true; 13685 for (int i=0; i<receivers.size(); i++) { 13686 ResolveInfo ri = receivers.get(i); 13687 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13688 ComponentName cn = new ComponentName( 13689 ri.activityInfo.packageName, ri.activityInfo.name); 13690 if (singleUserReceivers == null) { 13691 singleUserReceivers = new HashSet<ComponentName>(); 13692 } 13693 singleUserReceivers.add(cn); 13694 } 13695 } 13696 } 13697 // Add the new results to the existing results, tracking 13698 // and de-dupping single user receivers. 13699 for (int i=0; i<newReceivers.size(); i++) { 13700 ResolveInfo ri = newReceivers.get(i); 13701 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13702 ComponentName cn = new ComponentName( 13703 ri.activityInfo.packageName, ri.activityInfo.name); 13704 if (singleUserReceivers == null) { 13705 singleUserReceivers = new HashSet<ComponentName>(); 13706 } 13707 if (!singleUserReceivers.contains(cn)) { 13708 singleUserReceivers.add(cn); 13709 receivers.add(ri); 13710 } 13711 } else { 13712 receivers.add(ri); 13713 } 13714 } 13715 } 13716 } 13717 } catch (RemoteException ex) { 13718 // pm is in same process, this will never happen. 13719 } 13720 return receivers; 13721 } 13722 13723 private final int broadcastIntentLocked(ProcessRecord callerApp, 13724 String callerPackage, Intent intent, String resolvedType, 13725 IIntentReceiver resultTo, int resultCode, String resultData, 13726 Bundle map, String requiredPermission, int appOp, 13727 boolean ordered, boolean sticky, int callingPid, int callingUid, 13728 int userId) { 13729 intent = new Intent(intent); 13730 13731 // By default broadcasts do not go to stopped apps. 13732 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13733 13734 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13735 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13736 + " ordered=" + ordered + " userid=" + userId); 13737 if ((resultTo != null) && !ordered) { 13738 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13739 } 13740 13741 userId = handleIncomingUser(callingPid, callingUid, userId, 13742 true, false, "broadcast", callerPackage); 13743 13744 // Make sure that the user who is receiving this broadcast is started. 13745 // If not, we will just skip it. 13746 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13747 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13748 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13749 Slog.w(TAG, "Skipping broadcast of " + intent 13750 + ": user " + userId + " is stopped"); 13751 return ActivityManager.BROADCAST_SUCCESS; 13752 } 13753 } 13754 13755 /* 13756 * Prevent non-system code (defined here to be non-persistent 13757 * processes) from sending protected broadcasts. 13758 */ 13759 int callingAppId = UserHandle.getAppId(callingUid); 13760 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13761 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 13762 || callingUid == 0) { 13763 // Always okay. 13764 } else if (callerApp == null || !callerApp.persistent) { 13765 try { 13766 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13767 intent.getAction())) { 13768 String msg = "Permission Denial: not allowed to send broadcast " 13769 + intent.getAction() + " from pid=" 13770 + callingPid + ", uid=" + callingUid; 13771 Slog.w(TAG, msg); 13772 throw new SecurityException(msg); 13773 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13774 // Special case for compatibility: we don't want apps to send this, 13775 // but historically it has not been protected and apps may be using it 13776 // to poke their own app widget. So, instead of making it protected, 13777 // just limit it to the caller. 13778 if (callerApp == null) { 13779 String msg = "Permission Denial: not allowed to send broadcast " 13780 + intent.getAction() + " from unknown caller."; 13781 Slog.w(TAG, msg); 13782 throw new SecurityException(msg); 13783 } else if (intent.getComponent() != null) { 13784 // They are good enough to send to an explicit component... verify 13785 // it is being sent to the calling app. 13786 if (!intent.getComponent().getPackageName().equals( 13787 callerApp.info.packageName)) { 13788 String msg = "Permission Denial: not allowed to send broadcast " 13789 + intent.getAction() + " to " 13790 + intent.getComponent().getPackageName() + " from " 13791 + callerApp.info.packageName; 13792 Slog.w(TAG, msg); 13793 throw new SecurityException(msg); 13794 } 13795 } else { 13796 // Limit broadcast to their own package. 13797 intent.setPackage(callerApp.info.packageName); 13798 } 13799 } 13800 } catch (RemoteException e) { 13801 Slog.w(TAG, "Remote exception", e); 13802 return ActivityManager.BROADCAST_SUCCESS; 13803 } 13804 } 13805 13806 // Handle special intents: if this broadcast is from the package 13807 // manager about a package being removed, we need to remove all of 13808 // its activities from the history stack. 13809 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13810 intent.getAction()); 13811 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13812 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13813 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13814 || uidRemoved) { 13815 if (checkComponentPermission( 13816 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13817 callingPid, callingUid, -1, true) 13818 == PackageManager.PERMISSION_GRANTED) { 13819 if (uidRemoved) { 13820 final Bundle intentExtras = intent.getExtras(); 13821 final int uid = intentExtras != null 13822 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13823 if (uid >= 0) { 13824 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13825 synchronized (bs) { 13826 bs.removeUidStatsLocked(uid); 13827 } 13828 mAppOpsService.uidRemoved(uid); 13829 } 13830 } else { 13831 // If resources are unavailable just force stop all 13832 // those packages and flush the attribute cache as well. 13833 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13834 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13835 if (list != null && (list.length > 0)) { 13836 for (String pkg : list) { 13837 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13838 "storage unmount"); 13839 } 13840 sendPackageBroadcastLocked( 13841 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13842 } 13843 } else { 13844 Uri data = intent.getData(); 13845 String ssp; 13846 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13847 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13848 intent.getAction()); 13849 boolean fullUninstall = removed && 13850 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13851 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13852 forceStopPackageLocked(ssp, UserHandle.getAppId( 13853 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13854 false, fullUninstall, userId, 13855 removed ? "pkg removed" : "pkg changed"); 13856 } 13857 if (removed) { 13858 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13859 new String[] {ssp}, userId); 13860 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13861 mAppOpsService.packageRemoved( 13862 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13863 13864 // Remove all permissions granted from/to this package 13865 removeUriPermissionsForPackageLocked(ssp, userId, true); 13866 } 13867 } 13868 } 13869 } 13870 } 13871 } else { 13872 String msg = "Permission Denial: " + intent.getAction() 13873 + " broadcast from " + callerPackage + " (pid=" + callingPid 13874 + ", uid=" + callingUid + ")" 13875 + " requires " 13876 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13877 Slog.w(TAG, msg); 13878 throw new SecurityException(msg); 13879 } 13880 13881 // Special case for adding a package: by default turn on compatibility 13882 // mode. 13883 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13884 Uri data = intent.getData(); 13885 String ssp; 13886 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13887 mCompatModePackages.handlePackageAddedLocked(ssp, 13888 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13889 } 13890 } 13891 13892 /* 13893 * If this is the time zone changed action, queue up a message that will reset the timezone 13894 * of all currently running processes. This message will get queued up before the broadcast 13895 * happens. 13896 */ 13897 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13898 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13899 } 13900 13901 /* 13902 * If the user set the time, let all running processes know. 13903 */ 13904 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13905 final int is24Hour = intent.getBooleanExtra( 13906 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13907 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13908 } 13909 13910 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13911 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13912 } 13913 13914 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13915 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 13916 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13917 } 13918 13919 // Add to the sticky list if requested. 13920 if (sticky) { 13921 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13922 callingPid, callingUid) 13923 != PackageManager.PERMISSION_GRANTED) { 13924 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13925 + callingPid + ", uid=" + callingUid 13926 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13927 Slog.w(TAG, msg); 13928 throw new SecurityException(msg); 13929 } 13930 if (requiredPermission != null) { 13931 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13932 + " and enforce permission " + requiredPermission); 13933 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13934 } 13935 if (intent.getComponent() != null) { 13936 throw new SecurityException( 13937 "Sticky broadcasts can't target a specific component"); 13938 } 13939 // We use userId directly here, since the "all" target is maintained 13940 // as a separate set of sticky broadcasts. 13941 if (userId != UserHandle.USER_ALL) { 13942 // But first, if this is not a broadcast to all users, then 13943 // make sure it doesn't conflict with an existing broadcast to 13944 // all users. 13945 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13946 UserHandle.USER_ALL); 13947 if (stickies != null) { 13948 ArrayList<Intent> list = stickies.get(intent.getAction()); 13949 if (list != null) { 13950 int N = list.size(); 13951 int i; 13952 for (i=0; i<N; i++) { 13953 if (intent.filterEquals(list.get(i))) { 13954 throw new IllegalArgumentException( 13955 "Sticky broadcast " + intent + " for user " 13956 + userId + " conflicts with existing global broadcast"); 13957 } 13958 } 13959 } 13960 } 13961 } 13962 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13963 if (stickies == null) { 13964 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13965 mStickyBroadcasts.put(userId, stickies); 13966 } 13967 ArrayList<Intent> list = stickies.get(intent.getAction()); 13968 if (list == null) { 13969 list = new ArrayList<Intent>(); 13970 stickies.put(intent.getAction(), list); 13971 } 13972 int N = list.size(); 13973 int i; 13974 for (i=0; i<N; i++) { 13975 if (intent.filterEquals(list.get(i))) { 13976 // This sticky already exists, replace it. 13977 list.set(i, new Intent(intent)); 13978 break; 13979 } 13980 } 13981 if (i >= N) { 13982 list.add(new Intent(intent)); 13983 } 13984 } 13985 13986 int[] users; 13987 if (userId == UserHandle.USER_ALL) { 13988 // Caller wants broadcast to go to all started users. 13989 users = mStartedUserArray; 13990 } else { 13991 // Caller wants broadcast to go to one specific user. 13992 users = new int[] {userId}; 13993 } 13994 13995 // Figure out who all will receive this broadcast. 13996 List receivers = null; 13997 List<BroadcastFilter> registeredReceivers = null; 13998 // Need to resolve the intent to interested receivers... 13999 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 14000 == 0) { 14001 receivers = collectReceiverComponents(intent, resolvedType, users); 14002 } 14003 if (intent.getComponent() == null) { 14004 registeredReceivers = mReceiverResolver.queryIntent(intent, 14005 resolvedType, false, userId); 14006 } 14007 14008 final boolean replacePending = 14009 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 14010 14011 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 14012 + " replacePending=" + replacePending); 14013 14014 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 14015 if (!ordered && NR > 0) { 14016 // If we are not serializing this broadcast, then send the 14017 // registered receivers separately so they don't wait for the 14018 // components to be launched. 14019 final BroadcastQueue queue = broadcastQueueForIntent(intent); 14020 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14021 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 14022 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 14023 ordered, sticky, false, userId); 14024 if (DEBUG_BROADCAST) Slog.v( 14025 TAG, "Enqueueing parallel broadcast " + r); 14026 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 14027 if (!replaced) { 14028 queue.enqueueParallelBroadcastLocked(r); 14029 queue.scheduleBroadcastsLocked(); 14030 } 14031 registeredReceivers = null; 14032 NR = 0; 14033 } 14034 14035 // Merge into one list. 14036 int ir = 0; 14037 if (receivers != null) { 14038 // A special case for PACKAGE_ADDED: do not allow the package 14039 // being added to see this broadcast. This prevents them from 14040 // using this as a back door to get run as soon as they are 14041 // installed. Maybe in the future we want to have a special install 14042 // broadcast or such for apps, but we'd like to deliberately make 14043 // this decision. 14044 String skipPackages[] = null; 14045 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 14046 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 14047 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 14048 Uri data = intent.getData(); 14049 if (data != null) { 14050 String pkgName = data.getSchemeSpecificPart(); 14051 if (pkgName != null) { 14052 skipPackages = new String[] { pkgName }; 14053 } 14054 } 14055 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 14056 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14057 } 14058 if (skipPackages != null && (skipPackages.length > 0)) { 14059 for (String skipPackage : skipPackages) { 14060 if (skipPackage != null) { 14061 int NT = receivers.size(); 14062 for (int it=0; it<NT; it++) { 14063 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14064 if (curt.activityInfo.packageName.equals(skipPackage)) { 14065 receivers.remove(it); 14066 it--; 14067 NT--; 14068 } 14069 } 14070 } 14071 } 14072 } 14073 14074 int NT = receivers != null ? receivers.size() : 0; 14075 int it = 0; 14076 ResolveInfo curt = null; 14077 BroadcastFilter curr = null; 14078 while (it < NT && ir < NR) { 14079 if (curt == null) { 14080 curt = (ResolveInfo)receivers.get(it); 14081 } 14082 if (curr == null) { 14083 curr = registeredReceivers.get(ir); 14084 } 14085 if (curr.getPriority() >= curt.priority) { 14086 // Insert this broadcast record into the final list. 14087 receivers.add(it, curr); 14088 ir++; 14089 curr = null; 14090 it++; 14091 NT++; 14092 } else { 14093 // Skip to the next ResolveInfo in the final list. 14094 it++; 14095 curt = null; 14096 } 14097 } 14098 } 14099 while (ir < NR) { 14100 if (receivers == null) { 14101 receivers = new ArrayList(); 14102 } 14103 receivers.add(registeredReceivers.get(ir)); 14104 ir++; 14105 } 14106 14107 if ((receivers != null && receivers.size() > 0) 14108 || resultTo != null) { 14109 BroadcastQueue queue = broadcastQueueForIntent(intent); 14110 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14111 callerPackage, callingPid, callingUid, resolvedType, 14112 requiredPermission, appOp, receivers, resultTo, resultCode, 14113 resultData, map, ordered, sticky, false, userId); 14114 if (DEBUG_BROADCAST) Slog.v( 14115 TAG, "Enqueueing ordered broadcast " + r 14116 + ": prev had " + queue.mOrderedBroadcasts.size()); 14117 if (DEBUG_BROADCAST) { 14118 int seq = r.intent.getIntExtra("seq", -1); 14119 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14120 } 14121 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14122 if (!replaced) { 14123 queue.enqueueOrderedBroadcastLocked(r); 14124 queue.scheduleBroadcastsLocked(); 14125 } 14126 } 14127 14128 return ActivityManager.BROADCAST_SUCCESS; 14129 } 14130 14131 final Intent verifyBroadcastLocked(Intent intent) { 14132 // Refuse possible leaked file descriptors 14133 if (intent != null && intent.hasFileDescriptors() == true) { 14134 throw new IllegalArgumentException("File descriptors passed in Intent"); 14135 } 14136 14137 int flags = intent.getFlags(); 14138 14139 if (!mProcessesReady) { 14140 // if the caller really truly claims to know what they're doing, go 14141 // ahead and allow the broadcast without launching any receivers 14142 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14143 intent = new Intent(intent); 14144 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14145 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14146 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14147 + " before boot completion"); 14148 throw new IllegalStateException("Cannot broadcast before boot completed"); 14149 } 14150 } 14151 14152 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14153 throw new IllegalArgumentException( 14154 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14155 } 14156 14157 return intent; 14158 } 14159 14160 public final int broadcastIntent(IApplicationThread caller, 14161 Intent intent, String resolvedType, IIntentReceiver resultTo, 14162 int resultCode, String resultData, Bundle map, 14163 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14164 enforceNotIsolatedCaller("broadcastIntent"); 14165 synchronized(this) { 14166 intent = verifyBroadcastLocked(intent); 14167 14168 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14169 final int callingPid = Binder.getCallingPid(); 14170 final int callingUid = Binder.getCallingUid(); 14171 final long origId = Binder.clearCallingIdentity(); 14172 int res = broadcastIntentLocked(callerApp, 14173 callerApp != null ? callerApp.info.packageName : null, 14174 intent, resolvedType, resultTo, 14175 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14176 callingPid, callingUid, userId); 14177 Binder.restoreCallingIdentity(origId); 14178 return res; 14179 } 14180 } 14181 14182 int broadcastIntentInPackage(String packageName, int uid, 14183 Intent intent, String resolvedType, IIntentReceiver resultTo, 14184 int resultCode, String resultData, Bundle map, 14185 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14186 synchronized(this) { 14187 intent = verifyBroadcastLocked(intent); 14188 14189 final long origId = Binder.clearCallingIdentity(); 14190 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14191 resultTo, resultCode, resultData, map, requiredPermission, 14192 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14193 Binder.restoreCallingIdentity(origId); 14194 return res; 14195 } 14196 } 14197 14198 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14199 // Refuse possible leaked file descriptors 14200 if (intent != null && intent.hasFileDescriptors() == true) { 14201 throw new IllegalArgumentException("File descriptors passed in Intent"); 14202 } 14203 14204 userId = handleIncomingUser(Binder.getCallingPid(), 14205 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14206 14207 synchronized(this) { 14208 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14209 != PackageManager.PERMISSION_GRANTED) { 14210 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14211 + Binder.getCallingPid() 14212 + ", uid=" + Binder.getCallingUid() 14213 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14214 Slog.w(TAG, msg); 14215 throw new SecurityException(msg); 14216 } 14217 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14218 if (stickies != null) { 14219 ArrayList<Intent> list = stickies.get(intent.getAction()); 14220 if (list != null) { 14221 int N = list.size(); 14222 int i; 14223 for (i=0; i<N; i++) { 14224 if (intent.filterEquals(list.get(i))) { 14225 list.remove(i); 14226 break; 14227 } 14228 } 14229 if (list.size() <= 0) { 14230 stickies.remove(intent.getAction()); 14231 } 14232 } 14233 if (stickies.size() <= 0) { 14234 mStickyBroadcasts.remove(userId); 14235 } 14236 } 14237 } 14238 } 14239 14240 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14241 String resultData, Bundle resultExtras, boolean resultAbort) { 14242 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14243 if (r == null) { 14244 Slog.w(TAG, "finishReceiver called but not found on queue"); 14245 return false; 14246 } 14247 14248 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14249 } 14250 14251 void backgroundServicesFinishedLocked(int userId) { 14252 for (BroadcastQueue queue : mBroadcastQueues) { 14253 queue.backgroundServicesFinishedLocked(userId); 14254 } 14255 } 14256 14257 public void finishReceiver(IBinder who, int resultCode, String resultData, 14258 Bundle resultExtras, boolean resultAbort) { 14259 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14260 14261 // Refuse possible leaked file descriptors 14262 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14263 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14264 } 14265 14266 final long origId = Binder.clearCallingIdentity(); 14267 try { 14268 boolean doNext = false; 14269 BroadcastRecord r; 14270 14271 synchronized(this) { 14272 r = broadcastRecordForReceiverLocked(who); 14273 if (r != null) { 14274 doNext = r.queue.finishReceiverLocked(r, resultCode, 14275 resultData, resultExtras, resultAbort, true); 14276 } 14277 } 14278 14279 if (doNext) { 14280 r.queue.processNextBroadcast(false); 14281 } 14282 trimApplications(); 14283 } finally { 14284 Binder.restoreCallingIdentity(origId); 14285 } 14286 } 14287 14288 // ========================================================= 14289 // INSTRUMENTATION 14290 // ========================================================= 14291 14292 public boolean startInstrumentation(ComponentName className, 14293 String profileFile, int flags, Bundle arguments, 14294 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14295 int userId) { 14296 enforceNotIsolatedCaller("startInstrumentation"); 14297 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14298 userId, false, true, "startInstrumentation", null); 14299 // Refuse possible leaked file descriptors 14300 if (arguments != null && arguments.hasFileDescriptors()) { 14301 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14302 } 14303 14304 synchronized(this) { 14305 InstrumentationInfo ii = null; 14306 ApplicationInfo ai = null; 14307 try { 14308 ii = mContext.getPackageManager().getInstrumentationInfo( 14309 className, STOCK_PM_FLAGS); 14310 ai = AppGlobals.getPackageManager().getApplicationInfo( 14311 ii.targetPackage, STOCK_PM_FLAGS, userId); 14312 } catch (PackageManager.NameNotFoundException e) { 14313 } catch (RemoteException e) { 14314 } 14315 if (ii == null) { 14316 reportStartInstrumentationFailure(watcher, className, 14317 "Unable to find instrumentation info for: " + className); 14318 return false; 14319 } 14320 if (ai == null) { 14321 reportStartInstrumentationFailure(watcher, className, 14322 "Unable to find instrumentation target package: " + ii.targetPackage); 14323 return false; 14324 } 14325 14326 int match = mContext.getPackageManager().checkSignatures( 14327 ii.targetPackage, ii.packageName); 14328 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14329 String msg = "Permission Denial: starting instrumentation " 14330 + className + " from pid=" 14331 + Binder.getCallingPid() 14332 + ", uid=" + Binder.getCallingPid() 14333 + " not allowed because package " + ii.packageName 14334 + " does not have a signature matching the target " 14335 + ii.targetPackage; 14336 reportStartInstrumentationFailure(watcher, className, msg); 14337 throw new SecurityException(msg); 14338 } 14339 14340 final long origId = Binder.clearCallingIdentity(); 14341 // Instrumentation can kill and relaunch even persistent processes 14342 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14343 "start instr"); 14344 ProcessRecord app = addAppLocked(ai, false); 14345 app.instrumentationClass = className; 14346 app.instrumentationInfo = ai; 14347 app.instrumentationProfileFile = profileFile; 14348 app.instrumentationArguments = arguments; 14349 app.instrumentationWatcher = watcher; 14350 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14351 app.instrumentationResultClass = className; 14352 Binder.restoreCallingIdentity(origId); 14353 } 14354 14355 return true; 14356 } 14357 14358 /** 14359 * Report errors that occur while attempting to start Instrumentation. Always writes the 14360 * error to the logs, but if somebody is watching, send the report there too. This enables 14361 * the "am" command to report errors with more information. 14362 * 14363 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14364 * @param cn The component name of the instrumentation. 14365 * @param report The error report. 14366 */ 14367 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14368 ComponentName cn, String report) { 14369 Slog.w(TAG, report); 14370 try { 14371 if (watcher != null) { 14372 Bundle results = new Bundle(); 14373 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14374 results.putString("Error", report); 14375 watcher.instrumentationStatus(cn, -1, results); 14376 } 14377 } catch (RemoteException e) { 14378 Slog.w(TAG, e); 14379 } 14380 } 14381 14382 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14383 if (app.instrumentationWatcher != null) { 14384 try { 14385 // NOTE: IInstrumentationWatcher *must* be oneway here 14386 app.instrumentationWatcher.instrumentationFinished( 14387 app.instrumentationClass, 14388 resultCode, 14389 results); 14390 } catch (RemoteException e) { 14391 } 14392 } 14393 if (app.instrumentationUiAutomationConnection != null) { 14394 try { 14395 app.instrumentationUiAutomationConnection.shutdown(); 14396 } catch (RemoteException re) { 14397 /* ignore */ 14398 } 14399 // Only a UiAutomation can set this flag and now that 14400 // it is finished we make sure it is reset to its default. 14401 mUserIsMonkey = false; 14402 } 14403 app.instrumentationWatcher = null; 14404 app.instrumentationUiAutomationConnection = null; 14405 app.instrumentationClass = null; 14406 app.instrumentationInfo = null; 14407 app.instrumentationProfileFile = null; 14408 app.instrumentationArguments = null; 14409 14410 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14411 "finished inst"); 14412 } 14413 14414 public void finishInstrumentation(IApplicationThread target, 14415 int resultCode, Bundle results) { 14416 int userId = UserHandle.getCallingUserId(); 14417 // Refuse possible leaked file descriptors 14418 if (results != null && results.hasFileDescriptors()) { 14419 throw new IllegalArgumentException("File descriptors passed in Intent"); 14420 } 14421 14422 synchronized(this) { 14423 ProcessRecord app = getRecordForAppLocked(target); 14424 if (app == null) { 14425 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14426 return; 14427 } 14428 final long origId = Binder.clearCallingIdentity(); 14429 finishInstrumentationLocked(app, resultCode, results); 14430 Binder.restoreCallingIdentity(origId); 14431 } 14432 } 14433 14434 // ========================================================= 14435 // CONFIGURATION 14436 // ========================================================= 14437 14438 public ConfigurationInfo getDeviceConfigurationInfo() { 14439 ConfigurationInfo config = new ConfigurationInfo(); 14440 synchronized (this) { 14441 config.reqTouchScreen = mConfiguration.touchscreen; 14442 config.reqKeyboardType = mConfiguration.keyboard; 14443 config.reqNavigation = mConfiguration.navigation; 14444 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14445 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14446 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14447 } 14448 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14449 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14450 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14451 } 14452 config.reqGlEsVersion = GL_ES_VERSION; 14453 } 14454 return config; 14455 } 14456 14457 ActivityStack getFocusedStack() { 14458 return mStackSupervisor.getFocusedStack(); 14459 } 14460 14461 public Configuration getConfiguration() { 14462 Configuration ci; 14463 synchronized(this) { 14464 ci = new Configuration(mConfiguration); 14465 } 14466 return ci; 14467 } 14468 14469 public void updatePersistentConfiguration(Configuration values) { 14470 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14471 "updateConfiguration()"); 14472 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14473 "updateConfiguration()"); 14474 if (values == null) { 14475 throw new NullPointerException("Configuration must not be null"); 14476 } 14477 14478 synchronized(this) { 14479 final long origId = Binder.clearCallingIdentity(); 14480 updateConfigurationLocked(values, null, true, false); 14481 Binder.restoreCallingIdentity(origId); 14482 } 14483 } 14484 14485 public void updateConfiguration(Configuration values) { 14486 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14487 "updateConfiguration()"); 14488 14489 synchronized(this) { 14490 if (values == null && mWindowManager != null) { 14491 // sentinel: fetch the current configuration from the window manager 14492 values = mWindowManager.computeNewConfiguration(); 14493 } 14494 14495 if (mWindowManager != null) { 14496 mProcessList.applyDisplaySize(mWindowManager); 14497 } 14498 14499 final long origId = Binder.clearCallingIdentity(); 14500 if (values != null) { 14501 Settings.System.clearConfiguration(values); 14502 } 14503 updateConfigurationLocked(values, null, false, false); 14504 Binder.restoreCallingIdentity(origId); 14505 } 14506 } 14507 14508 /** 14509 * Do either or both things: (1) change the current configuration, and (2) 14510 * make sure the given activity is running with the (now) current 14511 * configuration. Returns true if the activity has been left running, or 14512 * false if <var>starting</var> is being destroyed to match the new 14513 * configuration. 14514 * @param persistent TODO 14515 */ 14516 boolean updateConfigurationLocked(Configuration values, 14517 ActivityRecord starting, boolean persistent, boolean initLocale) { 14518 int changes = 0; 14519 14520 if (values != null) { 14521 Configuration newConfig = new Configuration(mConfiguration); 14522 changes = newConfig.updateFrom(values); 14523 if (changes != 0) { 14524 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14525 Slog.i(TAG, "Updating configuration to: " + values); 14526 } 14527 14528 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14529 14530 if (values.locale != null && !initLocale) { 14531 saveLocaleLocked(values.locale, 14532 !values.locale.equals(mConfiguration.locale), 14533 values.userSetLocale); 14534 } 14535 14536 mConfigurationSeq++; 14537 if (mConfigurationSeq <= 0) { 14538 mConfigurationSeq = 1; 14539 } 14540 newConfig.seq = mConfigurationSeq; 14541 mConfiguration = newConfig; 14542 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14543 mUsageStatsService.noteStartConfig(newConfig); 14544 14545 final Configuration configCopy = new Configuration(mConfiguration); 14546 14547 // TODO: If our config changes, should we auto dismiss any currently 14548 // showing dialogs? 14549 mShowDialogs = shouldShowDialogs(newConfig); 14550 14551 AttributeCache ac = AttributeCache.instance(); 14552 if (ac != null) { 14553 ac.updateConfiguration(configCopy); 14554 } 14555 14556 // Make sure all resources in our process are updated 14557 // right now, so that anyone who is going to retrieve 14558 // resource values after we return will be sure to get 14559 // the new ones. This is especially important during 14560 // boot, where the first config change needs to guarantee 14561 // all resources have that config before following boot 14562 // code is executed. 14563 mSystemThread.applyConfigurationToResources(configCopy); 14564 14565 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14566 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14567 msg.obj = new Configuration(configCopy); 14568 mHandler.sendMessage(msg); 14569 } 14570 14571 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14572 ProcessRecord app = mLruProcesses.get(i); 14573 try { 14574 if (app.thread != null) { 14575 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14576 + app.processName + " new config " + mConfiguration); 14577 app.thread.scheduleConfigurationChanged(configCopy); 14578 } 14579 } catch (Exception e) { 14580 } 14581 } 14582 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14583 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14584 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14585 | Intent.FLAG_RECEIVER_FOREGROUND); 14586 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14587 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14588 Process.SYSTEM_UID, UserHandle.USER_ALL); 14589 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14590 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14591 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14592 broadcastIntentLocked(null, null, intent, 14593 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14594 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14595 } 14596 } 14597 } 14598 14599 boolean kept = true; 14600 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14601 // mainStack is null during startup. 14602 if (mainStack != null) { 14603 if (changes != 0 && starting == null) { 14604 // If the configuration changed, and the caller is not already 14605 // in the process of starting an activity, then find the top 14606 // activity to check if its configuration needs to change. 14607 starting = mainStack.topRunningActivityLocked(null); 14608 } 14609 14610 if (starting != null) { 14611 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14612 // And we need to make sure at this point that all other activities 14613 // are made visible with the correct configuration. 14614 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14615 } 14616 } 14617 14618 if (values != null && mWindowManager != null) { 14619 mWindowManager.setNewConfiguration(mConfiguration); 14620 } 14621 14622 return kept; 14623 } 14624 14625 /** 14626 * Decide based on the configuration whether we should shouw the ANR, 14627 * crash, etc dialogs. The idea is that if there is no affordnace to 14628 * press the on-screen buttons, we shouldn't show the dialog. 14629 * 14630 * A thought: SystemUI might also want to get told about this, the Power 14631 * dialog / global actions also might want different behaviors. 14632 */ 14633 private static final boolean shouldShowDialogs(Configuration config) { 14634 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14635 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14636 } 14637 14638 /** 14639 * Save the locale. You must be inside a synchronized (this) block. 14640 */ 14641 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14642 if(isDiff) { 14643 SystemProperties.set("user.language", l.getLanguage()); 14644 SystemProperties.set("user.region", l.getCountry()); 14645 } 14646 14647 if(isPersist) { 14648 SystemProperties.set("persist.sys.language", l.getLanguage()); 14649 SystemProperties.set("persist.sys.country", l.getCountry()); 14650 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14651 } 14652 } 14653 14654 @Override 14655 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14656 ActivityRecord srec = ActivityRecord.forToken(token); 14657 return srec != null && srec.task.affinity != null && 14658 srec.task.affinity.equals(destAffinity); 14659 } 14660 14661 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14662 Intent resultData) { 14663 14664 synchronized (this) { 14665 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14666 if (stack != null) { 14667 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14668 } 14669 return false; 14670 } 14671 } 14672 14673 public int getLaunchedFromUid(IBinder activityToken) { 14674 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14675 if (srec == null) { 14676 return -1; 14677 } 14678 return srec.launchedFromUid; 14679 } 14680 14681 public String getLaunchedFromPackage(IBinder activityToken) { 14682 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14683 if (srec == null) { 14684 return null; 14685 } 14686 return srec.launchedFromPackage; 14687 } 14688 14689 // ========================================================= 14690 // LIFETIME MANAGEMENT 14691 // ========================================================= 14692 14693 // Returns which broadcast queue the app is the current [or imminent] receiver 14694 // on, or 'null' if the app is not an active broadcast recipient. 14695 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14696 BroadcastRecord r = app.curReceiver; 14697 if (r != null) { 14698 return r.queue; 14699 } 14700 14701 // It's not the current receiver, but it might be starting up to become one 14702 synchronized (this) { 14703 for (BroadcastQueue queue : mBroadcastQueues) { 14704 r = queue.mPendingBroadcast; 14705 if (r != null && r.curApp == app) { 14706 // found it; report which queue it's in 14707 return queue; 14708 } 14709 } 14710 } 14711 14712 return null; 14713 } 14714 14715 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14716 boolean doingAll, long now) { 14717 if (mAdjSeq == app.adjSeq) { 14718 // This adjustment has already been computed. 14719 return app.curRawAdj; 14720 } 14721 14722 if (app.thread == null) { 14723 app.adjSeq = mAdjSeq; 14724 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14725 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14726 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14727 } 14728 14729 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14730 app.adjSource = null; 14731 app.adjTarget = null; 14732 app.empty = false; 14733 app.cached = false; 14734 14735 final int activitiesSize = app.activities.size(); 14736 14737 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14738 // The max adjustment doesn't allow this app to be anything 14739 // below foreground, so it is not worth doing work for it. 14740 app.adjType = "fixed"; 14741 app.adjSeq = mAdjSeq; 14742 app.curRawAdj = app.maxAdj; 14743 app.foregroundActivities = false; 14744 app.keeping = true; 14745 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14746 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14747 // System processes can do UI, and when they do we want to have 14748 // them trim their memory after the user leaves the UI. To 14749 // facilitate this, here we need to determine whether or not it 14750 // is currently showing UI. 14751 app.systemNoUi = true; 14752 if (app == TOP_APP) { 14753 app.systemNoUi = false; 14754 } else if (activitiesSize > 0) { 14755 for (int j = 0; j < activitiesSize; j++) { 14756 final ActivityRecord r = app.activities.get(j); 14757 if (r.visible) { 14758 app.systemNoUi = false; 14759 } 14760 } 14761 } 14762 if (!app.systemNoUi) { 14763 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14764 } 14765 return (app.curAdj=app.maxAdj); 14766 } 14767 14768 app.keeping = false; 14769 app.systemNoUi = false; 14770 14771 // Determine the importance of the process, starting with most 14772 // important to least, and assign an appropriate OOM adjustment. 14773 int adj; 14774 int schedGroup; 14775 int procState; 14776 boolean foregroundActivities = false; 14777 boolean interesting = false; 14778 BroadcastQueue queue; 14779 if (app == TOP_APP) { 14780 // The last app on the list is the foreground app. 14781 adj = ProcessList.FOREGROUND_APP_ADJ; 14782 schedGroup = Process.THREAD_GROUP_DEFAULT; 14783 app.adjType = "top-activity"; 14784 foregroundActivities = true; 14785 interesting = true; 14786 procState = ActivityManager.PROCESS_STATE_TOP; 14787 } else if (app.instrumentationClass != null) { 14788 // Don't want to kill running instrumentation. 14789 adj = ProcessList.FOREGROUND_APP_ADJ; 14790 schedGroup = Process.THREAD_GROUP_DEFAULT; 14791 app.adjType = "instrumentation"; 14792 interesting = true; 14793 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14794 } else if ((queue = isReceivingBroadcast(app)) != null) { 14795 // An app that is currently receiving a broadcast also 14796 // counts as being in the foreground for OOM killer purposes. 14797 // It's placed in a sched group based on the nature of the 14798 // broadcast as reflected by which queue it's active in. 14799 adj = ProcessList.FOREGROUND_APP_ADJ; 14800 schedGroup = (queue == mFgBroadcastQueue) 14801 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14802 app.adjType = "broadcast"; 14803 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14804 } else if (app.executingServices.size() > 0) { 14805 // An app that is currently executing a service callback also 14806 // counts as being in the foreground. 14807 adj = ProcessList.FOREGROUND_APP_ADJ; 14808 schedGroup = app.execServicesFg ? 14809 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14810 app.adjType = "exec-service"; 14811 procState = ActivityManager.PROCESS_STATE_SERVICE; 14812 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14813 } else { 14814 // As far as we know the process is empty. We may change our mind later. 14815 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14816 // At this point we don't actually know the adjustment. Use the cached adj 14817 // value that the caller wants us to. 14818 adj = cachedAdj; 14819 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14820 app.cached = true; 14821 app.empty = true; 14822 app.adjType = "cch-empty"; 14823 } 14824 14825 // Examine all activities if not already foreground. 14826 if (!foregroundActivities && activitiesSize > 0) { 14827 for (int j = 0; j < activitiesSize; j++) { 14828 final ActivityRecord r = app.activities.get(j); 14829 if (r.app != app) { 14830 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14831 + app + "?!?"); 14832 continue; 14833 } 14834 if (r.visible) { 14835 // App has a visible activity; only upgrade adjustment. 14836 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14837 adj = ProcessList.VISIBLE_APP_ADJ; 14838 app.adjType = "visible"; 14839 } 14840 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14841 procState = ActivityManager.PROCESS_STATE_TOP; 14842 } 14843 schedGroup = Process.THREAD_GROUP_DEFAULT; 14844 app.cached = false; 14845 app.empty = false; 14846 foregroundActivities = true; 14847 break; 14848 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14849 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14850 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14851 app.adjType = "pausing"; 14852 } 14853 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14854 procState = ActivityManager.PROCESS_STATE_TOP; 14855 } 14856 schedGroup = Process.THREAD_GROUP_DEFAULT; 14857 app.cached = false; 14858 app.empty = false; 14859 foregroundActivities = true; 14860 } else if (r.state == ActivityState.STOPPING) { 14861 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14862 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14863 app.adjType = "stopping"; 14864 } 14865 // For the process state, we will at this point consider the 14866 // process to be cached. It will be cached either as an activity 14867 // or empty depending on whether the activity is finishing. We do 14868 // this so that we can treat the process as cached for purposes of 14869 // memory trimming (determing current memory level, trim command to 14870 // send to process) since there can be an arbitrary number of stopping 14871 // processes and they should soon all go into the cached state. 14872 if (!r.finishing) { 14873 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14874 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14875 } 14876 } 14877 app.cached = false; 14878 app.empty = false; 14879 foregroundActivities = true; 14880 } else { 14881 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14882 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14883 app.adjType = "cch-act"; 14884 } 14885 } 14886 } 14887 } 14888 14889 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14890 if (app.foregroundServices) { 14891 // The user is aware of this app, so make it visible. 14892 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14893 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14894 app.cached = false; 14895 app.adjType = "fg-service"; 14896 schedGroup = Process.THREAD_GROUP_DEFAULT; 14897 } else if (app.forcingToForeground != null) { 14898 // The user is aware of this app, so make it visible. 14899 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14900 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14901 app.cached = false; 14902 app.adjType = "force-fg"; 14903 app.adjSource = app.forcingToForeground; 14904 schedGroup = Process.THREAD_GROUP_DEFAULT; 14905 } 14906 } 14907 14908 if (app.foregroundServices) { 14909 interesting = true; 14910 } 14911 14912 if (app == mHeavyWeightProcess) { 14913 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14914 // We don't want to kill the current heavy-weight process. 14915 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14916 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14917 app.cached = false; 14918 app.adjType = "heavy"; 14919 } 14920 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14921 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14922 } 14923 } 14924 14925 if (app == mHomeProcess) { 14926 if (adj > ProcessList.HOME_APP_ADJ) { 14927 // This process is hosting what we currently consider to be the 14928 // home app, so we don't want to let it go into the background. 14929 adj = ProcessList.HOME_APP_ADJ; 14930 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14931 app.cached = false; 14932 app.adjType = "home"; 14933 } 14934 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14935 procState = ActivityManager.PROCESS_STATE_HOME; 14936 } 14937 } 14938 14939 if (app == mPreviousProcess && app.activities.size() > 0) { 14940 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14941 // This was the previous process that showed UI to the user. 14942 // We want to try to keep it around more aggressively, to give 14943 // a good experience around switching between two apps. 14944 adj = ProcessList.PREVIOUS_APP_ADJ; 14945 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14946 app.cached = false; 14947 app.adjType = "previous"; 14948 } 14949 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14950 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14951 } 14952 } 14953 14954 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14955 + " reason=" + app.adjType); 14956 14957 // By default, we use the computed adjustment. It may be changed if 14958 // there are applications dependent on our services or providers, but 14959 // this gives us a baseline and makes sure we don't get into an 14960 // infinite recursion. 14961 app.adjSeq = mAdjSeq; 14962 app.curRawAdj = adj; 14963 app.hasStartedServices = false; 14964 14965 if (mBackupTarget != null && app == mBackupTarget.app) { 14966 // If possible we want to avoid killing apps while they're being backed up 14967 if (adj > ProcessList.BACKUP_APP_ADJ) { 14968 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14969 adj = ProcessList.BACKUP_APP_ADJ; 14970 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14971 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14972 } 14973 app.adjType = "backup"; 14974 app.cached = false; 14975 } 14976 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14977 procState = ActivityManager.PROCESS_STATE_BACKUP; 14978 } 14979 } 14980 14981 boolean mayBeTop = false; 14982 14983 for (int is = app.services.size()-1; 14984 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14985 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14986 || procState > ActivityManager.PROCESS_STATE_TOP); 14987 is--) { 14988 ServiceRecord s = app.services.valueAt(is); 14989 if (s.startRequested) { 14990 app.hasStartedServices = true; 14991 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14992 procState = ActivityManager.PROCESS_STATE_SERVICE; 14993 } 14994 if (app.hasShownUi && app != mHomeProcess) { 14995 // If this process has shown some UI, let it immediately 14996 // go to the LRU list because it may be pretty heavy with 14997 // UI stuff. We'll tag it with a label just to help 14998 // debug and understand what is going on. 14999 if (adj > ProcessList.SERVICE_ADJ) { 15000 app.adjType = "cch-started-ui-services"; 15001 } 15002 } else { 15003 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15004 // This service has seen some activity within 15005 // recent memory, so we will keep its process ahead 15006 // of the background processes. 15007 if (adj > ProcessList.SERVICE_ADJ) { 15008 adj = ProcessList.SERVICE_ADJ; 15009 app.adjType = "started-services"; 15010 app.cached = false; 15011 } 15012 } 15013 // If we have let the service slide into the background 15014 // state, still have some text describing what it is doing 15015 // even though the service no longer has an impact. 15016 if (adj > ProcessList.SERVICE_ADJ) { 15017 app.adjType = "cch-started-services"; 15018 } 15019 } 15020 // Don't kill this process because it is doing work; it 15021 // has said it is doing work. 15022 app.keeping = true; 15023 } 15024 for (int conni = s.connections.size()-1; 15025 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15026 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15027 || procState > ActivityManager.PROCESS_STATE_TOP); 15028 conni--) { 15029 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 15030 for (int i = 0; 15031 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 15032 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15033 || procState > ActivityManager.PROCESS_STATE_TOP); 15034 i++) { 15035 // XXX should compute this based on the max of 15036 // all connected clients. 15037 ConnectionRecord cr = clist.get(i); 15038 if (cr.binding.client == app) { 15039 // Binding to ourself is not interesting. 15040 continue; 15041 } 15042 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 15043 ProcessRecord client = cr.binding.client; 15044 int clientAdj = computeOomAdjLocked(client, cachedAdj, 15045 TOP_APP, doingAll, now); 15046 int clientProcState = client.curProcState; 15047 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15048 // If the other app is cached for any reason, for purposes here 15049 // we are going to consider it empty. The specific cached state 15050 // doesn't propagate except under certain conditions. 15051 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15052 } 15053 String adjType = null; 15054 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 15055 // Not doing bind OOM management, so treat 15056 // this guy more like a started service. 15057 if (app.hasShownUi && app != mHomeProcess) { 15058 // If this process has shown some UI, let it immediately 15059 // go to the LRU list because it may be pretty heavy with 15060 // UI stuff. We'll tag it with a label just to help 15061 // debug and understand what is going on. 15062 if (adj > clientAdj) { 15063 adjType = "cch-bound-ui-services"; 15064 } 15065 app.cached = false; 15066 clientAdj = adj; 15067 clientProcState = procState; 15068 } else { 15069 if (now >= (s.lastActivity 15070 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15071 // This service has not seen activity within 15072 // recent memory, so allow it to drop to the 15073 // LRU list if there is no other reason to keep 15074 // it around. We'll also tag it with a label just 15075 // to help debug and undertand what is going on. 15076 if (adj > clientAdj) { 15077 adjType = "cch-bound-services"; 15078 } 15079 clientAdj = adj; 15080 } 15081 } 15082 } 15083 if (adj > clientAdj) { 15084 // If this process has recently shown UI, and 15085 // the process that is binding to it is less 15086 // important than being visible, then we don't 15087 // care about the binding as much as we care 15088 // about letting this process get into the LRU 15089 // list to be killed and restarted if needed for 15090 // memory. 15091 if (app.hasShownUi && app != mHomeProcess 15092 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15093 adjType = "cch-bound-ui-services"; 15094 } else { 15095 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15096 |Context.BIND_IMPORTANT)) != 0) { 15097 adj = clientAdj; 15098 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15099 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15100 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15101 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15102 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15103 adj = clientAdj; 15104 } else { 15105 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15106 adj = ProcessList.VISIBLE_APP_ADJ; 15107 } 15108 } 15109 if (!client.cached) { 15110 app.cached = false; 15111 } 15112 if (client.keeping) { 15113 app.keeping = true; 15114 } 15115 adjType = "service"; 15116 } 15117 } 15118 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15119 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15120 schedGroup = Process.THREAD_GROUP_DEFAULT; 15121 } 15122 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15123 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15124 // Special handling of clients who are in the top state. 15125 // We *may* want to consider this process to be in the 15126 // top state as well, but only if there is not another 15127 // reason for it to be running. Being on the top is a 15128 // special state, meaning you are specifically running 15129 // for the current top app. If the process is already 15130 // running in the background for some other reason, it 15131 // is more important to continue considering it to be 15132 // in the background state. 15133 mayBeTop = true; 15134 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15135 } else { 15136 // Special handling for above-top states (persistent 15137 // processes). These should not bring the current process 15138 // into the top state, since they are not on top. Instead 15139 // give them the best state after that. 15140 clientProcState = 15141 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15142 } 15143 } 15144 } else { 15145 if (clientProcState < 15146 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15147 clientProcState = 15148 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15149 } 15150 } 15151 if (procState > clientProcState) { 15152 procState = clientProcState; 15153 } 15154 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15155 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15156 app.pendingUiClean = true; 15157 } 15158 if (adjType != null) { 15159 app.adjType = adjType; 15160 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15161 .REASON_SERVICE_IN_USE; 15162 app.adjSource = cr.binding.client; 15163 app.adjSourceOom = clientAdj; 15164 app.adjTarget = s.name; 15165 } 15166 } 15167 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15168 app.treatLikeActivity = true; 15169 } 15170 final ActivityRecord a = cr.activity; 15171 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15172 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15173 (a.visible || a.state == ActivityState.RESUMED 15174 || a.state == ActivityState.PAUSING)) { 15175 adj = ProcessList.FOREGROUND_APP_ADJ; 15176 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15177 schedGroup = Process.THREAD_GROUP_DEFAULT; 15178 } 15179 app.cached = false; 15180 app.adjType = "service"; 15181 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15182 .REASON_SERVICE_IN_USE; 15183 app.adjSource = a; 15184 app.adjSourceOom = adj; 15185 app.adjTarget = s.name; 15186 } 15187 } 15188 } 15189 } 15190 } 15191 15192 for (int provi = app.pubProviders.size()-1; 15193 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15194 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15195 || procState > ActivityManager.PROCESS_STATE_TOP); 15196 provi--) { 15197 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15198 for (int i = cpr.connections.size()-1; 15199 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15200 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15201 || procState > ActivityManager.PROCESS_STATE_TOP); 15202 i--) { 15203 ContentProviderConnection conn = cpr.connections.get(i); 15204 ProcessRecord client = conn.client; 15205 if (client == app) { 15206 // Being our own client is not interesting. 15207 continue; 15208 } 15209 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15210 int clientProcState = client.curProcState; 15211 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15212 // If the other app is cached for any reason, for purposes here 15213 // we are going to consider it empty. 15214 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15215 } 15216 if (adj > clientAdj) { 15217 if (app.hasShownUi && app != mHomeProcess 15218 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15219 app.adjType = "cch-ui-provider"; 15220 } else { 15221 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15222 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15223 app.adjType = "provider"; 15224 } 15225 app.cached &= client.cached; 15226 app.keeping |= client.keeping; 15227 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15228 .REASON_PROVIDER_IN_USE; 15229 app.adjSource = client; 15230 app.adjSourceOom = clientAdj; 15231 app.adjTarget = cpr.name; 15232 } 15233 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15234 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15235 // Special handling of clients who are in the top state. 15236 // We *may* want to consider this process to be in the 15237 // top state as well, but only if there is not another 15238 // reason for it to be running. Being on the top is a 15239 // special state, meaning you are specifically running 15240 // for the current top app. If the process is already 15241 // running in the background for some other reason, it 15242 // is more important to continue considering it to be 15243 // in the background state. 15244 mayBeTop = true; 15245 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15246 } else { 15247 // Special handling for above-top states (persistent 15248 // processes). These should not bring the current process 15249 // into the top state, since they are not on top. Instead 15250 // give them the best state after that. 15251 clientProcState = 15252 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15253 } 15254 } 15255 if (procState > clientProcState) { 15256 procState = clientProcState; 15257 } 15258 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15259 schedGroup = Process.THREAD_GROUP_DEFAULT; 15260 } 15261 } 15262 // If the provider has external (non-framework) process 15263 // dependencies, ensure that its adjustment is at least 15264 // FOREGROUND_APP_ADJ. 15265 if (cpr.hasExternalProcessHandles()) { 15266 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15267 adj = ProcessList.FOREGROUND_APP_ADJ; 15268 schedGroup = Process.THREAD_GROUP_DEFAULT; 15269 app.cached = false; 15270 app.keeping = true; 15271 app.adjType = "provider"; 15272 app.adjTarget = cpr.name; 15273 } 15274 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15275 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15276 } 15277 } 15278 } 15279 15280 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15281 // A client of one of our services or providers is in the top state. We 15282 // *may* want to be in the top state, but not if we are already running in 15283 // the background for some other reason. For the decision here, we are going 15284 // to pick out a few specific states that we want to remain in when a client 15285 // is top (states that tend to be longer-term) and otherwise allow it to go 15286 // to the top state. 15287 switch (procState) { 15288 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15289 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15290 case ActivityManager.PROCESS_STATE_SERVICE: 15291 // These all are longer-term states, so pull them up to the top 15292 // of the background states, but not all the way to the top state. 15293 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15294 break; 15295 default: 15296 // Otherwise, top is a better choice, so take it. 15297 procState = ActivityManager.PROCESS_STATE_TOP; 15298 break; 15299 } 15300 } 15301 15302 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15303 if (app.hasClientActivities) { 15304 // This is a cached process, but with client activities. Mark it so. 15305 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15306 app.adjType = "cch-client-act"; 15307 } else if (app.treatLikeActivity) { 15308 // This is a cached process, but somebody wants us to treat it like it has 15309 // an activity, okay! 15310 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15311 app.adjType = "cch-as-act"; 15312 } 15313 } 15314 15315 if (adj == ProcessList.SERVICE_ADJ) { 15316 if (doingAll) { 15317 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15318 mNewNumServiceProcs++; 15319 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15320 if (!app.serviceb) { 15321 // This service isn't far enough down on the LRU list to 15322 // normally be a B service, but if we are low on RAM and it 15323 // is large we want to force it down since we would prefer to 15324 // keep launcher over it. 15325 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15326 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15327 app.serviceHighRam = true; 15328 app.serviceb = true; 15329 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15330 } else { 15331 mNewNumAServiceProcs++; 15332 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15333 } 15334 } else { 15335 app.serviceHighRam = false; 15336 } 15337 } 15338 if (app.serviceb) { 15339 adj = ProcessList.SERVICE_B_ADJ; 15340 } 15341 } 15342 15343 app.curRawAdj = adj; 15344 15345 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15346 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15347 if (adj > app.maxAdj) { 15348 adj = app.maxAdj; 15349 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15350 schedGroup = Process.THREAD_GROUP_DEFAULT; 15351 } 15352 } 15353 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15354 app.keeping = true; 15355 } 15356 15357 // Do final modification to adj. Everything we do between here and applying 15358 // the final setAdj must be done in this function, because we will also use 15359 // it when computing the final cached adj later. Note that we don't need to 15360 // worry about this for max adj above, since max adj will always be used to 15361 // keep it out of the cached vaues. 15362 app.curAdj = app.modifyRawOomAdj(adj); 15363 app.curSchedGroup = schedGroup; 15364 app.curProcState = procState; 15365 app.foregroundActivities = foregroundActivities; 15366 15367 return app.curRawAdj; 15368 } 15369 15370 /** 15371 * Schedule PSS collection of a process. 15372 */ 15373 void requestPssLocked(ProcessRecord proc, int procState) { 15374 if (mPendingPssProcesses.contains(proc)) { 15375 return; 15376 } 15377 if (mPendingPssProcesses.size() == 0) { 15378 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15379 } 15380 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15381 proc.pssProcState = procState; 15382 mPendingPssProcesses.add(proc); 15383 } 15384 15385 /** 15386 * Schedule PSS collection of all processes. 15387 */ 15388 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15389 if (!always) { 15390 if (now < (mLastFullPssTime + 15391 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15392 return; 15393 } 15394 } 15395 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15396 mLastFullPssTime = now; 15397 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15398 mPendingPssProcesses.clear(); 15399 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15400 ProcessRecord app = mLruProcesses.get(i); 15401 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15402 app.pssProcState = app.setProcState; 15403 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15404 isSleeping(), now); 15405 mPendingPssProcesses.add(app); 15406 } 15407 } 15408 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15409 } 15410 15411 /** 15412 * Ask a given process to GC right now. 15413 */ 15414 final void performAppGcLocked(ProcessRecord app) { 15415 try { 15416 app.lastRequestedGc = SystemClock.uptimeMillis(); 15417 if (app.thread != null) { 15418 if (app.reportLowMemory) { 15419 app.reportLowMemory = false; 15420 app.thread.scheduleLowMemory(); 15421 } else { 15422 app.thread.processInBackground(); 15423 } 15424 } 15425 } catch (Exception e) { 15426 // whatever. 15427 } 15428 } 15429 15430 /** 15431 * Returns true if things are idle enough to perform GCs. 15432 */ 15433 private final boolean canGcNowLocked() { 15434 boolean processingBroadcasts = false; 15435 for (BroadcastQueue q : mBroadcastQueues) { 15436 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15437 processingBroadcasts = true; 15438 } 15439 } 15440 return !processingBroadcasts 15441 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15442 } 15443 15444 /** 15445 * Perform GCs on all processes that are waiting for it, but only 15446 * if things are idle. 15447 */ 15448 final void performAppGcsLocked() { 15449 final int N = mProcessesToGc.size(); 15450 if (N <= 0) { 15451 return; 15452 } 15453 if (canGcNowLocked()) { 15454 while (mProcessesToGc.size() > 0) { 15455 ProcessRecord proc = mProcessesToGc.remove(0); 15456 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15457 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15458 <= SystemClock.uptimeMillis()) { 15459 // To avoid spamming the system, we will GC processes one 15460 // at a time, waiting a few seconds between each. 15461 performAppGcLocked(proc); 15462 scheduleAppGcsLocked(); 15463 return; 15464 } else { 15465 // It hasn't been long enough since we last GCed this 15466 // process... put it in the list to wait for its time. 15467 addProcessToGcListLocked(proc); 15468 break; 15469 } 15470 } 15471 } 15472 15473 scheduleAppGcsLocked(); 15474 } 15475 } 15476 15477 /** 15478 * If all looks good, perform GCs on all processes waiting for them. 15479 */ 15480 final void performAppGcsIfAppropriateLocked() { 15481 if (canGcNowLocked()) { 15482 performAppGcsLocked(); 15483 return; 15484 } 15485 // Still not idle, wait some more. 15486 scheduleAppGcsLocked(); 15487 } 15488 15489 /** 15490 * Schedule the execution of all pending app GCs. 15491 */ 15492 final void scheduleAppGcsLocked() { 15493 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15494 15495 if (mProcessesToGc.size() > 0) { 15496 // Schedule a GC for the time to the next process. 15497 ProcessRecord proc = mProcessesToGc.get(0); 15498 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15499 15500 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15501 long now = SystemClock.uptimeMillis(); 15502 if (when < (now+GC_TIMEOUT)) { 15503 when = now + GC_TIMEOUT; 15504 } 15505 mHandler.sendMessageAtTime(msg, when); 15506 } 15507 } 15508 15509 /** 15510 * Add a process to the array of processes waiting to be GCed. Keeps the 15511 * list in sorted order by the last GC time. The process can't already be 15512 * on the list. 15513 */ 15514 final void addProcessToGcListLocked(ProcessRecord proc) { 15515 boolean added = false; 15516 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15517 if (mProcessesToGc.get(i).lastRequestedGc < 15518 proc.lastRequestedGc) { 15519 added = true; 15520 mProcessesToGc.add(i+1, proc); 15521 break; 15522 } 15523 } 15524 if (!added) { 15525 mProcessesToGc.add(0, proc); 15526 } 15527 } 15528 15529 /** 15530 * Set up to ask a process to GC itself. This will either do it 15531 * immediately, or put it on the list of processes to gc the next 15532 * time things are idle. 15533 */ 15534 final void scheduleAppGcLocked(ProcessRecord app) { 15535 long now = SystemClock.uptimeMillis(); 15536 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15537 return; 15538 } 15539 if (!mProcessesToGc.contains(app)) { 15540 addProcessToGcListLocked(app); 15541 scheduleAppGcsLocked(); 15542 } 15543 } 15544 15545 final void checkExcessivePowerUsageLocked(boolean doKills) { 15546 updateCpuStatsNow(); 15547 15548 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15549 boolean doWakeKills = doKills; 15550 boolean doCpuKills = doKills; 15551 if (mLastPowerCheckRealtime == 0) { 15552 doWakeKills = false; 15553 } 15554 if (mLastPowerCheckUptime == 0) { 15555 doCpuKills = false; 15556 } 15557 if (stats.isScreenOn()) { 15558 doWakeKills = false; 15559 } 15560 final long curRealtime = SystemClock.elapsedRealtime(); 15561 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15562 final long curUptime = SystemClock.uptimeMillis(); 15563 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15564 mLastPowerCheckRealtime = curRealtime; 15565 mLastPowerCheckUptime = curUptime; 15566 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15567 doWakeKills = false; 15568 } 15569 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15570 doCpuKills = false; 15571 } 15572 int i = mLruProcesses.size(); 15573 while (i > 0) { 15574 i--; 15575 ProcessRecord app = mLruProcesses.get(i); 15576 if (!app.keeping) { 15577 long wtime; 15578 synchronized (stats) { 15579 wtime = stats.getProcessWakeTime(app.info.uid, 15580 app.pid, curRealtime); 15581 } 15582 long wtimeUsed = wtime - app.lastWakeTime; 15583 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15584 if (DEBUG_POWER) { 15585 StringBuilder sb = new StringBuilder(128); 15586 sb.append("Wake for "); 15587 app.toShortString(sb); 15588 sb.append(": over "); 15589 TimeUtils.formatDuration(realtimeSince, sb); 15590 sb.append(" used "); 15591 TimeUtils.formatDuration(wtimeUsed, sb); 15592 sb.append(" ("); 15593 sb.append((wtimeUsed*100)/realtimeSince); 15594 sb.append("%)"); 15595 Slog.i(TAG, sb.toString()); 15596 sb.setLength(0); 15597 sb.append("CPU for "); 15598 app.toShortString(sb); 15599 sb.append(": over "); 15600 TimeUtils.formatDuration(uptimeSince, sb); 15601 sb.append(" used "); 15602 TimeUtils.formatDuration(cputimeUsed, sb); 15603 sb.append(" ("); 15604 sb.append((cputimeUsed*100)/uptimeSince); 15605 sb.append("%)"); 15606 Slog.i(TAG, sb.toString()); 15607 } 15608 // If a process has held a wake lock for more 15609 // than 50% of the time during this period, 15610 // that sounds bad. Kill! 15611 if (doWakeKills && realtimeSince > 0 15612 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15613 synchronized (stats) { 15614 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15615 realtimeSince, wtimeUsed); 15616 } 15617 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15618 + " during " + realtimeSince); 15619 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15620 } else if (doCpuKills && uptimeSince > 0 15621 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15622 synchronized (stats) { 15623 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15624 uptimeSince, cputimeUsed); 15625 } 15626 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15627 + " during " + uptimeSince); 15628 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15629 } else { 15630 app.lastWakeTime = wtime; 15631 app.lastCpuTime = app.curCpuTime; 15632 } 15633 } 15634 } 15635 } 15636 15637 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15638 ProcessRecord TOP_APP, boolean doingAll, long now) { 15639 boolean success = true; 15640 15641 if (app.curRawAdj != app.setRawAdj) { 15642 if (wasKeeping && !app.keeping) { 15643 // This app is no longer something we want to keep. Note 15644 // its current wake lock time to later know to kill it if 15645 // it is not behaving well. 15646 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15647 synchronized (stats) { 15648 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15649 app.pid, SystemClock.elapsedRealtime()); 15650 } 15651 app.lastCpuTime = app.curCpuTime; 15652 } 15653 15654 app.setRawAdj = app.curRawAdj; 15655 } 15656 15657 int changes = 0; 15658 15659 if (app.curAdj != app.setAdj) { 15660 ProcessList.setOomAdj(app.pid, app.curAdj); 15661 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15662 TAG, "Set " + app.pid + " " + app.processName + 15663 " adj " + app.curAdj + ": " + app.adjType); 15664 app.setAdj = app.curAdj; 15665 } 15666 15667 if (app.setSchedGroup != app.curSchedGroup) { 15668 app.setSchedGroup = app.curSchedGroup; 15669 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15670 "Setting process group of " + app.processName 15671 + " to " + app.curSchedGroup); 15672 if (app.waitingToKill != null && 15673 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15674 killUnneededProcessLocked(app, app.waitingToKill); 15675 success = false; 15676 } else { 15677 if (true) { 15678 long oldId = Binder.clearCallingIdentity(); 15679 try { 15680 Process.setProcessGroup(app.pid, app.curSchedGroup); 15681 } catch (Exception e) { 15682 Slog.w(TAG, "Failed setting process group of " + app.pid 15683 + " to " + app.curSchedGroup); 15684 e.printStackTrace(); 15685 } finally { 15686 Binder.restoreCallingIdentity(oldId); 15687 } 15688 } else { 15689 if (app.thread != null) { 15690 try { 15691 app.thread.setSchedulingGroup(app.curSchedGroup); 15692 } catch (RemoteException e) { 15693 } 15694 } 15695 } 15696 Process.setSwappiness(app.pid, 15697 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15698 } 15699 } 15700 if (app.repForegroundActivities != app.foregroundActivities) { 15701 app.repForegroundActivities = app.foregroundActivities; 15702 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15703 } 15704 if (app.repProcState != app.curProcState) { 15705 app.repProcState = app.curProcState; 15706 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15707 if (app.thread != null) { 15708 try { 15709 if (false) { 15710 //RuntimeException h = new RuntimeException("here"); 15711 Slog.i(TAG, "Sending new process state " + app.repProcState 15712 + " to " + app /*, h*/); 15713 } 15714 app.thread.setProcessState(app.repProcState); 15715 } catch (RemoteException e) { 15716 } 15717 } 15718 } 15719 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15720 app.setProcState)) { 15721 app.lastStateTime = now; 15722 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15723 isSleeping(), now); 15724 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15725 + ProcessList.makeProcStateString(app.setProcState) + " to " 15726 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15727 + (app.nextPssTime-now) + ": " + app); 15728 } else { 15729 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15730 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15731 requestPssLocked(app, app.setProcState); 15732 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15733 isSleeping(), now); 15734 } else if (false && DEBUG_PSS) { 15735 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15736 } 15737 } 15738 if (app.setProcState != app.curProcState) { 15739 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15740 "Proc state change of " + app.processName 15741 + " to " + app.curProcState); 15742 app.setProcState = app.curProcState; 15743 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15744 app.notCachedSinceIdle = false; 15745 } 15746 if (!doingAll) { 15747 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15748 } else { 15749 app.procStateChanged = true; 15750 } 15751 } 15752 15753 if (changes != 0) { 15754 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15755 int i = mPendingProcessChanges.size()-1; 15756 ProcessChangeItem item = null; 15757 while (i >= 0) { 15758 item = mPendingProcessChanges.get(i); 15759 if (item.pid == app.pid) { 15760 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15761 break; 15762 } 15763 i--; 15764 } 15765 if (i < 0) { 15766 // No existing item in pending changes; need a new one. 15767 final int NA = mAvailProcessChanges.size(); 15768 if (NA > 0) { 15769 item = mAvailProcessChanges.remove(NA-1); 15770 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15771 } else { 15772 item = new ProcessChangeItem(); 15773 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15774 } 15775 item.changes = 0; 15776 item.pid = app.pid; 15777 item.uid = app.info.uid; 15778 if (mPendingProcessChanges.size() == 0) { 15779 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15780 "*** Enqueueing dispatch processes changed!"); 15781 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15782 } 15783 mPendingProcessChanges.add(item); 15784 } 15785 item.changes |= changes; 15786 item.processState = app.repProcState; 15787 item.foregroundActivities = app.repForegroundActivities; 15788 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15789 + Integer.toHexString(System.identityHashCode(item)) 15790 + " " + app.toShortString() + ": changes=" + item.changes 15791 + " procState=" + item.processState 15792 + " foreground=" + item.foregroundActivities 15793 + " type=" + app.adjType + " source=" + app.adjSource 15794 + " target=" + app.adjTarget); 15795 } 15796 15797 return success; 15798 } 15799 15800 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15801 if (proc.thread != null && proc.baseProcessTracker != null) { 15802 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15803 } 15804 } 15805 15806 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15807 ProcessRecord TOP_APP, boolean doingAll, long now) { 15808 if (app.thread == null) { 15809 return false; 15810 } 15811 15812 final boolean wasKeeping = app.keeping; 15813 15814 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15815 15816 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 15817 } 15818 15819 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15820 boolean oomAdj) { 15821 if (isForeground != proc.foregroundServices) { 15822 proc.foregroundServices = isForeground; 15823 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15824 proc.info.uid); 15825 if (isForeground) { 15826 if (curProcs == null) { 15827 curProcs = new ArrayList<ProcessRecord>(); 15828 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15829 } 15830 if (!curProcs.contains(proc)) { 15831 curProcs.add(proc); 15832 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15833 proc.info.packageName, proc.info.uid); 15834 } 15835 } else { 15836 if (curProcs != null) { 15837 if (curProcs.remove(proc)) { 15838 mBatteryStatsService.noteEvent( 15839 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15840 proc.info.packageName, proc.info.uid); 15841 if (curProcs.size() <= 0) { 15842 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15843 } 15844 } 15845 } 15846 } 15847 if (oomAdj) { 15848 updateOomAdjLocked(); 15849 } 15850 } 15851 } 15852 15853 private final ActivityRecord resumedAppLocked() { 15854 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15855 String pkg; 15856 int uid; 15857 if (act != null && !act.sleeping) { 15858 pkg = act.packageName; 15859 uid = act.info.applicationInfo.uid; 15860 } else { 15861 pkg = null; 15862 uid = -1; 15863 } 15864 // Has the UID or resumed package name changed? 15865 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15866 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15867 if (mCurResumedPackage != null) { 15868 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15869 mCurResumedPackage, mCurResumedUid); 15870 } 15871 mCurResumedPackage = pkg; 15872 mCurResumedUid = uid; 15873 if (mCurResumedPackage != null) { 15874 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15875 mCurResumedPackage, mCurResumedUid); 15876 } 15877 } 15878 return act; 15879 } 15880 15881 final boolean updateOomAdjLocked(ProcessRecord app) { 15882 final ActivityRecord TOP_ACT = resumedAppLocked(); 15883 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15884 final boolean wasCached = app.cached; 15885 15886 mAdjSeq++; 15887 15888 // This is the desired cached adjusment we want to tell it to use. 15889 // If our app is currently cached, we know it, and that is it. Otherwise, 15890 // we don't know it yet, and it needs to now be cached we will then 15891 // need to do a complete oom adj. 15892 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15893 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15894 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 15895 SystemClock.uptimeMillis()); 15896 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15897 // Changed to/from cached state, so apps after it in the LRU 15898 // list may also be changed. 15899 updateOomAdjLocked(); 15900 } 15901 return success; 15902 } 15903 15904 final void updateOomAdjLocked() { 15905 final ActivityRecord TOP_ACT = resumedAppLocked(); 15906 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15907 final long now = SystemClock.uptimeMillis(); 15908 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15909 final int N = mLruProcesses.size(); 15910 15911 if (false) { 15912 RuntimeException e = new RuntimeException(); 15913 e.fillInStackTrace(); 15914 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15915 } 15916 15917 mAdjSeq++; 15918 mNewNumServiceProcs = 0; 15919 mNewNumAServiceProcs = 0; 15920 15921 final int emptyProcessLimit; 15922 final int cachedProcessLimit; 15923 if (mProcessLimit <= 0) { 15924 emptyProcessLimit = cachedProcessLimit = 0; 15925 } else if (mProcessLimit == 1) { 15926 emptyProcessLimit = 1; 15927 cachedProcessLimit = 0; 15928 } else { 15929 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15930 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15931 } 15932 15933 // Let's determine how many processes we have running vs. 15934 // how many slots we have for background processes; we may want 15935 // to put multiple processes in a slot of there are enough of 15936 // them. 15937 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15938 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15939 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15940 if (numEmptyProcs > cachedProcessLimit) { 15941 // If there are more empty processes than our limit on cached 15942 // processes, then use the cached process limit for the factor. 15943 // This ensures that the really old empty processes get pushed 15944 // down to the bottom, so if we are running low on memory we will 15945 // have a better chance at keeping around more cached processes 15946 // instead of a gazillion empty processes. 15947 numEmptyProcs = cachedProcessLimit; 15948 } 15949 int emptyFactor = numEmptyProcs/numSlots; 15950 if (emptyFactor < 1) emptyFactor = 1; 15951 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15952 if (cachedFactor < 1) cachedFactor = 1; 15953 int stepCached = 0; 15954 int stepEmpty = 0; 15955 int numCached = 0; 15956 int numEmpty = 0; 15957 int numTrimming = 0; 15958 15959 mNumNonCachedProcs = 0; 15960 mNumCachedHiddenProcs = 0; 15961 15962 // First update the OOM adjustment for each of the 15963 // application processes based on their current state. 15964 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15965 int nextCachedAdj = curCachedAdj+1; 15966 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15967 int nextEmptyAdj = curEmptyAdj+2; 15968 for (int i=N-1; i>=0; i--) { 15969 ProcessRecord app = mLruProcesses.get(i); 15970 if (!app.killedByAm && app.thread != null) { 15971 app.procStateChanged = false; 15972 final boolean wasKeeping = app.keeping; 15973 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15974 15975 // If we haven't yet assigned the final cached adj 15976 // to the process, do that now. 15977 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15978 switch (app.curProcState) { 15979 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15980 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15981 // This process is a cached process holding activities... 15982 // assign it the next cached value for that type, and then 15983 // step that cached level. 15984 app.curRawAdj = curCachedAdj; 15985 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15986 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15987 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15988 + ")"); 15989 if (curCachedAdj != nextCachedAdj) { 15990 stepCached++; 15991 if (stepCached >= cachedFactor) { 15992 stepCached = 0; 15993 curCachedAdj = nextCachedAdj; 15994 nextCachedAdj += 2; 15995 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15996 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15997 } 15998 } 15999 } 16000 break; 16001 default: 16002 // For everything else, assign next empty cached process 16003 // level and bump that up. Note that this means that 16004 // long-running services that have dropped down to the 16005 // cached level will be treated as empty (since their process 16006 // state is still as a service), which is what we want. 16007 app.curRawAdj = curEmptyAdj; 16008 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 16009 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 16010 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 16011 + ")"); 16012 if (curEmptyAdj != nextEmptyAdj) { 16013 stepEmpty++; 16014 if (stepEmpty >= emptyFactor) { 16015 stepEmpty = 0; 16016 curEmptyAdj = nextEmptyAdj; 16017 nextEmptyAdj += 2; 16018 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16019 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 16020 } 16021 } 16022 } 16023 break; 16024 } 16025 } 16026 16027 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 16028 16029 // Count the number of process types. 16030 switch (app.curProcState) { 16031 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16032 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16033 mNumCachedHiddenProcs++; 16034 numCached++; 16035 if (numCached > cachedProcessLimit) { 16036 killUnneededProcessLocked(app, "cached #" + numCached); 16037 } 16038 break; 16039 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 16040 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 16041 && app.lastActivityTime < oldTime) { 16042 killUnneededProcessLocked(app, "empty for " 16043 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 16044 / 1000) + "s"); 16045 } else { 16046 numEmpty++; 16047 if (numEmpty > emptyProcessLimit) { 16048 killUnneededProcessLocked(app, "empty #" + numEmpty); 16049 } 16050 } 16051 break; 16052 default: 16053 mNumNonCachedProcs++; 16054 break; 16055 } 16056 16057 if (app.isolated && app.services.size() <= 0) { 16058 // If this is an isolated process, and there are no 16059 // services running in it, then the process is no longer 16060 // needed. We agressively kill these because we can by 16061 // definition not re-use the same process again, and it is 16062 // good to avoid having whatever code was running in them 16063 // left sitting around after no longer needed. 16064 killUnneededProcessLocked(app, "isolated not needed"); 16065 } 16066 16067 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16068 && !app.killedByAm) { 16069 numTrimming++; 16070 } 16071 } 16072 } 16073 16074 mNumServiceProcs = mNewNumServiceProcs; 16075 16076 // Now determine the memory trimming level of background processes. 16077 // Unfortunately we need to start at the back of the list to do this 16078 // properly. We only do this if the number of background apps we 16079 // are managing to keep around is less than half the maximum we desire; 16080 // if we are keeping a good number around, we'll let them use whatever 16081 // memory they want. 16082 final int numCachedAndEmpty = numCached + numEmpty; 16083 int memFactor; 16084 if (numCached <= ProcessList.TRIM_CACHED_APPS 16085 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16086 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16087 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16088 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16089 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16090 } else { 16091 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16092 } 16093 } else { 16094 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16095 } 16096 // We always allow the memory level to go up (better). We only allow it to go 16097 // down if we are in a state where that is allowed, *and* the total number of processes 16098 // has gone down since last time. 16099 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16100 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16101 + " last=" + mLastNumProcesses); 16102 if (memFactor > mLastMemoryLevel) { 16103 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16104 memFactor = mLastMemoryLevel; 16105 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16106 } 16107 } 16108 mLastMemoryLevel = memFactor; 16109 mLastNumProcesses = mLruProcesses.size(); 16110 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16111 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16112 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16113 if (mLowRamStartTime == 0) { 16114 mLowRamStartTime = now; 16115 } 16116 int step = 0; 16117 int fgTrimLevel; 16118 switch (memFactor) { 16119 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16120 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16121 break; 16122 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16123 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16124 break; 16125 default: 16126 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16127 break; 16128 } 16129 int factor = numTrimming/3; 16130 int minFactor = 2; 16131 if (mHomeProcess != null) minFactor++; 16132 if (mPreviousProcess != null) minFactor++; 16133 if (factor < minFactor) factor = minFactor; 16134 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16135 for (int i=N-1; i>=0; i--) { 16136 ProcessRecord app = mLruProcesses.get(i); 16137 if (allChanged || app.procStateChanged) { 16138 setProcessTrackerState(app, trackerMemFactor, now); 16139 app.procStateChanged = false; 16140 } 16141 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16142 && !app.killedByAm) { 16143 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16144 try { 16145 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16146 "Trimming memory of " + app.processName 16147 + " to " + curLevel); 16148 app.thread.scheduleTrimMemory(curLevel); 16149 } catch (RemoteException e) { 16150 } 16151 if (false) { 16152 // For now we won't do this; our memory trimming seems 16153 // to be good enough at this point that destroying 16154 // activities causes more harm than good. 16155 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16156 && app != mHomeProcess && app != mPreviousProcess) { 16157 // Need to do this on its own message because the stack may not 16158 // be in a consistent state at this point. 16159 // For these apps we will also finish their activities 16160 // to help them free memory. 16161 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16162 } 16163 } 16164 } 16165 app.trimMemoryLevel = curLevel; 16166 step++; 16167 if (step >= factor) { 16168 step = 0; 16169 switch (curLevel) { 16170 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16171 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16172 break; 16173 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16174 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16175 break; 16176 } 16177 } 16178 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16179 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16180 && app.thread != null) { 16181 try { 16182 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16183 "Trimming memory of heavy-weight " + app.processName 16184 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16185 app.thread.scheduleTrimMemory( 16186 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16187 } catch (RemoteException e) { 16188 } 16189 } 16190 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16191 } else { 16192 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16193 || app.systemNoUi) && app.pendingUiClean) { 16194 // If this application is now in the background and it 16195 // had done UI, then give it the special trim level to 16196 // have it free UI resources. 16197 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16198 if (app.trimMemoryLevel < level && app.thread != null) { 16199 try { 16200 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16201 "Trimming memory of bg-ui " + app.processName 16202 + " to " + level); 16203 app.thread.scheduleTrimMemory(level); 16204 } catch (RemoteException e) { 16205 } 16206 } 16207 app.pendingUiClean = false; 16208 } 16209 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16210 try { 16211 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16212 "Trimming memory of fg " + app.processName 16213 + " to " + fgTrimLevel); 16214 app.thread.scheduleTrimMemory(fgTrimLevel); 16215 } catch (RemoteException e) { 16216 } 16217 } 16218 app.trimMemoryLevel = fgTrimLevel; 16219 } 16220 } 16221 } else { 16222 if (mLowRamStartTime != 0) { 16223 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16224 mLowRamStartTime = 0; 16225 } 16226 for (int i=N-1; i>=0; i--) { 16227 ProcessRecord app = mLruProcesses.get(i); 16228 if (allChanged || app.procStateChanged) { 16229 setProcessTrackerState(app, trackerMemFactor, now); 16230 app.procStateChanged = false; 16231 } 16232 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16233 || app.systemNoUi) && app.pendingUiClean) { 16234 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16235 && app.thread != null) { 16236 try { 16237 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16238 "Trimming memory of ui hidden " + app.processName 16239 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16240 app.thread.scheduleTrimMemory( 16241 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16242 } catch (RemoteException e) { 16243 } 16244 } 16245 app.pendingUiClean = false; 16246 } 16247 app.trimMemoryLevel = 0; 16248 } 16249 } 16250 16251 if (mAlwaysFinishActivities) { 16252 // Need to do this on its own message because the stack may not 16253 // be in a consistent state at this point. 16254 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16255 } 16256 16257 if (allChanged) { 16258 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16259 } 16260 16261 if (mProcessStats.shouldWriteNowLocked(now)) { 16262 mHandler.post(new Runnable() { 16263 @Override public void run() { 16264 synchronized (ActivityManagerService.this) { 16265 mProcessStats.writeStateAsyncLocked(); 16266 } 16267 } 16268 }); 16269 } 16270 16271 if (DEBUG_OOM_ADJ) { 16272 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16273 } 16274 } 16275 16276 final void trimApplications() { 16277 synchronized (this) { 16278 int i; 16279 16280 // First remove any unused application processes whose package 16281 // has been removed. 16282 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16283 final ProcessRecord app = mRemovedProcesses.get(i); 16284 if (app.activities.size() == 0 16285 && app.curReceiver == null && app.services.size() == 0) { 16286 Slog.i( 16287 TAG, "Exiting empty application process " 16288 + app.processName + " (" 16289 + (app.thread != null ? app.thread.asBinder() : null) 16290 + ")\n"); 16291 if (app.pid > 0 && app.pid != MY_PID) { 16292 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16293 app.processName, app.setAdj, "empty"); 16294 app.killedByAm = true; 16295 Process.killProcessQuiet(app.pid); 16296 } else { 16297 try { 16298 app.thread.scheduleExit(); 16299 } catch (Exception e) { 16300 // Ignore exceptions. 16301 } 16302 } 16303 cleanUpApplicationRecordLocked(app, false, true, -1); 16304 mRemovedProcesses.remove(i); 16305 16306 if (app.persistent) { 16307 if (app.persistent) { 16308 addAppLocked(app.info, false); 16309 } 16310 } 16311 } 16312 } 16313 16314 // Now update the oom adj for all processes. 16315 updateOomAdjLocked(); 16316 } 16317 } 16318 16319 /** This method sends the specified signal to each of the persistent apps */ 16320 public void signalPersistentProcesses(int sig) throws RemoteException { 16321 if (sig != Process.SIGNAL_USR1) { 16322 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16323 } 16324 16325 synchronized (this) { 16326 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16327 != PackageManager.PERMISSION_GRANTED) { 16328 throw new SecurityException("Requires permission " 16329 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16330 } 16331 16332 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16333 ProcessRecord r = mLruProcesses.get(i); 16334 if (r.thread != null && r.persistent) { 16335 Process.sendSignal(r.pid, sig); 16336 } 16337 } 16338 } 16339 } 16340 16341 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16342 if (proc == null || proc == mProfileProc) { 16343 proc = mProfileProc; 16344 path = mProfileFile; 16345 profileType = mProfileType; 16346 clearProfilerLocked(); 16347 } 16348 if (proc == null) { 16349 return; 16350 } 16351 try { 16352 proc.thread.profilerControl(false, path, null, profileType); 16353 } catch (RemoteException e) { 16354 throw new IllegalStateException("Process disappeared"); 16355 } 16356 } 16357 16358 private void clearProfilerLocked() { 16359 if (mProfileFd != null) { 16360 try { 16361 mProfileFd.close(); 16362 } catch (IOException e) { 16363 } 16364 } 16365 mProfileApp = null; 16366 mProfileProc = null; 16367 mProfileFile = null; 16368 mProfileType = 0; 16369 mAutoStopProfiler = false; 16370 } 16371 16372 public boolean profileControl(String process, int userId, boolean start, 16373 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16374 16375 try { 16376 synchronized (this) { 16377 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16378 // its own permission. 16379 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16380 != PackageManager.PERMISSION_GRANTED) { 16381 throw new SecurityException("Requires permission " 16382 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16383 } 16384 16385 if (start && fd == null) { 16386 throw new IllegalArgumentException("null fd"); 16387 } 16388 16389 ProcessRecord proc = null; 16390 if (process != null) { 16391 proc = findProcessLocked(process, userId, "profileControl"); 16392 } 16393 16394 if (start && (proc == null || proc.thread == null)) { 16395 throw new IllegalArgumentException("Unknown process: " + process); 16396 } 16397 16398 if (start) { 16399 stopProfilerLocked(null, null, 0); 16400 setProfileApp(proc.info, proc.processName, path, fd, false); 16401 mProfileProc = proc; 16402 mProfileType = profileType; 16403 try { 16404 fd = fd.dup(); 16405 } catch (IOException e) { 16406 fd = null; 16407 } 16408 proc.thread.profilerControl(start, path, fd, profileType); 16409 fd = null; 16410 mProfileFd = null; 16411 } else { 16412 stopProfilerLocked(proc, path, profileType); 16413 if (fd != null) { 16414 try { 16415 fd.close(); 16416 } catch (IOException e) { 16417 } 16418 } 16419 } 16420 16421 return true; 16422 } 16423 } catch (RemoteException e) { 16424 throw new IllegalStateException("Process disappeared"); 16425 } finally { 16426 if (fd != null) { 16427 try { 16428 fd.close(); 16429 } catch (IOException e) { 16430 } 16431 } 16432 } 16433 } 16434 16435 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16436 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16437 userId, true, true, callName, null); 16438 ProcessRecord proc = null; 16439 try { 16440 int pid = Integer.parseInt(process); 16441 synchronized (mPidsSelfLocked) { 16442 proc = mPidsSelfLocked.get(pid); 16443 } 16444 } catch (NumberFormatException e) { 16445 } 16446 16447 if (proc == null) { 16448 ArrayMap<String, SparseArray<ProcessRecord>> all 16449 = mProcessNames.getMap(); 16450 SparseArray<ProcessRecord> procs = all.get(process); 16451 if (procs != null && procs.size() > 0) { 16452 proc = procs.valueAt(0); 16453 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16454 for (int i=1; i<procs.size(); i++) { 16455 ProcessRecord thisProc = procs.valueAt(i); 16456 if (thisProc.userId == userId) { 16457 proc = thisProc; 16458 break; 16459 } 16460 } 16461 } 16462 } 16463 } 16464 16465 return proc; 16466 } 16467 16468 public boolean dumpHeap(String process, int userId, boolean managed, 16469 String path, ParcelFileDescriptor fd) throws RemoteException { 16470 16471 try { 16472 synchronized (this) { 16473 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16474 // its own permission (same as profileControl). 16475 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16476 != PackageManager.PERMISSION_GRANTED) { 16477 throw new SecurityException("Requires permission " 16478 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16479 } 16480 16481 if (fd == null) { 16482 throw new IllegalArgumentException("null fd"); 16483 } 16484 16485 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16486 if (proc == null || proc.thread == null) { 16487 throw new IllegalArgumentException("Unknown process: " + process); 16488 } 16489 16490 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16491 if (!isDebuggable) { 16492 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16493 throw new SecurityException("Process not debuggable: " + proc); 16494 } 16495 } 16496 16497 proc.thread.dumpHeap(managed, path, fd); 16498 fd = null; 16499 return true; 16500 } 16501 } catch (RemoteException e) { 16502 throw new IllegalStateException("Process disappeared"); 16503 } finally { 16504 if (fd != null) { 16505 try { 16506 fd.close(); 16507 } catch (IOException e) { 16508 } 16509 } 16510 } 16511 } 16512 16513 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16514 public void monitor() { 16515 synchronized (this) { } 16516 } 16517 16518 void onCoreSettingsChange(Bundle settings) { 16519 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16520 ProcessRecord processRecord = mLruProcesses.get(i); 16521 try { 16522 if (processRecord.thread != null) { 16523 processRecord.thread.setCoreSettings(settings); 16524 } 16525 } catch (RemoteException re) { 16526 /* ignore */ 16527 } 16528 } 16529 } 16530 16531 // Multi-user methods 16532 16533 /** 16534 * Start user, if its not already running, but don't bring it to foreground. 16535 */ 16536 @Override 16537 public boolean startUserInBackground(final int userId) { 16538 return startUser(userId, /* foreground */ false); 16539 } 16540 16541 /** 16542 * Refreshes the list of users related to the current user when either a 16543 * user switch happens or when a new related user is started in the 16544 * background. 16545 */ 16546 private void updateCurrentProfileIdsLocked() { 16547 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16548 mCurrentUserId, false /* enabledOnly */); 16549 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16550 for (int i = 0; i < currentProfileIds.length; i++) { 16551 currentProfileIds[i] = profiles.get(i).id; 16552 } 16553 mCurrentProfileIds = currentProfileIds; 16554 } 16555 16556 private Set getProfileIdsLocked(int userId) { 16557 Set userIds = new HashSet<Integer>(); 16558 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16559 userId, false /* enabledOnly */); 16560 for (UserInfo user : profiles) { 16561 userIds.add(Integer.valueOf(user.id)); 16562 } 16563 return userIds; 16564 } 16565 16566 @Override 16567 public boolean switchUser(final int userId) { 16568 return startUser(userId, /* foregound */ true); 16569 } 16570 16571 private boolean startUser(final int userId, boolean foreground) { 16572 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 16573 != PackageManager.PERMISSION_GRANTED) { 16574 String msg = "Permission Denial: switchUser() from pid=" 16575 + Binder.getCallingPid() 16576 + ", uid=" + Binder.getCallingUid() 16577 + " requires " + INTERACT_ACROSS_USERS_FULL; 16578 Slog.w(TAG, msg); 16579 throw new SecurityException(msg); 16580 } 16581 16582 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16583 16584 final long ident = Binder.clearCallingIdentity(); 16585 try { 16586 synchronized (this) { 16587 final int oldUserId = mCurrentUserId; 16588 if (oldUserId == userId) { 16589 return true; 16590 } 16591 16592 mStackSupervisor.setLockTaskModeLocked(null); 16593 16594 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16595 if (userInfo == null) { 16596 Slog.w(TAG, "No user info for user #" + userId); 16597 return false; 16598 } 16599 16600 if (foreground) { 16601 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16602 R.anim.screen_user_enter); 16603 } 16604 16605 boolean needStart = false; 16606 16607 // If the user we are switching to is not currently started, then 16608 // we need to start it now. 16609 if (mStartedUsers.get(userId) == null) { 16610 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16611 updateStartedUserArrayLocked(); 16612 needStart = true; 16613 } 16614 16615 final Integer userIdInt = Integer.valueOf(userId); 16616 mUserLru.remove(userIdInt); 16617 mUserLru.add(userIdInt); 16618 16619 if (foreground) { 16620 mCurrentUserId = userId; 16621 updateCurrentProfileIdsLocked(); 16622 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16623 // Once the internal notion of the active user has switched, we lock the device 16624 // with the option to show the user switcher on the keyguard. 16625 mWindowManager.lockNow(null); 16626 } else { 16627 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16628 updateCurrentProfileIdsLocked(); 16629 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16630 mUserLru.remove(currentUserIdInt); 16631 mUserLru.add(currentUserIdInt); 16632 } 16633 16634 final UserStartedState uss = mStartedUsers.get(userId); 16635 16636 // Make sure user is in the started state. If it is currently 16637 // stopping, we need to knock that off. 16638 if (uss.mState == UserStartedState.STATE_STOPPING) { 16639 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16640 // so we can just fairly silently bring the user back from 16641 // the almost-dead. 16642 uss.mState = UserStartedState.STATE_RUNNING; 16643 updateStartedUserArrayLocked(); 16644 needStart = true; 16645 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16646 // This means ACTION_SHUTDOWN has been sent, so we will 16647 // need to treat this as a new boot of the user. 16648 uss.mState = UserStartedState.STATE_BOOTING; 16649 updateStartedUserArrayLocked(); 16650 needStart = true; 16651 } 16652 16653 if (uss.mState == UserStartedState.STATE_BOOTING) { 16654 // Booting up a new user, need to tell system services about it. 16655 // Note that this is on the same handler as scheduling of broadcasts, 16656 // which is important because it needs to go first. 16657 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16658 } 16659 16660 if (foreground) { 16661 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16662 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16663 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16664 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16665 oldUserId, userId, uss)); 16666 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16667 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16668 } 16669 16670 if (needStart) { 16671 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16672 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16673 | Intent.FLAG_RECEIVER_FOREGROUND); 16674 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16675 broadcastIntentLocked(null, null, intent, 16676 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16677 false, false, MY_PID, Process.SYSTEM_UID, userId); 16678 } 16679 16680 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16681 if (userId != UserHandle.USER_OWNER) { 16682 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16683 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16684 broadcastIntentLocked(null, null, intent, null, 16685 new IIntentReceiver.Stub() { 16686 public void performReceive(Intent intent, int resultCode, 16687 String data, Bundle extras, boolean ordered, 16688 boolean sticky, int sendingUser) { 16689 userInitialized(uss, userId); 16690 } 16691 }, 0, null, null, null, AppOpsManager.OP_NONE, 16692 true, false, MY_PID, Process.SYSTEM_UID, 16693 userId); 16694 uss.initializing = true; 16695 } else { 16696 getUserManagerLocked().makeInitialized(userInfo.id); 16697 } 16698 } 16699 16700 if (foreground) { 16701 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16702 if (homeInFront) { 16703 startHomeActivityLocked(userId); 16704 } else { 16705 mStackSupervisor.resumeTopActivitiesLocked(); 16706 } 16707 EventLogTags.writeAmSwitchUser(userId); 16708 getUserManagerLocked().userForeground(userId); 16709 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16710 } else { 16711 mStackSupervisor.startBackgroundUserLocked(userId, uss); 16712 } 16713 16714 if (needStart) { 16715 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16716 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16717 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16718 broadcastIntentLocked(null, null, intent, 16719 null, new IIntentReceiver.Stub() { 16720 @Override 16721 public void performReceive(Intent intent, int resultCode, String data, 16722 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16723 throws RemoteException { 16724 } 16725 }, 0, null, null, 16726 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16727 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16728 } 16729 } 16730 } finally { 16731 Binder.restoreCallingIdentity(ident); 16732 } 16733 16734 return true; 16735 } 16736 16737 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16738 long ident = Binder.clearCallingIdentity(); 16739 try { 16740 Intent intent; 16741 if (oldUserId >= 0) { 16742 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16743 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16744 | Intent.FLAG_RECEIVER_FOREGROUND); 16745 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16746 broadcastIntentLocked(null, null, intent, 16747 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16748 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16749 } 16750 if (newUserId >= 0) { 16751 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16752 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16753 | Intent.FLAG_RECEIVER_FOREGROUND); 16754 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16755 broadcastIntentLocked(null, null, intent, 16756 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16757 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16758 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16759 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16760 | Intent.FLAG_RECEIVER_FOREGROUND); 16761 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16762 broadcastIntentLocked(null, null, intent, 16763 null, null, 0, null, null, 16764 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16765 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16766 } 16767 } finally { 16768 Binder.restoreCallingIdentity(ident); 16769 } 16770 } 16771 16772 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16773 final int newUserId) { 16774 final int N = mUserSwitchObservers.beginBroadcast(); 16775 if (N > 0) { 16776 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16777 int mCount = 0; 16778 @Override 16779 public void sendResult(Bundle data) throws RemoteException { 16780 synchronized (ActivityManagerService.this) { 16781 if (mCurUserSwitchCallback == this) { 16782 mCount++; 16783 if (mCount == N) { 16784 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16785 } 16786 } 16787 } 16788 } 16789 }; 16790 synchronized (this) { 16791 uss.switching = true; 16792 mCurUserSwitchCallback = callback; 16793 } 16794 for (int i=0; i<N; i++) { 16795 try { 16796 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16797 newUserId, callback); 16798 } catch (RemoteException e) { 16799 } 16800 } 16801 } else { 16802 synchronized (this) { 16803 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16804 } 16805 } 16806 mUserSwitchObservers.finishBroadcast(); 16807 } 16808 16809 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16810 synchronized (this) { 16811 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16812 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16813 } 16814 } 16815 16816 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16817 mCurUserSwitchCallback = null; 16818 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16819 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16820 oldUserId, newUserId, uss)); 16821 } 16822 16823 void userInitialized(UserStartedState uss, int newUserId) { 16824 completeSwitchAndInitalize(uss, newUserId, true, false); 16825 } 16826 16827 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16828 completeSwitchAndInitalize(uss, newUserId, false, true); 16829 } 16830 16831 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16832 boolean clearInitializing, boolean clearSwitching) { 16833 boolean unfrozen = false; 16834 synchronized (this) { 16835 if (clearInitializing) { 16836 uss.initializing = false; 16837 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16838 } 16839 if (clearSwitching) { 16840 uss.switching = false; 16841 } 16842 if (!uss.switching && !uss.initializing) { 16843 mWindowManager.stopFreezingScreen(); 16844 unfrozen = true; 16845 } 16846 } 16847 if (unfrozen) { 16848 final int N = mUserSwitchObservers.beginBroadcast(); 16849 for (int i=0; i<N; i++) { 16850 try { 16851 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16852 } catch (RemoteException e) { 16853 } 16854 } 16855 mUserSwitchObservers.finishBroadcast(); 16856 } 16857 } 16858 16859 void scheduleStartProfilesLocked() { 16860 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16861 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16862 DateUtils.SECOND_IN_MILLIS); 16863 } 16864 } 16865 16866 void startProfilesLocked() { 16867 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16868 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16869 mCurrentUserId, false /* enabledOnly */); 16870 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16871 for (UserInfo user : profiles) { 16872 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16873 && user.id != mCurrentUserId) { 16874 toStart.add(user); 16875 } 16876 } 16877 final int n = toStart.size(); 16878 int i = 0; 16879 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16880 startUserInBackground(toStart.get(i).id); 16881 } 16882 if (i < n) { 16883 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16884 } 16885 } 16886 16887 void finishUserBoot(UserStartedState uss) { 16888 synchronized (this) { 16889 if (uss.mState == UserStartedState.STATE_BOOTING 16890 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16891 uss.mState = UserStartedState.STATE_RUNNING; 16892 final int userId = uss.mHandle.getIdentifier(); 16893 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16894 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16895 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16896 broadcastIntentLocked(null, null, intent, 16897 null, null, 0, null, null, 16898 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16899 true, false, MY_PID, Process.SYSTEM_UID, userId); 16900 } 16901 } 16902 } 16903 16904 void finishUserSwitch(UserStartedState uss) { 16905 synchronized (this) { 16906 finishUserBoot(uss); 16907 16908 startProfilesLocked(); 16909 16910 int num = mUserLru.size(); 16911 int i = 0; 16912 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16913 Integer oldUserId = mUserLru.get(i); 16914 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16915 if (oldUss == null) { 16916 // Shouldn't happen, but be sane if it does. 16917 mUserLru.remove(i); 16918 num--; 16919 continue; 16920 } 16921 if (oldUss.mState == UserStartedState.STATE_STOPPING 16922 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16923 // This user is already stopping, doesn't count. 16924 num--; 16925 i++; 16926 continue; 16927 } 16928 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16929 // Owner and current can't be stopped, but count as running. 16930 i++; 16931 continue; 16932 } 16933 // This is a user to be stopped. 16934 stopUserLocked(oldUserId, null); 16935 num--; 16936 i++; 16937 } 16938 } 16939 } 16940 16941 @Override 16942 public int stopUser(final int userId, final IStopUserCallback callback) { 16943 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 16944 != PackageManager.PERMISSION_GRANTED) { 16945 String msg = "Permission Denial: switchUser() from pid=" 16946 + Binder.getCallingPid() 16947 + ", uid=" + Binder.getCallingUid() 16948 + " requires " + INTERACT_ACROSS_USERS_FULL; 16949 Slog.w(TAG, msg); 16950 throw new SecurityException(msg); 16951 } 16952 if (userId <= 0) { 16953 throw new IllegalArgumentException("Can't stop primary user " + userId); 16954 } 16955 synchronized (this) { 16956 return stopUserLocked(userId, callback); 16957 } 16958 } 16959 16960 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16961 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16962 if (mCurrentUserId == userId) { 16963 return ActivityManager.USER_OP_IS_CURRENT; 16964 } 16965 16966 final UserStartedState uss = mStartedUsers.get(userId); 16967 if (uss == null) { 16968 // User is not started, nothing to do... but we do need to 16969 // callback if requested. 16970 if (callback != null) { 16971 mHandler.post(new Runnable() { 16972 @Override 16973 public void run() { 16974 try { 16975 callback.userStopped(userId); 16976 } catch (RemoteException e) { 16977 } 16978 } 16979 }); 16980 } 16981 return ActivityManager.USER_OP_SUCCESS; 16982 } 16983 16984 if (callback != null) { 16985 uss.mStopCallbacks.add(callback); 16986 } 16987 16988 if (uss.mState != UserStartedState.STATE_STOPPING 16989 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16990 uss.mState = UserStartedState.STATE_STOPPING; 16991 updateStartedUserArrayLocked(); 16992 16993 long ident = Binder.clearCallingIdentity(); 16994 try { 16995 // We are going to broadcast ACTION_USER_STOPPING and then 16996 // once that is done send a final ACTION_SHUTDOWN and then 16997 // stop the user. 16998 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16999 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17000 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17001 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 17002 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 17003 // This is the result receiver for the final shutdown broadcast. 17004 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 17005 @Override 17006 public void performReceive(Intent intent, int resultCode, String data, 17007 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17008 finishUserStop(uss); 17009 } 17010 }; 17011 // This is the result receiver for the initial stopping broadcast. 17012 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 17013 @Override 17014 public void performReceive(Intent intent, int resultCode, String data, 17015 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17016 // On to the next. 17017 synchronized (ActivityManagerService.this) { 17018 if (uss.mState != UserStartedState.STATE_STOPPING) { 17019 // Whoops, we are being started back up. Abort, abort! 17020 return; 17021 } 17022 uss.mState = UserStartedState.STATE_SHUTDOWN; 17023 } 17024 mSystemServiceManager.stopUser(userId); 17025 broadcastIntentLocked(null, null, shutdownIntent, 17026 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 17027 true, false, MY_PID, Process.SYSTEM_UID, userId); 17028 } 17029 }; 17030 // Kick things off. 17031 broadcastIntentLocked(null, null, stoppingIntent, 17032 null, stoppingReceiver, 0, null, null, 17033 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17034 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17035 } finally { 17036 Binder.restoreCallingIdentity(ident); 17037 } 17038 } 17039 17040 return ActivityManager.USER_OP_SUCCESS; 17041 } 17042 17043 void finishUserStop(UserStartedState uss) { 17044 final int userId = uss.mHandle.getIdentifier(); 17045 boolean stopped; 17046 ArrayList<IStopUserCallback> callbacks; 17047 synchronized (this) { 17048 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 17049 if (mStartedUsers.get(userId) != uss) { 17050 stopped = false; 17051 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 17052 stopped = false; 17053 } else { 17054 stopped = true; 17055 // User can no longer run. 17056 mStartedUsers.remove(userId); 17057 mUserLru.remove(Integer.valueOf(userId)); 17058 updateStartedUserArrayLocked(); 17059 17060 // Clean up all state and processes associated with the user. 17061 // Kill all the processes for the user. 17062 forceStopUserLocked(userId, "finish user"); 17063 } 17064 } 17065 17066 for (int i=0; i<callbacks.size(); i++) { 17067 try { 17068 if (stopped) callbacks.get(i).userStopped(userId); 17069 else callbacks.get(i).userStopAborted(userId); 17070 } catch (RemoteException e) { 17071 } 17072 } 17073 17074 if (stopped) { 17075 mSystemServiceManager.cleanupUser(userId); 17076 synchronized (this) { 17077 mStackSupervisor.removeUserLocked(userId); 17078 } 17079 } 17080 } 17081 17082 @Override 17083 public UserInfo getCurrentUser() { 17084 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17085 != PackageManager.PERMISSION_GRANTED) && ( 17086 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17087 != PackageManager.PERMISSION_GRANTED)) { 17088 String msg = "Permission Denial: getCurrentUser() from pid=" 17089 + Binder.getCallingPid() 17090 + ", uid=" + Binder.getCallingUid() 17091 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17092 Slog.w(TAG, msg); 17093 throw new SecurityException(msg); 17094 } 17095 synchronized (this) { 17096 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17097 } 17098 } 17099 17100 int getCurrentUserIdLocked() { 17101 return mCurrentUserId; 17102 } 17103 17104 @Override 17105 public boolean isUserRunning(int userId, boolean orStopped) { 17106 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17107 != PackageManager.PERMISSION_GRANTED) { 17108 String msg = "Permission Denial: isUserRunning() from pid=" 17109 + Binder.getCallingPid() 17110 + ", uid=" + Binder.getCallingUid() 17111 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17112 Slog.w(TAG, msg); 17113 throw new SecurityException(msg); 17114 } 17115 synchronized (this) { 17116 return isUserRunningLocked(userId, orStopped); 17117 } 17118 } 17119 17120 boolean isUserRunningLocked(int userId, boolean orStopped) { 17121 UserStartedState state = mStartedUsers.get(userId); 17122 if (state == null) { 17123 return false; 17124 } 17125 if (orStopped) { 17126 return true; 17127 } 17128 return state.mState != UserStartedState.STATE_STOPPING 17129 && state.mState != UserStartedState.STATE_SHUTDOWN; 17130 } 17131 17132 @Override 17133 public int[] getRunningUserIds() { 17134 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17135 != PackageManager.PERMISSION_GRANTED) { 17136 String msg = "Permission Denial: isUserRunning() from pid=" 17137 + Binder.getCallingPid() 17138 + ", uid=" + Binder.getCallingUid() 17139 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17140 Slog.w(TAG, msg); 17141 throw new SecurityException(msg); 17142 } 17143 synchronized (this) { 17144 return mStartedUserArray; 17145 } 17146 } 17147 17148 private void updateStartedUserArrayLocked() { 17149 int num = 0; 17150 for (int i=0; i<mStartedUsers.size(); i++) { 17151 UserStartedState uss = mStartedUsers.valueAt(i); 17152 // This list does not include stopping users. 17153 if (uss.mState != UserStartedState.STATE_STOPPING 17154 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17155 num++; 17156 } 17157 } 17158 mStartedUserArray = new int[num]; 17159 num = 0; 17160 for (int i=0; i<mStartedUsers.size(); i++) { 17161 UserStartedState uss = mStartedUsers.valueAt(i); 17162 if (uss.mState != UserStartedState.STATE_STOPPING 17163 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17164 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17165 num++; 17166 } 17167 } 17168 } 17169 17170 @Override 17171 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17172 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17173 != PackageManager.PERMISSION_GRANTED) { 17174 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17175 + Binder.getCallingPid() 17176 + ", uid=" + Binder.getCallingUid() 17177 + " requires " + INTERACT_ACROSS_USERS_FULL; 17178 Slog.w(TAG, msg); 17179 throw new SecurityException(msg); 17180 } 17181 17182 mUserSwitchObservers.register(observer); 17183 } 17184 17185 @Override 17186 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17187 mUserSwitchObservers.unregister(observer); 17188 } 17189 17190 private boolean userExists(int userId) { 17191 if (userId == 0) { 17192 return true; 17193 } 17194 UserManagerService ums = getUserManagerLocked(); 17195 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17196 } 17197 17198 int[] getUsersLocked() { 17199 UserManagerService ums = getUserManagerLocked(); 17200 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17201 } 17202 17203 UserManagerService getUserManagerLocked() { 17204 if (mUserManager == null) { 17205 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17206 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17207 } 17208 return mUserManager; 17209 } 17210 17211 private int applyUserId(int uid, int userId) { 17212 return UserHandle.getUid(userId, uid); 17213 } 17214 17215 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17216 if (info == null) return null; 17217 ApplicationInfo newInfo = new ApplicationInfo(info); 17218 newInfo.uid = applyUserId(info.uid, userId); 17219 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17220 + info.packageName; 17221 return newInfo; 17222 } 17223 17224 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17225 if (aInfo == null 17226 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17227 return aInfo; 17228 } 17229 17230 ActivityInfo info = new ActivityInfo(aInfo); 17231 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17232 return info; 17233 } 17234 17235 private final class LocalService extends ActivityManagerInternal { 17236 @Override 17237 public void goingToSleep() { 17238 ActivityManagerService.this.goingToSleep(); 17239 } 17240 17241 @Override 17242 public void wakingUp() { 17243 ActivityManagerService.this.wakingUp(); 17244 } 17245 } 17246 17247 /** 17248 * An implementation of IAppTask, that allows an app to manage its own tasks via 17249 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 17250 * only the process that calls getAppTasks() can call the AppTask methods. 17251 */ 17252 class AppTaskImpl extends IAppTask.Stub { 17253 private int mTaskId; 17254 private int mCallingUid; 17255 17256 public AppTaskImpl(int taskId, int callingUid) { 17257 mTaskId = taskId; 17258 mCallingUid = callingUid; 17259 } 17260 17261 @Override 17262 public void finishAndRemoveTask() { 17263 // Ensure that we are called from the same process that created this AppTask 17264 if (mCallingUid != Binder.getCallingUid()) { 17265 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17266 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17267 return; 17268 } 17269 17270 synchronized (ActivityManagerService.this) { 17271 long origId = Binder.clearCallingIdentity(); 17272 try { 17273 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17274 if (tr != null) { 17275 // Only kill the process if we are not a new document 17276 int flags = tr.getBaseIntent().getFlags(); 17277 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 17278 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 17279 removeTaskByIdLocked(mTaskId, 17280 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 17281 } 17282 } finally { 17283 Binder.restoreCallingIdentity(origId); 17284 } 17285 } 17286 } 17287 17288 @Override 17289 public ActivityManager.RecentTaskInfo getTaskInfo() { 17290 // Ensure that we are called from the same process that created this AppTask 17291 if (mCallingUid != Binder.getCallingUid()) { 17292 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17293 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17294 return null; 17295 } 17296 17297 synchronized (ActivityManagerService.this) { 17298 long origId = Binder.clearCallingIdentity(); 17299 try { 17300 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17301 if (tr != null) { 17302 return createRecentTaskInfoFromTaskRecord(tr); 17303 } 17304 } finally { 17305 Binder.restoreCallingIdentity(origId); 17306 } 17307 return null; 17308 } 17309 } 17310 } 17311} 17312