ActivityManagerService.java revision 1147c406515bbfbcb7dbd750f81c7a5de928c5c6
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20import static com.android.internal.util.XmlUtils.readBooleanAttribute; 21import static com.android.internal.util.XmlUtils.readIntAttribute; 22import static com.android.internal.util.XmlUtils.readLongAttribute; 23import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 24import static com.android.internal.util.XmlUtils.writeIntAttribute; 25import static com.android.internal.util.XmlUtils.writeLongAttribute; 26import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 27import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 28import static org.xmlpull.v1.XmlPullParser.START_TAG; 29import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 30 31import android.Manifest; 32import android.app.AppOpsManager; 33import android.app.IActivityContainer; 34import android.app.IActivityContainerCallback; 35import android.app.IAppTask; 36import android.appwidget.AppWidgetManager; 37import android.graphics.Rect; 38import android.os.BatteryStats; 39import android.os.PersistableBundle; 40import android.service.voice.IVoiceInteractionSession; 41import android.util.ArrayMap; 42 43import com.android.internal.R; 44import com.android.internal.annotations.GuardedBy; 45import com.android.internal.app.IAppOpsService; 46import com.android.internal.app.IVoiceInteractor; 47import com.android.internal.app.ProcessMap; 48import com.android.internal.app.ProcessStats; 49import com.android.internal.content.PackageMonitor; 50import com.android.internal.os.BackgroundThread; 51import com.android.internal.os.BatteryStatsImpl; 52import com.android.internal.os.ProcessCpuTracker; 53import com.android.internal.os.TransferPipe; 54import com.android.internal.os.Zygote; 55import com.android.internal.util.FastPrintWriter; 56import com.android.internal.util.FastXmlSerializer; 57import com.android.internal.util.MemInfoReader; 58import com.android.internal.util.Preconditions; 59import com.android.server.AppOpsService; 60import com.android.server.AttributeCache; 61import com.android.server.IntentResolver; 62import com.android.server.LocalServices; 63import com.android.server.ServiceThread; 64import com.android.server.SystemService; 65import com.android.server.SystemServiceManager; 66import com.android.server.Watchdog; 67import com.android.server.am.ActivityStack.ActivityState; 68import com.android.server.firewall.IntentFirewall; 69import com.android.server.pm.UserManagerService; 70import com.android.server.wm.AppTransition; 71import com.android.server.wm.WindowManagerService; 72import com.google.android.collect.Lists; 73import com.google.android.collect.Maps; 74 75import libcore.io.IoUtils; 76 77import org.xmlpull.v1.XmlPullParser; 78import org.xmlpull.v1.XmlPullParserException; 79import org.xmlpull.v1.XmlSerializer; 80 81import android.app.Activity; 82import android.app.ActivityManager; 83import android.app.ActivityManager.RunningTaskInfo; 84import android.app.ActivityManager.StackInfo; 85import android.app.ActivityManagerInternal; 86import android.app.ActivityManagerNative; 87import android.app.ActivityOptions; 88import android.app.ActivityThread; 89import android.app.AlertDialog; 90import android.app.AppGlobals; 91import android.app.ApplicationErrorReport; 92import android.app.Dialog; 93import android.app.IActivityController; 94import android.app.IApplicationThread; 95import android.app.IInstrumentationWatcher; 96import android.app.INotificationManager; 97import android.app.IProcessObserver; 98import android.app.IServiceConnection; 99import android.app.IStopUserCallback; 100import android.app.IUiAutomationConnection; 101import android.app.IUserSwitchObserver; 102import android.app.Instrumentation; 103import android.app.Notification; 104import android.app.NotificationManager; 105import android.app.PendingIntent; 106import android.app.backup.IBackupManager; 107import android.content.ActivityNotFoundException; 108import android.content.BroadcastReceiver; 109import android.content.ClipData; 110import android.content.ComponentCallbacks2; 111import android.content.ComponentName; 112import android.content.ContentProvider; 113import android.content.ContentResolver; 114import android.content.Context; 115import android.content.DialogInterface; 116import android.content.IContentProvider; 117import android.content.IIntentReceiver; 118import android.content.IIntentSender; 119import android.content.Intent; 120import android.content.IntentFilter; 121import android.content.IntentSender; 122import android.content.pm.ActivityInfo; 123import android.content.pm.ApplicationInfo; 124import android.content.pm.ConfigurationInfo; 125import android.content.pm.IPackageDataObserver; 126import android.content.pm.IPackageManager; 127import android.content.pm.InstrumentationInfo; 128import android.content.pm.PackageInfo; 129import android.content.pm.PackageManager; 130import android.content.pm.ParceledListSlice; 131import android.content.pm.UserInfo; 132import android.content.pm.PackageManager.NameNotFoundException; 133import android.content.pm.PathPermission; 134import android.content.pm.ProviderInfo; 135import android.content.pm.ResolveInfo; 136import android.content.pm.ServiceInfo; 137import android.content.res.CompatibilityInfo; 138import android.content.res.Configuration; 139import android.graphics.Bitmap; 140import android.net.Proxy; 141import android.net.ProxyInfo; 142import android.net.Uri; 143import android.os.Binder; 144import android.os.Build; 145import android.os.Bundle; 146import android.os.Debug; 147import android.os.DropBoxManager; 148import android.os.Environment; 149import android.os.FactoryTest; 150import android.os.FileObserver; 151import android.os.FileUtils; 152import android.os.Handler; 153import android.os.IBinder; 154import android.os.IPermissionController; 155import android.os.IRemoteCallback; 156import android.os.IUserManager; 157import android.os.Looper; 158import android.os.Message; 159import android.os.Parcel; 160import android.os.ParcelFileDescriptor; 161import android.os.Process; 162import android.os.RemoteCallbackList; 163import android.os.RemoteException; 164import android.os.SELinux; 165import android.os.ServiceManager; 166import android.os.StrictMode; 167import android.os.SystemClock; 168import android.os.SystemProperties; 169import android.os.UpdateLock; 170import android.os.UserHandle; 171import android.provider.Settings; 172import android.text.format.DateUtils; 173import android.text.format.Time; 174import android.util.AtomicFile; 175import android.util.EventLog; 176import android.util.Log; 177import android.util.Pair; 178import android.util.PrintWriterPrinter; 179import android.util.Slog; 180import android.util.SparseArray; 181import android.util.TimeUtils; 182import android.util.Xml; 183import android.view.Gravity; 184import android.view.LayoutInflater; 185import android.view.View; 186import android.view.WindowManager; 187 188import java.io.BufferedInputStream; 189import java.io.BufferedOutputStream; 190import java.io.DataInputStream; 191import java.io.DataOutputStream; 192import java.io.File; 193import java.io.FileDescriptor; 194import java.io.FileInputStream; 195import java.io.FileNotFoundException; 196import java.io.FileOutputStream; 197import java.io.IOException; 198import java.io.InputStreamReader; 199import java.io.PrintWriter; 200import java.io.StringWriter; 201import java.lang.ref.WeakReference; 202import java.util.ArrayList; 203import java.util.Arrays; 204import java.util.Collections; 205import java.util.Comparator; 206import java.util.HashMap; 207import java.util.HashSet; 208import java.util.Iterator; 209import java.util.List; 210import java.util.Locale; 211import java.util.Map; 212import java.util.Set; 213import java.util.concurrent.atomic.AtomicBoolean; 214import java.util.concurrent.atomic.AtomicLong; 215 216public final class ActivityManagerService extends ActivityManagerNative 217 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 218 private static final String USER_DATA_DIR = "/data/user/"; 219 static final String TAG = "ActivityManager"; 220 static final String TAG_MU = "ActivityManagerServiceMU"; 221 static final boolean DEBUG = false; 222 static final boolean localLOGV = DEBUG; 223 static final boolean DEBUG_BACKUP = localLOGV || false; 224 static final boolean DEBUG_BROADCAST = localLOGV || false; 225 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 226 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 227 static final boolean DEBUG_CLEANUP = localLOGV || false; 228 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 229 static final boolean DEBUG_FOCUS = false; 230 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 231 static final boolean DEBUG_MU = localLOGV || false; 232 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 233 static final boolean DEBUG_LRU = localLOGV || false; 234 static final boolean DEBUG_PAUSE = localLOGV || false; 235 static final boolean DEBUG_POWER = localLOGV || false; 236 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 237 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 238 static final boolean DEBUG_PROCESSES = localLOGV || false; 239 static final boolean DEBUG_PROVIDER = localLOGV || false; 240 static final boolean DEBUG_RESULTS = localLOGV || false; 241 static final boolean DEBUG_SERVICE = localLOGV || false; 242 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 243 static final boolean DEBUG_STACK = localLOGV || false; 244 static final boolean DEBUG_SWITCH = localLOGV || false; 245 static final boolean DEBUG_TASKS = localLOGV || false; 246 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 247 static final boolean DEBUG_TRANSITION = localLOGV || false; 248 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 249 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 250 static final boolean DEBUG_VISBILITY = localLOGV || false; 251 static final boolean DEBUG_PSS = localLOGV || false; 252 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 253 static final boolean VALIDATE_TOKENS = false; 254 static final boolean SHOW_ACTIVITY_START_TIME = true; 255 256 // Control over CPU and battery monitoring. 257 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 258 static final boolean MONITOR_CPU_USAGE = true; 259 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 260 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 261 static final boolean MONITOR_THREAD_CPU_USAGE = false; 262 263 // The flags that are set for all calls we make to the package manager. 264 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 265 266 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 267 268 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 269 270 // Maximum number of recent tasks that we can remember. 271 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 272 273 // Amount of time after a call to stopAppSwitches() during which we will 274 // prevent further untrusted switches from happening. 275 static final long APP_SWITCH_DELAY_TIME = 5*1000; 276 277 // How long we wait for a launched process to attach to the activity manager 278 // before we decide it's never going to come up for real. 279 static final int PROC_START_TIMEOUT = 10*1000; 280 281 // How long we wait for a launched process to attach to the activity manager 282 // before we decide it's never going to come up for real, when the process was 283 // started with a wrapper for instrumentation (such as Valgrind) because it 284 // could take much longer than usual. 285 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 286 287 // How long to wait after going idle before forcing apps to GC. 288 static final int GC_TIMEOUT = 5*1000; 289 290 // The minimum amount of time between successive GC requests for a process. 291 static final int GC_MIN_INTERVAL = 60*1000; 292 293 // The minimum amount of time between successive PSS requests for a process. 294 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 295 296 // The minimum amount of time between successive PSS requests for a process 297 // when the request is due to the memory state being lowered. 298 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 299 300 // The rate at which we check for apps using excessive power -- 15 mins. 301 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 302 303 // The minimum sample duration we will allow before deciding we have 304 // enough data on wake locks to start killing things. 305 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 306 307 // The minimum sample duration we will allow before deciding we have 308 // enough data on CPU usage to start killing things. 309 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 310 311 // How long we allow a receiver to run before giving up on it. 312 static final int BROADCAST_FG_TIMEOUT = 10*1000; 313 static final int BROADCAST_BG_TIMEOUT = 60*1000; 314 315 // How long we wait until we timeout on key dispatching. 316 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 317 318 // How long we wait until we timeout on key dispatching during instrumentation. 319 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 320 321 // Amount of time we wait for observers to handle a user switch before 322 // giving up on them and unfreezing the screen. 323 static final int USER_SWITCH_TIMEOUT = 2*1000; 324 325 // Maximum number of users we allow to be running at a time. 326 static final int MAX_RUNNING_USERS = 3; 327 328 // How long to wait in getAssistContextExtras for the activity and foreground services 329 // to respond with the result. 330 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 331 332 // Maximum number of persisted Uri grants a package is allowed 333 static final int MAX_PERSISTED_URI_GRANTS = 128; 334 335 static final int MY_PID = Process.myPid(); 336 337 static final String[] EMPTY_STRING_ARRAY = new String[0]; 338 339 // How many bytes to write into the dropbox log before truncating 340 static final int DROPBOX_MAX_SIZE = 256 * 1024; 341 342 /** All system services */ 343 SystemServiceManager mSystemServiceManager; 344 345 /** Run all ActivityStacks through this */ 346 ActivityStackSupervisor mStackSupervisor; 347 348 public IntentFirewall mIntentFirewall; 349 350 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 351 // default actuion automatically. Important for devices without direct input 352 // devices. 353 private boolean mShowDialogs = true; 354 355 /** 356 * Description of a request to start a new activity, which has been held 357 * due to app switches being disabled. 358 */ 359 static class PendingActivityLaunch { 360 final ActivityRecord r; 361 final ActivityRecord sourceRecord; 362 final int startFlags; 363 final ActivityStack stack; 364 365 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 366 int _startFlags, ActivityStack _stack) { 367 r = _r; 368 sourceRecord = _sourceRecord; 369 startFlags = _startFlags; 370 stack = _stack; 371 } 372 } 373 374 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 375 = new ArrayList<PendingActivityLaunch>(); 376 377 BroadcastQueue mFgBroadcastQueue; 378 BroadcastQueue mBgBroadcastQueue; 379 // Convenient for easy iteration over the queues. Foreground is first 380 // so that dispatch of foreground broadcasts gets precedence. 381 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 382 383 BroadcastQueue broadcastQueueForIntent(Intent intent) { 384 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 385 if (DEBUG_BACKGROUND_BROADCAST) { 386 Slog.i(TAG, "Broadcast intent " + intent + " on " 387 + (isFg ? "foreground" : "background") 388 + " queue"); 389 } 390 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 391 } 392 393 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 394 for (BroadcastQueue queue : mBroadcastQueues) { 395 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 396 if (r != null) { 397 return r; 398 } 399 } 400 return null; 401 } 402 403 /** 404 * Activity we have told the window manager to have key focus. 405 */ 406 ActivityRecord mFocusedActivity = null; 407 408 /** 409 * List of intents that were used to start the most recent tasks. 410 */ 411 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 412 413 public class PendingAssistExtras extends Binder implements Runnable { 414 public final ActivityRecord activity; 415 public boolean haveResult = false; 416 public Bundle result = null; 417 public PendingAssistExtras(ActivityRecord _activity) { 418 activity = _activity; 419 } 420 @Override 421 public void run() { 422 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 423 synchronized (this) { 424 haveResult = true; 425 notifyAll(); 426 } 427 } 428 } 429 430 final ArrayList<PendingAssistExtras> mPendingAssistExtras 431 = new ArrayList<PendingAssistExtras>(); 432 433 /** 434 * Process management. 435 */ 436 final ProcessList mProcessList = new ProcessList(); 437 438 /** 439 * All of the applications we currently have running organized by name. 440 * The keys are strings of the application package name (as 441 * returned by the package manager), and the keys are ApplicationRecord 442 * objects. 443 */ 444 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 445 446 /** 447 * Tracking long-term execution of processes to look for abuse and other 448 * bad app behavior. 449 */ 450 final ProcessStatsService mProcessStats; 451 452 /** 453 * The currently running isolated processes. 454 */ 455 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 456 457 /** 458 * Counter for assigning isolated process uids, to avoid frequently reusing the 459 * same ones. 460 */ 461 int mNextIsolatedProcessUid = 0; 462 463 /** 464 * The currently running heavy-weight process, if any. 465 */ 466 ProcessRecord mHeavyWeightProcess = null; 467 468 /** 469 * The last time that various processes have crashed. 470 */ 471 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 472 473 /** 474 * Information about a process that is currently marked as bad. 475 */ 476 static final class BadProcessInfo { 477 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 478 this.time = time; 479 this.shortMsg = shortMsg; 480 this.longMsg = longMsg; 481 this.stack = stack; 482 } 483 484 final long time; 485 final String shortMsg; 486 final String longMsg; 487 final String stack; 488 } 489 490 /** 491 * Set of applications that we consider to be bad, and will reject 492 * incoming broadcasts from (which the user has no control over). 493 * Processes are added to this set when they have crashed twice within 494 * a minimum amount of time; they are removed from it when they are 495 * later restarted (hopefully due to some user action). The value is the 496 * time it was added to the list. 497 */ 498 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 499 500 /** 501 * All of the processes we currently have running organized by pid. 502 * The keys are the pid running the application. 503 * 504 * <p>NOTE: This object is protected by its own lock, NOT the global 505 * activity manager lock! 506 */ 507 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 508 509 /** 510 * All of the processes that have been forced to be foreground. The key 511 * is the pid of the caller who requested it (we hold a death 512 * link on it). 513 */ 514 abstract class ForegroundToken implements IBinder.DeathRecipient { 515 int pid; 516 IBinder token; 517 } 518 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 519 520 /** 521 * List of records for processes that someone had tried to start before the 522 * system was ready. We don't start them at that point, but ensure they 523 * are started by the time booting is complete. 524 */ 525 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 526 527 /** 528 * List of persistent applications that are in the process 529 * of being started. 530 */ 531 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 532 533 /** 534 * Processes that are being forcibly torn down. 535 */ 536 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 537 538 /** 539 * List of running applications, sorted by recent usage. 540 * The first entry in the list is the least recently used. 541 */ 542 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 543 544 /** 545 * Where in mLruProcesses that the processes hosting activities start. 546 */ 547 int mLruProcessActivityStart = 0; 548 549 /** 550 * Where in mLruProcesses that the processes hosting services start. 551 * This is after (lower index) than mLruProcessesActivityStart. 552 */ 553 int mLruProcessServiceStart = 0; 554 555 /** 556 * List of processes that should gc as soon as things are idle. 557 */ 558 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 559 560 /** 561 * Processes we want to collect PSS data from. 562 */ 563 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 564 565 /** 566 * Last time we requested PSS data of all processes. 567 */ 568 long mLastFullPssTime = SystemClock.uptimeMillis(); 569 570 /** 571 * This is the process holding what we currently consider to be 572 * the "home" activity. 573 */ 574 ProcessRecord mHomeProcess; 575 576 /** 577 * This is the process holding the activity the user last visited that 578 * is in a different process from the one they are currently in. 579 */ 580 ProcessRecord mPreviousProcess; 581 582 /** 583 * The time at which the previous process was last visible. 584 */ 585 long mPreviousProcessVisibleTime; 586 587 /** 588 * Which uses have been started, so are allowed to run code. 589 */ 590 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 591 592 /** 593 * LRU list of history of current users. Most recently current is at the end. 594 */ 595 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 596 597 /** 598 * Constant array of the users that are currently started. 599 */ 600 int[] mStartedUserArray = new int[] { 0 }; 601 602 /** 603 * Registered observers of the user switching mechanics. 604 */ 605 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 606 = new RemoteCallbackList<IUserSwitchObserver>(); 607 608 /** 609 * Currently active user switch. 610 */ 611 Object mCurUserSwitchCallback; 612 613 /** 614 * Packages that the user has asked to have run in screen size 615 * compatibility mode instead of filling the screen. 616 */ 617 final CompatModePackages mCompatModePackages; 618 619 /** 620 * Set of IntentSenderRecord objects that are currently active. 621 */ 622 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 623 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 624 625 /** 626 * Fingerprints (hashCode()) of stack traces that we've 627 * already logged DropBox entries for. Guarded by itself. If 628 * something (rogue user app) forces this over 629 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 630 */ 631 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 632 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 633 634 /** 635 * Strict Mode background batched logging state. 636 * 637 * The string buffer is guarded by itself, and its lock is also 638 * used to determine if another batched write is already 639 * in-flight. 640 */ 641 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 642 643 /** 644 * Keeps track of all IIntentReceivers that have been registered for 645 * broadcasts. Hash keys are the receiver IBinder, hash value is 646 * a ReceiverList. 647 */ 648 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 649 new HashMap<IBinder, ReceiverList>(); 650 651 /** 652 * Resolver for broadcast intents to registered receivers. 653 * Holds BroadcastFilter (subclass of IntentFilter). 654 */ 655 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 656 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 657 @Override 658 protected boolean allowFilterResult( 659 BroadcastFilter filter, List<BroadcastFilter> dest) { 660 IBinder target = filter.receiverList.receiver.asBinder(); 661 for (int i=dest.size()-1; i>=0; i--) { 662 if (dest.get(i).receiverList.receiver.asBinder() == target) { 663 return false; 664 } 665 } 666 return true; 667 } 668 669 @Override 670 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 671 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 672 || userId == filter.owningUserId) { 673 return super.newResult(filter, match, userId); 674 } 675 return null; 676 } 677 678 @Override 679 protected BroadcastFilter[] newArray(int size) { 680 return new BroadcastFilter[size]; 681 } 682 683 @Override 684 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 685 return packageName.equals(filter.packageName); 686 } 687 }; 688 689 /** 690 * State of all active sticky broadcasts per user. Keys are the action of the 691 * sticky Intent, values are an ArrayList of all broadcasted intents with 692 * that action (which should usually be one). The SparseArray is keyed 693 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 694 * for stickies that are sent to all users. 695 */ 696 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 697 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 698 699 final ActiveServices mServices; 700 701 /** 702 * Backup/restore process management 703 */ 704 String mBackupAppName = null; 705 BackupRecord mBackupTarget = null; 706 707 final ProviderMap mProviderMap; 708 709 /** 710 * List of content providers who have clients waiting for them. The 711 * application is currently being launched and the provider will be 712 * removed from this list once it is published. 713 */ 714 final ArrayList<ContentProviderRecord> mLaunchingProviders 715 = new ArrayList<ContentProviderRecord>(); 716 717 /** 718 * File storing persisted {@link #mGrantedUriPermissions}. 719 */ 720 private final AtomicFile mGrantFile; 721 722 /** XML constants used in {@link #mGrantFile} */ 723 private static final String TAG_URI_GRANTS = "uri-grants"; 724 private static final String TAG_URI_GRANT = "uri-grant"; 725 private static final String ATTR_USER_HANDLE = "userHandle"; 726 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 727 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 728 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 729 private static final String ATTR_TARGET_PKG = "targetPkg"; 730 private static final String ATTR_URI = "uri"; 731 private static final String ATTR_MODE_FLAGS = "modeFlags"; 732 private static final String ATTR_CREATED_TIME = "createdTime"; 733 private static final String ATTR_PREFIX = "prefix"; 734 735 /** 736 * Global set of specific {@link Uri} permissions that have been granted. 737 * This optimized lookup structure maps from {@link UriPermission#targetUid} 738 * to {@link UriPermission#uri} to {@link UriPermission}. 739 */ 740 @GuardedBy("this") 741 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 742 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 743 744 public static class GrantUri { 745 public final int sourceUserId; 746 public final Uri uri; 747 public boolean prefix; 748 749 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 750 this.sourceUserId = sourceUserId; 751 this.uri = uri; 752 this.prefix = prefix; 753 } 754 755 @Override 756 public int hashCode() { 757 return toString().hashCode(); 758 } 759 760 @Override 761 public boolean equals(Object o) { 762 if (o instanceof GrantUri) { 763 GrantUri other = (GrantUri) o; 764 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 765 && prefix == other.prefix; 766 } 767 return false; 768 } 769 770 @Override 771 public String toString() { 772 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 773 if (prefix) result += " [prefix]"; 774 return result; 775 } 776 777 public String toSafeString() { 778 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 779 if (prefix) result += " [prefix]"; 780 return result; 781 } 782 783 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 784 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 785 ContentProvider.getUriWithoutUserId(uri), false); 786 } 787 } 788 789 CoreSettingsObserver mCoreSettingsObserver; 790 791 /** 792 * Thread-local storage used to carry caller permissions over through 793 * indirect content-provider access. 794 */ 795 private class Identity { 796 public int pid; 797 public int uid; 798 799 Identity(int _pid, int _uid) { 800 pid = _pid; 801 uid = _uid; 802 } 803 } 804 805 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 806 807 /** 808 * All information we have collected about the runtime performance of 809 * any user id that can impact battery performance. 810 */ 811 final BatteryStatsService mBatteryStatsService; 812 813 /** 814 * Information about component usage 815 */ 816 final UsageStatsService mUsageStatsService; 817 818 /** 819 * Information about and control over application operations 820 */ 821 final AppOpsService mAppOpsService; 822 823 /** 824 * Current configuration information. HistoryRecord objects are given 825 * a reference to this object to indicate which configuration they are 826 * currently running in, so this object must be kept immutable. 827 */ 828 Configuration mConfiguration = new Configuration(); 829 830 /** 831 * Current sequencing integer of the configuration, for skipping old 832 * configurations. 833 */ 834 int mConfigurationSeq = 0; 835 836 /** 837 * Hardware-reported OpenGLES version. 838 */ 839 final int GL_ES_VERSION; 840 841 /** 842 * List of initialization arguments to pass to all processes when binding applications to them. 843 * For example, references to the commonly used services. 844 */ 845 HashMap<String, IBinder> mAppBindArgs; 846 847 /** 848 * Temporary to avoid allocations. Protected by main lock. 849 */ 850 final StringBuilder mStringBuilder = new StringBuilder(256); 851 852 /** 853 * Used to control how we initialize the service. 854 */ 855 ComponentName mTopComponent; 856 String mTopAction = Intent.ACTION_MAIN; 857 String mTopData; 858 boolean mProcessesReady = false; 859 boolean mSystemReady = false; 860 boolean mBooting = false; 861 boolean mWaitingUpdate = false; 862 boolean mDidUpdate = false; 863 boolean mOnBattery = false; 864 boolean mLaunchWarningShown = false; 865 866 Context mContext; 867 868 int mFactoryTest; 869 870 boolean mCheckedForSetup; 871 872 /** 873 * The time at which we will allow normal application switches again, 874 * after a call to {@link #stopAppSwitches()}. 875 */ 876 long mAppSwitchesAllowedTime; 877 878 /** 879 * This is set to true after the first switch after mAppSwitchesAllowedTime 880 * is set; any switches after that will clear the time. 881 */ 882 boolean mDidAppSwitch; 883 884 /** 885 * Last time (in realtime) at which we checked for power usage. 886 */ 887 long mLastPowerCheckRealtime; 888 889 /** 890 * Last time (in uptime) at which we checked for power usage. 891 */ 892 long mLastPowerCheckUptime; 893 894 /** 895 * Set while we are wanting to sleep, to prevent any 896 * activities from being started/resumed. 897 */ 898 private boolean mSleeping = false; 899 900 /** 901 * Set while we are running a voice interaction. This overrides 902 * sleeping while it is active. 903 */ 904 private boolean mRunningVoice = false; 905 906 /** 907 * State of external calls telling us if the device is asleep. 908 */ 909 private boolean mWentToSleep = false; 910 911 /** 912 * State of external call telling us if the lock screen is shown. 913 */ 914 private boolean mLockScreenShown = false; 915 916 /** 917 * Set if we are shutting down the system, similar to sleeping. 918 */ 919 boolean mShuttingDown = false; 920 921 /** 922 * Current sequence id for oom_adj computation traversal. 923 */ 924 int mAdjSeq = 0; 925 926 /** 927 * Current sequence id for process LRU updating. 928 */ 929 int mLruSeq = 0; 930 931 /** 932 * Keep track of the non-cached/empty process we last found, to help 933 * determine how to distribute cached/empty processes next time. 934 */ 935 int mNumNonCachedProcs = 0; 936 937 /** 938 * Keep track of the number of cached hidden procs, to balance oom adj 939 * distribution between those and empty procs. 940 */ 941 int mNumCachedHiddenProcs = 0; 942 943 /** 944 * Keep track of the number of service processes we last found, to 945 * determine on the next iteration which should be B services. 946 */ 947 int mNumServiceProcs = 0; 948 int mNewNumAServiceProcs = 0; 949 int mNewNumServiceProcs = 0; 950 951 /** 952 * Allow the current computed overall memory level of the system to go down? 953 * This is set to false when we are killing processes for reasons other than 954 * memory management, so that the now smaller process list will not be taken as 955 * an indication that memory is tighter. 956 */ 957 boolean mAllowLowerMemLevel = false; 958 959 /** 960 * The last computed memory level, for holding when we are in a state that 961 * processes are going away for other reasons. 962 */ 963 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 964 965 /** 966 * The last total number of process we have, to determine if changes actually look 967 * like a shrinking number of process due to lower RAM. 968 */ 969 int mLastNumProcesses; 970 971 /** 972 * The uptime of the last time we performed idle maintenance. 973 */ 974 long mLastIdleTime = SystemClock.uptimeMillis(); 975 976 /** 977 * Total time spent with RAM that has been added in the past since the last idle time. 978 */ 979 long mLowRamTimeSinceLastIdle = 0; 980 981 /** 982 * If RAM is currently low, when that horrible situation started. 983 */ 984 long mLowRamStartTime = 0; 985 986 /** 987 * For reporting to battery stats the current top application. 988 */ 989 private String mCurResumedPackage = null; 990 private int mCurResumedUid = -1; 991 992 /** 993 * For reporting to battery stats the apps currently running foreground 994 * service. The ProcessMap is package/uid tuples; each of these contain 995 * an array of the currently foreground processes. 996 */ 997 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 998 = new ProcessMap<ArrayList<ProcessRecord>>(); 999 1000 /** 1001 * This is set if we had to do a delayed dexopt of an app before launching 1002 * it, to increase the ANR timeouts in that case. 1003 */ 1004 boolean mDidDexOpt; 1005 1006 /** 1007 * Set if the systemServer made a call to enterSafeMode. 1008 */ 1009 boolean mSafeMode; 1010 1011 String mDebugApp = null; 1012 boolean mWaitForDebugger = false; 1013 boolean mDebugTransient = false; 1014 String mOrigDebugApp = null; 1015 boolean mOrigWaitForDebugger = false; 1016 boolean mAlwaysFinishActivities = false; 1017 IActivityController mController = null; 1018 String mProfileApp = null; 1019 ProcessRecord mProfileProc = null; 1020 String mProfileFile; 1021 ParcelFileDescriptor mProfileFd; 1022 int mProfileType = 0; 1023 boolean mAutoStopProfiler = false; 1024 String mOpenGlTraceApp = null; 1025 1026 static class ProcessChangeItem { 1027 static final int CHANGE_ACTIVITIES = 1<<0; 1028 static final int CHANGE_PROCESS_STATE = 1<<1; 1029 int changes; 1030 int uid; 1031 int pid; 1032 int processState; 1033 boolean foregroundActivities; 1034 } 1035 1036 final RemoteCallbackList<IProcessObserver> mProcessObservers 1037 = new RemoteCallbackList<IProcessObserver>(); 1038 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1039 1040 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1041 = new ArrayList<ProcessChangeItem>(); 1042 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1043 = new ArrayList<ProcessChangeItem>(); 1044 1045 /** 1046 * Runtime CPU use collection thread. This object's lock is used to 1047 * protect all related state. 1048 */ 1049 final Thread mProcessCpuThread; 1050 1051 /** 1052 * Used to collect process stats when showing not responding dialog. 1053 * Protected by mProcessCpuThread. 1054 */ 1055 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1056 MONITOR_THREAD_CPU_USAGE); 1057 final AtomicLong mLastCpuTime = new AtomicLong(0); 1058 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1059 1060 long mLastWriteTime = 0; 1061 1062 /** 1063 * Used to retain an update lock when the foreground activity is in 1064 * immersive mode. 1065 */ 1066 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1067 1068 /** 1069 * Set to true after the system has finished booting. 1070 */ 1071 boolean mBooted = false; 1072 1073 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1074 int mProcessLimitOverride = -1; 1075 1076 WindowManagerService mWindowManager; 1077 1078 final ActivityThread mSystemThread; 1079 1080 int mCurrentUserId = 0; 1081 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1082 private UserManagerService mUserManager; 1083 1084 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1085 final ProcessRecord mApp; 1086 final int mPid; 1087 final IApplicationThread mAppThread; 1088 1089 AppDeathRecipient(ProcessRecord app, int pid, 1090 IApplicationThread thread) { 1091 if (localLOGV) Slog.v( 1092 TAG, "New death recipient " + this 1093 + " for thread " + thread.asBinder()); 1094 mApp = app; 1095 mPid = pid; 1096 mAppThread = thread; 1097 } 1098 1099 @Override 1100 public void binderDied() { 1101 if (localLOGV) Slog.v( 1102 TAG, "Death received in " + this 1103 + " for thread " + mAppThread.asBinder()); 1104 synchronized(ActivityManagerService.this) { 1105 appDiedLocked(mApp, mPid, mAppThread); 1106 } 1107 } 1108 } 1109 1110 static final int SHOW_ERROR_MSG = 1; 1111 static final int SHOW_NOT_RESPONDING_MSG = 2; 1112 static final int SHOW_FACTORY_ERROR_MSG = 3; 1113 static final int UPDATE_CONFIGURATION_MSG = 4; 1114 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1115 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1116 static final int SERVICE_TIMEOUT_MSG = 12; 1117 static final int UPDATE_TIME_ZONE = 13; 1118 static final int SHOW_UID_ERROR_MSG = 14; 1119 static final int IM_FEELING_LUCKY_MSG = 15; 1120 static final int PROC_START_TIMEOUT_MSG = 20; 1121 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1122 static final int KILL_APPLICATION_MSG = 22; 1123 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1124 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1125 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1126 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1127 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1128 static final int CLEAR_DNS_CACHE_MSG = 28; 1129 static final int UPDATE_HTTP_PROXY_MSG = 29; 1130 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1131 static final int DISPATCH_PROCESSES_CHANGED = 31; 1132 static final int DISPATCH_PROCESS_DIED = 32; 1133 static final int REPORT_MEM_USAGE_MSG = 33; 1134 static final int REPORT_USER_SWITCH_MSG = 34; 1135 static final int CONTINUE_USER_SWITCH_MSG = 35; 1136 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1137 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1138 static final int PERSIST_URI_GRANTS_MSG = 38; 1139 static final int REQUEST_ALL_PSS_MSG = 39; 1140 static final int START_PROFILES_MSG = 40; 1141 static final int UPDATE_TIME = 41; 1142 static final int SYSTEM_USER_START_MSG = 42; 1143 static final int SYSTEM_USER_CURRENT_MSG = 43; 1144 1145 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1146 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1147 static final int FIRST_COMPAT_MODE_MSG = 300; 1148 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1149 1150 AlertDialog mUidAlert; 1151 CompatModeDialog mCompatModeDialog; 1152 long mLastMemUsageReportTime = 0; 1153 1154 /** 1155 * Flag whether the current user is a "monkey", i.e. whether 1156 * the UI is driven by a UI automation tool. 1157 */ 1158 private boolean mUserIsMonkey; 1159 1160 final ServiceThread mHandlerThread; 1161 final MainHandler mHandler; 1162 1163 final class MainHandler extends Handler { 1164 public MainHandler(Looper looper) { 1165 super(looper, null, true); 1166 } 1167 1168 @Override 1169 public void handleMessage(Message msg) { 1170 switch (msg.what) { 1171 case SHOW_ERROR_MSG: { 1172 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1173 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1174 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1175 synchronized (ActivityManagerService.this) { 1176 ProcessRecord proc = (ProcessRecord)data.get("app"); 1177 AppErrorResult res = (AppErrorResult) data.get("result"); 1178 if (proc != null && proc.crashDialog != null) { 1179 Slog.e(TAG, "App already has crash dialog: " + proc); 1180 if (res != null) { 1181 res.set(0); 1182 } 1183 return; 1184 } 1185 if (!showBackground && UserHandle.getAppId(proc.uid) 1186 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1187 && proc.pid != MY_PID) { 1188 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1189 if (res != null) { 1190 res.set(0); 1191 } 1192 return; 1193 } 1194 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1195 Dialog d = new AppErrorDialog(mContext, 1196 ActivityManagerService.this, res, proc); 1197 d.show(); 1198 proc.crashDialog = d; 1199 } else { 1200 // The device is asleep, so just pretend that the user 1201 // saw a crash dialog and hit "force quit". 1202 if (res != null) { 1203 res.set(0); 1204 } 1205 } 1206 } 1207 1208 ensureBootCompleted(); 1209 } break; 1210 case SHOW_NOT_RESPONDING_MSG: { 1211 synchronized (ActivityManagerService.this) { 1212 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1213 ProcessRecord proc = (ProcessRecord)data.get("app"); 1214 if (proc != null && proc.anrDialog != null) { 1215 Slog.e(TAG, "App already has anr dialog: " + proc); 1216 return; 1217 } 1218 1219 Intent intent = new Intent("android.intent.action.ANR"); 1220 if (!mProcessesReady) { 1221 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1222 | Intent.FLAG_RECEIVER_FOREGROUND); 1223 } 1224 broadcastIntentLocked(null, null, intent, 1225 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1226 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1227 1228 if (mShowDialogs) { 1229 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1230 mContext, proc, (ActivityRecord)data.get("activity"), 1231 msg.arg1 != 0); 1232 d.show(); 1233 proc.anrDialog = d; 1234 } else { 1235 // Just kill the app if there is no dialog to be shown. 1236 killAppAtUsersRequest(proc, null); 1237 } 1238 } 1239 1240 ensureBootCompleted(); 1241 } break; 1242 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1243 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1244 synchronized (ActivityManagerService.this) { 1245 ProcessRecord proc = (ProcessRecord) data.get("app"); 1246 if (proc == null) { 1247 Slog.e(TAG, "App not found when showing strict mode dialog."); 1248 break; 1249 } 1250 if (proc.crashDialog != null) { 1251 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1252 return; 1253 } 1254 AppErrorResult res = (AppErrorResult) data.get("result"); 1255 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1256 Dialog d = new StrictModeViolationDialog(mContext, 1257 ActivityManagerService.this, res, proc); 1258 d.show(); 1259 proc.crashDialog = d; 1260 } else { 1261 // The device is asleep, so just pretend that the user 1262 // saw a crash dialog and hit "force quit". 1263 res.set(0); 1264 } 1265 } 1266 ensureBootCompleted(); 1267 } break; 1268 case SHOW_FACTORY_ERROR_MSG: { 1269 Dialog d = new FactoryErrorDialog( 1270 mContext, msg.getData().getCharSequence("msg")); 1271 d.show(); 1272 ensureBootCompleted(); 1273 } break; 1274 case UPDATE_CONFIGURATION_MSG: { 1275 final ContentResolver resolver = mContext.getContentResolver(); 1276 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1277 } break; 1278 case GC_BACKGROUND_PROCESSES_MSG: { 1279 synchronized (ActivityManagerService.this) { 1280 performAppGcsIfAppropriateLocked(); 1281 } 1282 } break; 1283 case WAIT_FOR_DEBUGGER_MSG: { 1284 synchronized (ActivityManagerService.this) { 1285 ProcessRecord app = (ProcessRecord)msg.obj; 1286 if (msg.arg1 != 0) { 1287 if (!app.waitedForDebugger) { 1288 Dialog d = new AppWaitingForDebuggerDialog( 1289 ActivityManagerService.this, 1290 mContext, app); 1291 app.waitDialog = d; 1292 app.waitedForDebugger = true; 1293 d.show(); 1294 } 1295 } else { 1296 if (app.waitDialog != null) { 1297 app.waitDialog.dismiss(); 1298 app.waitDialog = null; 1299 } 1300 } 1301 } 1302 } break; 1303 case SERVICE_TIMEOUT_MSG: { 1304 if (mDidDexOpt) { 1305 mDidDexOpt = false; 1306 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1307 nmsg.obj = msg.obj; 1308 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1309 return; 1310 } 1311 mServices.serviceTimeout((ProcessRecord)msg.obj); 1312 } break; 1313 case UPDATE_TIME_ZONE: { 1314 synchronized (ActivityManagerService.this) { 1315 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1316 ProcessRecord r = mLruProcesses.get(i); 1317 if (r.thread != null) { 1318 try { 1319 r.thread.updateTimeZone(); 1320 } catch (RemoteException ex) { 1321 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1322 } 1323 } 1324 } 1325 } 1326 } break; 1327 case CLEAR_DNS_CACHE_MSG: { 1328 synchronized (ActivityManagerService.this) { 1329 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1330 ProcessRecord r = mLruProcesses.get(i); 1331 if (r.thread != null) { 1332 try { 1333 r.thread.clearDnsCache(); 1334 } catch (RemoteException ex) { 1335 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1336 } 1337 } 1338 } 1339 } 1340 } break; 1341 case UPDATE_HTTP_PROXY_MSG: { 1342 ProxyInfo proxy = (ProxyInfo)msg.obj; 1343 String host = ""; 1344 String port = ""; 1345 String exclList = ""; 1346 Uri pacFileUrl = Uri.EMPTY; 1347 if (proxy != null) { 1348 host = proxy.getHost(); 1349 port = Integer.toString(proxy.getPort()); 1350 exclList = proxy.getExclusionListAsString(); 1351 pacFileUrl = proxy.getPacFileUrl(); 1352 } 1353 synchronized (ActivityManagerService.this) { 1354 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1355 ProcessRecord r = mLruProcesses.get(i); 1356 if (r.thread != null) { 1357 try { 1358 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1359 } catch (RemoteException ex) { 1360 Slog.w(TAG, "Failed to update http proxy for: " + 1361 r.info.processName); 1362 } 1363 } 1364 } 1365 } 1366 } break; 1367 case SHOW_UID_ERROR_MSG: { 1368 String title = "System UIDs Inconsistent"; 1369 String text = "UIDs on the system are inconsistent, you need to wipe your" 1370 + " data partition or your device will be unstable."; 1371 Log.e(TAG, title + ": " + text); 1372 if (mShowDialogs) { 1373 // XXX This is a temporary dialog, no need to localize. 1374 AlertDialog d = new BaseErrorDialog(mContext); 1375 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1376 d.setCancelable(false); 1377 d.setTitle(title); 1378 d.setMessage(text); 1379 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1380 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1381 mUidAlert = d; 1382 d.show(); 1383 } 1384 } break; 1385 case IM_FEELING_LUCKY_MSG: { 1386 if (mUidAlert != null) { 1387 mUidAlert.dismiss(); 1388 mUidAlert = null; 1389 } 1390 } break; 1391 case PROC_START_TIMEOUT_MSG: { 1392 if (mDidDexOpt) { 1393 mDidDexOpt = false; 1394 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1395 nmsg.obj = msg.obj; 1396 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1397 return; 1398 } 1399 ProcessRecord app = (ProcessRecord)msg.obj; 1400 synchronized (ActivityManagerService.this) { 1401 processStartTimedOutLocked(app); 1402 } 1403 } break; 1404 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1405 synchronized (ActivityManagerService.this) { 1406 doPendingActivityLaunchesLocked(true); 1407 } 1408 } break; 1409 case KILL_APPLICATION_MSG: { 1410 synchronized (ActivityManagerService.this) { 1411 int appid = msg.arg1; 1412 boolean restart = (msg.arg2 == 1); 1413 Bundle bundle = (Bundle)msg.obj; 1414 String pkg = bundle.getString("pkg"); 1415 String reason = bundle.getString("reason"); 1416 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1417 false, UserHandle.USER_ALL, reason); 1418 } 1419 } break; 1420 case FINALIZE_PENDING_INTENT_MSG: { 1421 ((PendingIntentRecord)msg.obj).completeFinalize(); 1422 } break; 1423 case POST_HEAVY_NOTIFICATION_MSG: { 1424 INotificationManager inm = NotificationManager.getService(); 1425 if (inm == null) { 1426 return; 1427 } 1428 1429 ActivityRecord root = (ActivityRecord)msg.obj; 1430 ProcessRecord process = root.app; 1431 if (process == null) { 1432 return; 1433 } 1434 1435 try { 1436 Context context = mContext.createPackageContext(process.info.packageName, 0); 1437 String text = mContext.getString(R.string.heavy_weight_notification, 1438 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1439 Notification notification = new Notification(); 1440 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1441 notification.when = 0; 1442 notification.flags = Notification.FLAG_ONGOING_EVENT; 1443 notification.tickerText = text; 1444 notification.defaults = 0; // please be quiet 1445 notification.sound = null; 1446 notification.vibrate = null; 1447 notification.setLatestEventInfo(context, text, 1448 mContext.getText(R.string.heavy_weight_notification_detail), 1449 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1450 PendingIntent.FLAG_CANCEL_CURRENT, null, 1451 new UserHandle(root.userId))); 1452 1453 try { 1454 int[] outId = new int[1]; 1455 inm.enqueueNotificationWithTag("android", "android", null, 1456 R.string.heavy_weight_notification, 1457 notification, outId, root.userId); 1458 } catch (RuntimeException e) { 1459 Slog.w(ActivityManagerService.TAG, 1460 "Error showing notification for heavy-weight app", e); 1461 } catch (RemoteException e) { 1462 } 1463 } catch (NameNotFoundException e) { 1464 Slog.w(TAG, "Unable to create context for heavy notification", e); 1465 } 1466 } break; 1467 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1468 INotificationManager inm = NotificationManager.getService(); 1469 if (inm == null) { 1470 return; 1471 } 1472 try { 1473 inm.cancelNotificationWithTag("android", null, 1474 R.string.heavy_weight_notification, msg.arg1); 1475 } catch (RuntimeException e) { 1476 Slog.w(ActivityManagerService.TAG, 1477 "Error canceling notification for service", e); 1478 } catch (RemoteException e) { 1479 } 1480 } break; 1481 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1482 synchronized (ActivityManagerService.this) { 1483 checkExcessivePowerUsageLocked(true); 1484 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1485 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1486 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1487 } 1488 } break; 1489 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1490 synchronized (ActivityManagerService.this) { 1491 ActivityRecord ar = (ActivityRecord)msg.obj; 1492 if (mCompatModeDialog != null) { 1493 if (mCompatModeDialog.mAppInfo.packageName.equals( 1494 ar.info.applicationInfo.packageName)) { 1495 return; 1496 } 1497 mCompatModeDialog.dismiss(); 1498 mCompatModeDialog = null; 1499 } 1500 if (ar != null && false) { 1501 if (mCompatModePackages.getPackageAskCompatModeLocked( 1502 ar.packageName)) { 1503 int mode = mCompatModePackages.computeCompatModeLocked( 1504 ar.info.applicationInfo); 1505 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1506 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1507 mCompatModeDialog = new CompatModeDialog( 1508 ActivityManagerService.this, mContext, 1509 ar.info.applicationInfo); 1510 mCompatModeDialog.show(); 1511 } 1512 } 1513 } 1514 } 1515 break; 1516 } 1517 case DISPATCH_PROCESSES_CHANGED: { 1518 dispatchProcessesChanged(); 1519 break; 1520 } 1521 case DISPATCH_PROCESS_DIED: { 1522 final int pid = msg.arg1; 1523 final int uid = msg.arg2; 1524 dispatchProcessDied(pid, uid); 1525 break; 1526 } 1527 case REPORT_MEM_USAGE_MSG: { 1528 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1529 Thread thread = new Thread() { 1530 @Override public void run() { 1531 final SparseArray<ProcessMemInfo> infoMap 1532 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1533 for (int i=0, N=memInfos.size(); i<N; i++) { 1534 ProcessMemInfo mi = memInfos.get(i); 1535 infoMap.put(mi.pid, mi); 1536 } 1537 updateCpuStatsNow(); 1538 synchronized (mProcessCpuThread) { 1539 final int N = mProcessCpuTracker.countStats(); 1540 for (int i=0; i<N; i++) { 1541 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1542 if (st.vsize > 0) { 1543 long pss = Debug.getPss(st.pid, null); 1544 if (pss > 0) { 1545 if (infoMap.indexOfKey(st.pid) < 0) { 1546 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1547 ProcessList.NATIVE_ADJ, -1, "native", null); 1548 mi.pss = pss; 1549 memInfos.add(mi); 1550 } 1551 } 1552 } 1553 } 1554 } 1555 1556 long totalPss = 0; 1557 for (int i=0, N=memInfos.size(); i<N; i++) { 1558 ProcessMemInfo mi = memInfos.get(i); 1559 if (mi.pss == 0) { 1560 mi.pss = Debug.getPss(mi.pid, null); 1561 } 1562 totalPss += mi.pss; 1563 } 1564 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1565 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1566 if (lhs.oomAdj != rhs.oomAdj) { 1567 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1568 } 1569 if (lhs.pss != rhs.pss) { 1570 return lhs.pss < rhs.pss ? 1 : -1; 1571 } 1572 return 0; 1573 } 1574 }); 1575 1576 StringBuilder tag = new StringBuilder(128); 1577 StringBuilder stack = new StringBuilder(128); 1578 tag.append("Low on memory -- "); 1579 appendMemBucket(tag, totalPss, "total", false); 1580 appendMemBucket(stack, totalPss, "total", true); 1581 1582 StringBuilder logBuilder = new StringBuilder(1024); 1583 logBuilder.append("Low on memory:\n"); 1584 1585 boolean firstLine = true; 1586 int lastOomAdj = Integer.MIN_VALUE; 1587 for (int i=0, N=memInfos.size(); i<N; i++) { 1588 ProcessMemInfo mi = memInfos.get(i); 1589 1590 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1591 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1592 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1593 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1594 if (lastOomAdj != mi.oomAdj) { 1595 lastOomAdj = mi.oomAdj; 1596 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1597 tag.append(" / "); 1598 } 1599 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1600 if (firstLine) { 1601 stack.append(":"); 1602 firstLine = false; 1603 } 1604 stack.append("\n\t at "); 1605 } else { 1606 stack.append("$"); 1607 } 1608 } else { 1609 tag.append(" "); 1610 stack.append("$"); 1611 } 1612 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1613 appendMemBucket(tag, mi.pss, mi.name, false); 1614 } 1615 appendMemBucket(stack, mi.pss, mi.name, true); 1616 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1617 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1618 stack.append("("); 1619 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1620 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1621 stack.append(DUMP_MEM_OOM_LABEL[k]); 1622 stack.append(":"); 1623 stack.append(DUMP_MEM_OOM_ADJ[k]); 1624 } 1625 } 1626 stack.append(")"); 1627 } 1628 } 1629 1630 logBuilder.append(" "); 1631 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1632 logBuilder.append(' '); 1633 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1634 logBuilder.append(' '); 1635 ProcessList.appendRamKb(logBuilder, mi.pss); 1636 logBuilder.append(" kB: "); 1637 logBuilder.append(mi.name); 1638 logBuilder.append(" ("); 1639 logBuilder.append(mi.pid); 1640 logBuilder.append(") "); 1641 logBuilder.append(mi.adjType); 1642 logBuilder.append('\n'); 1643 if (mi.adjReason != null) { 1644 logBuilder.append(" "); 1645 logBuilder.append(mi.adjReason); 1646 logBuilder.append('\n'); 1647 } 1648 } 1649 1650 logBuilder.append(" "); 1651 ProcessList.appendRamKb(logBuilder, totalPss); 1652 logBuilder.append(" kB: TOTAL\n"); 1653 1654 long[] infos = new long[Debug.MEMINFO_COUNT]; 1655 Debug.getMemInfo(infos); 1656 logBuilder.append(" MemInfo: "); 1657 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1658 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1659 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1660 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1661 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1662 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1663 logBuilder.append(" ZRAM: "); 1664 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1665 logBuilder.append(" kB RAM, "); 1666 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1667 logBuilder.append(" kB swap total, "); 1668 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1669 logBuilder.append(" kB swap free\n"); 1670 } 1671 Slog.i(TAG, logBuilder.toString()); 1672 1673 StringBuilder dropBuilder = new StringBuilder(1024); 1674 /* 1675 StringWriter oomSw = new StringWriter(); 1676 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1677 StringWriter catSw = new StringWriter(); 1678 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1679 String[] emptyArgs = new String[] { }; 1680 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1681 oomPw.flush(); 1682 String oomString = oomSw.toString(); 1683 */ 1684 dropBuilder.append(stack); 1685 dropBuilder.append('\n'); 1686 dropBuilder.append('\n'); 1687 dropBuilder.append(logBuilder); 1688 dropBuilder.append('\n'); 1689 /* 1690 dropBuilder.append(oomString); 1691 dropBuilder.append('\n'); 1692 */ 1693 StringWriter catSw = new StringWriter(); 1694 synchronized (ActivityManagerService.this) { 1695 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1696 String[] emptyArgs = new String[] { }; 1697 catPw.println(); 1698 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1699 catPw.println(); 1700 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1701 false, false, null); 1702 catPw.println(); 1703 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1704 catPw.flush(); 1705 } 1706 dropBuilder.append(catSw.toString()); 1707 addErrorToDropBox("lowmem", null, "system_server", null, 1708 null, tag.toString(), dropBuilder.toString(), null, null); 1709 //Slog.i(TAG, "Sent to dropbox:"); 1710 //Slog.i(TAG, dropBuilder.toString()); 1711 synchronized (ActivityManagerService.this) { 1712 long now = SystemClock.uptimeMillis(); 1713 if (mLastMemUsageReportTime < now) { 1714 mLastMemUsageReportTime = now; 1715 } 1716 } 1717 } 1718 }; 1719 thread.start(); 1720 break; 1721 } 1722 case REPORT_USER_SWITCH_MSG: { 1723 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1724 break; 1725 } 1726 case CONTINUE_USER_SWITCH_MSG: { 1727 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1728 break; 1729 } 1730 case USER_SWITCH_TIMEOUT_MSG: { 1731 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1732 break; 1733 } 1734 case IMMERSIVE_MODE_LOCK_MSG: { 1735 final boolean nextState = (msg.arg1 != 0); 1736 if (mUpdateLock.isHeld() != nextState) { 1737 if (DEBUG_IMMERSIVE) { 1738 final ActivityRecord r = (ActivityRecord) msg.obj; 1739 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1740 } 1741 if (nextState) { 1742 mUpdateLock.acquire(); 1743 } else { 1744 mUpdateLock.release(); 1745 } 1746 } 1747 break; 1748 } 1749 case PERSIST_URI_GRANTS_MSG: { 1750 writeGrantedUriPermissions(); 1751 break; 1752 } 1753 case REQUEST_ALL_PSS_MSG: { 1754 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1755 break; 1756 } 1757 case START_PROFILES_MSG: { 1758 synchronized (ActivityManagerService.this) { 1759 startProfilesLocked(); 1760 } 1761 break; 1762 } 1763 case UPDATE_TIME: { 1764 synchronized (ActivityManagerService.this) { 1765 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1766 ProcessRecord r = mLruProcesses.get(i); 1767 if (r.thread != null) { 1768 try { 1769 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1770 } catch (RemoteException ex) { 1771 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1772 } 1773 } 1774 } 1775 } 1776 break; 1777 } 1778 case SYSTEM_USER_START_MSG: { 1779 mSystemServiceManager.startUser(msg.arg1); 1780 break; 1781 } 1782 case SYSTEM_USER_CURRENT_MSG: { 1783 mSystemServiceManager.switchUser(msg.arg1); 1784 break; 1785 } 1786 } 1787 } 1788 }; 1789 1790 static final int COLLECT_PSS_BG_MSG = 1; 1791 1792 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1793 @Override 1794 public void handleMessage(Message msg) { 1795 switch (msg.what) { 1796 case COLLECT_PSS_BG_MSG: { 1797 int i=0, num=0; 1798 long start = SystemClock.uptimeMillis(); 1799 long[] tmp = new long[1]; 1800 do { 1801 ProcessRecord proc; 1802 int procState; 1803 int pid; 1804 synchronized (ActivityManagerService.this) { 1805 if (i >= mPendingPssProcesses.size()) { 1806 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1807 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1808 mPendingPssProcesses.clear(); 1809 return; 1810 } 1811 proc = mPendingPssProcesses.get(i); 1812 procState = proc.pssProcState; 1813 if (proc.thread != null && procState == proc.setProcState) { 1814 pid = proc.pid; 1815 } else { 1816 proc = null; 1817 pid = 0; 1818 } 1819 i++; 1820 } 1821 if (proc != null) { 1822 long pss = Debug.getPss(pid, tmp); 1823 synchronized (ActivityManagerService.this) { 1824 if (proc.thread != null && proc.setProcState == procState 1825 && proc.pid == pid) { 1826 num++; 1827 proc.lastPssTime = SystemClock.uptimeMillis(); 1828 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1829 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1830 + ": " + pss + " lastPss=" + proc.lastPss 1831 + " state=" + ProcessList.makeProcStateString(procState)); 1832 if (proc.initialIdlePss == 0) { 1833 proc.initialIdlePss = pss; 1834 } 1835 proc.lastPss = pss; 1836 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1837 proc.lastCachedPss = pss; 1838 } 1839 } 1840 } 1841 } 1842 } while (true); 1843 } 1844 } 1845 } 1846 }; 1847 1848 /** 1849 * Monitor for package changes and update our internal state. 1850 */ 1851 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1852 @Override 1853 public void onPackageRemoved(String packageName, int uid) { 1854 // Remove all tasks with activities in the specified package from the list of recent tasks 1855 synchronized (ActivityManagerService.this) { 1856 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1857 TaskRecord tr = mRecentTasks.get(i); 1858 ComponentName cn = tr.intent.getComponent(); 1859 if (cn != null && cn.getPackageName().equals(packageName)) { 1860 // If the package name matches, remove the task and kill the process 1861 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1862 } 1863 } 1864 } 1865 } 1866 1867 @Override 1868 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1869 onPackageModified(packageName); 1870 return true; 1871 } 1872 1873 @Override 1874 public void onPackageModified(String packageName) { 1875 final PackageManager pm = mContext.getPackageManager(); 1876 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1877 new ArrayList<Pair<Intent, Integer>>(); 1878 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1879 // Copy the list of recent tasks so that we don't hold onto the lock on 1880 // ActivityManagerService for long periods while checking if components exist. 1881 synchronized (ActivityManagerService.this) { 1882 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1883 TaskRecord tr = mRecentTasks.get(i); 1884 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1885 } 1886 } 1887 // Check the recent tasks and filter out all tasks with components that no longer exist. 1888 Intent tmpI = new Intent(); 1889 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1890 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1891 ComponentName cn = p.first.getComponent(); 1892 if (cn != null && cn.getPackageName().equals(packageName)) { 1893 try { 1894 // Add the task to the list to remove if the component no longer exists 1895 tmpI.setComponent(cn); 1896 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1897 tasksToRemove.add(p.second); 1898 } 1899 } catch (Exception e) {} 1900 } 1901 } 1902 // Prune all the tasks with removed components from the list of recent tasks 1903 synchronized (ActivityManagerService.this) { 1904 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1905 // Remove the task but don't kill the process (since other components in that 1906 // package may still be running and in the background) 1907 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1908 } 1909 } 1910 } 1911 1912 @Override 1913 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1914 // Force stop the specified packages 1915 if (packages != null) { 1916 for (String pkg : packages) { 1917 synchronized (ActivityManagerService.this) { 1918 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1919 "finished booting")) { 1920 return true; 1921 } 1922 } 1923 } 1924 } 1925 return false; 1926 } 1927 }; 1928 1929 public void setSystemProcess() { 1930 try { 1931 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1932 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1933 ServiceManager.addService("meminfo", new MemBinder(this)); 1934 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1935 ServiceManager.addService("dbinfo", new DbBinder(this)); 1936 if (MONITOR_CPU_USAGE) { 1937 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1938 } 1939 ServiceManager.addService("permission", new PermissionController(this)); 1940 1941 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1942 "android", STOCK_PM_FLAGS); 1943 mSystemThread.installSystemApplicationInfo(info); 1944 1945 synchronized (this) { 1946 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1947 app.persistent = true; 1948 app.pid = MY_PID; 1949 app.maxAdj = ProcessList.SYSTEM_ADJ; 1950 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1951 mProcessNames.put(app.processName, app.uid, app); 1952 synchronized (mPidsSelfLocked) { 1953 mPidsSelfLocked.put(app.pid, app); 1954 } 1955 updateLruProcessLocked(app, false, null); 1956 updateOomAdjLocked(); 1957 } 1958 } catch (PackageManager.NameNotFoundException e) { 1959 throw new RuntimeException( 1960 "Unable to find android system package", e); 1961 } 1962 } 1963 1964 public void setWindowManager(WindowManagerService wm) { 1965 mWindowManager = wm; 1966 mStackSupervisor.setWindowManager(wm); 1967 } 1968 1969 public void startObservingNativeCrashes() { 1970 final NativeCrashListener ncl = new NativeCrashListener(this); 1971 ncl.start(); 1972 } 1973 1974 public IAppOpsService getAppOpsService() { 1975 return mAppOpsService; 1976 } 1977 1978 static class MemBinder extends Binder { 1979 ActivityManagerService mActivityManagerService; 1980 MemBinder(ActivityManagerService activityManagerService) { 1981 mActivityManagerService = activityManagerService; 1982 } 1983 1984 @Override 1985 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1986 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1987 != PackageManager.PERMISSION_GRANTED) { 1988 pw.println("Permission Denial: can't dump meminfo from from pid=" 1989 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1990 + " without permission " + android.Manifest.permission.DUMP); 1991 return; 1992 } 1993 1994 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1995 } 1996 } 1997 1998 static class GraphicsBinder extends Binder { 1999 ActivityManagerService mActivityManagerService; 2000 GraphicsBinder(ActivityManagerService activityManagerService) { 2001 mActivityManagerService = activityManagerService; 2002 } 2003 2004 @Override 2005 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2006 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2007 != PackageManager.PERMISSION_GRANTED) { 2008 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2009 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2010 + " without permission " + android.Manifest.permission.DUMP); 2011 return; 2012 } 2013 2014 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2015 } 2016 } 2017 2018 static class DbBinder extends Binder { 2019 ActivityManagerService mActivityManagerService; 2020 DbBinder(ActivityManagerService activityManagerService) { 2021 mActivityManagerService = activityManagerService; 2022 } 2023 2024 @Override 2025 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2026 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2027 != PackageManager.PERMISSION_GRANTED) { 2028 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2029 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2030 + " without permission " + android.Manifest.permission.DUMP); 2031 return; 2032 } 2033 2034 mActivityManagerService.dumpDbInfo(fd, pw, args); 2035 } 2036 } 2037 2038 static class CpuBinder extends Binder { 2039 ActivityManagerService mActivityManagerService; 2040 CpuBinder(ActivityManagerService activityManagerService) { 2041 mActivityManagerService = activityManagerService; 2042 } 2043 2044 @Override 2045 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2046 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2047 != PackageManager.PERMISSION_GRANTED) { 2048 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2049 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2050 + " without permission " + android.Manifest.permission.DUMP); 2051 return; 2052 } 2053 2054 synchronized (mActivityManagerService.mProcessCpuThread) { 2055 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2056 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2057 SystemClock.uptimeMillis())); 2058 } 2059 } 2060 } 2061 2062 public static final class Lifecycle extends SystemService { 2063 private final ActivityManagerService mService; 2064 2065 public Lifecycle(Context context) { 2066 super(context); 2067 mService = new ActivityManagerService(context); 2068 } 2069 2070 @Override 2071 public void onStart() { 2072 mService.start(); 2073 } 2074 2075 public ActivityManagerService getService() { 2076 return mService; 2077 } 2078 } 2079 2080 // Note: This method is invoked on the main thread but may need to attach various 2081 // handlers to other threads. So take care to be explicit about the looper. 2082 public ActivityManagerService(Context systemContext) { 2083 mContext = systemContext; 2084 mFactoryTest = FactoryTest.getMode(); 2085 mSystemThread = ActivityThread.currentActivityThread(); 2086 2087 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2088 2089 mHandlerThread = new ServiceThread(TAG, 2090 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2091 mHandlerThread.start(); 2092 mHandler = new MainHandler(mHandlerThread.getLooper()); 2093 2094 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2095 "foreground", BROADCAST_FG_TIMEOUT, false); 2096 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2097 "background", BROADCAST_BG_TIMEOUT, true); 2098 mBroadcastQueues[0] = mFgBroadcastQueue; 2099 mBroadcastQueues[1] = mBgBroadcastQueue; 2100 2101 mServices = new ActiveServices(this); 2102 mProviderMap = new ProviderMap(this); 2103 2104 // TODO: Move creation of battery stats service outside of activity manager service. 2105 File dataDir = Environment.getDataDirectory(); 2106 File systemDir = new File(dataDir, "system"); 2107 systemDir.mkdirs(); 2108 mBatteryStatsService = new BatteryStatsService(new File( 2109 systemDir, "batterystats.bin").toString(), mHandler); 2110 mBatteryStatsService.getActiveStatistics().readLocked(); 2111 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2112 mOnBattery = DEBUG_POWER ? true 2113 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2114 mBatteryStatsService.getActiveStatistics().setCallback(this); 2115 2116 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2117 2118 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2119 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2120 2121 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2122 2123 // User 0 is the first and only user that runs at boot. 2124 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2125 mUserLru.add(Integer.valueOf(0)); 2126 updateStartedUserArrayLocked(); 2127 2128 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2129 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2130 2131 mConfiguration.setToDefaults(); 2132 mConfiguration.setLocale(Locale.getDefault()); 2133 2134 mConfigurationSeq = mConfiguration.seq = 1; 2135 mProcessCpuTracker.init(); 2136 2137 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2138 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2139 mStackSupervisor = new ActivityStackSupervisor(this); 2140 2141 mProcessCpuThread = new Thread("CpuTracker") { 2142 @Override 2143 public void run() { 2144 while (true) { 2145 try { 2146 try { 2147 synchronized(this) { 2148 final long now = SystemClock.uptimeMillis(); 2149 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2150 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2151 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2152 // + ", write delay=" + nextWriteDelay); 2153 if (nextWriteDelay < nextCpuDelay) { 2154 nextCpuDelay = nextWriteDelay; 2155 } 2156 if (nextCpuDelay > 0) { 2157 mProcessCpuMutexFree.set(true); 2158 this.wait(nextCpuDelay); 2159 } 2160 } 2161 } catch (InterruptedException e) { 2162 } 2163 updateCpuStatsNow(); 2164 } catch (Exception e) { 2165 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2166 } 2167 } 2168 } 2169 }; 2170 2171 Watchdog.getInstance().addMonitor(this); 2172 Watchdog.getInstance().addThread(mHandler); 2173 } 2174 2175 public void setSystemServiceManager(SystemServiceManager mgr) { 2176 mSystemServiceManager = mgr; 2177 } 2178 2179 private void start() { 2180 mProcessCpuThread.start(); 2181 2182 mBatteryStatsService.publish(mContext); 2183 mUsageStatsService.publish(mContext); 2184 mAppOpsService.publish(mContext); 2185 2186 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2187 } 2188 2189 @Override 2190 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2191 throws RemoteException { 2192 if (code == SYSPROPS_TRANSACTION) { 2193 // We need to tell all apps about the system property change. 2194 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2195 synchronized(this) { 2196 final int NP = mProcessNames.getMap().size(); 2197 for (int ip=0; ip<NP; ip++) { 2198 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2199 final int NA = apps.size(); 2200 for (int ia=0; ia<NA; ia++) { 2201 ProcessRecord app = apps.valueAt(ia); 2202 if (app.thread != null) { 2203 procs.add(app.thread.asBinder()); 2204 } 2205 } 2206 } 2207 } 2208 2209 int N = procs.size(); 2210 for (int i=0; i<N; i++) { 2211 Parcel data2 = Parcel.obtain(); 2212 try { 2213 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2214 } catch (RemoteException e) { 2215 } 2216 data2.recycle(); 2217 } 2218 } 2219 try { 2220 return super.onTransact(code, data, reply, flags); 2221 } catch (RuntimeException e) { 2222 // The activity manager only throws security exceptions, so let's 2223 // log all others. 2224 if (!(e instanceof SecurityException)) { 2225 Slog.wtf(TAG, "Activity Manager Crash", e); 2226 } 2227 throw e; 2228 } 2229 } 2230 2231 void updateCpuStats() { 2232 final long now = SystemClock.uptimeMillis(); 2233 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2234 return; 2235 } 2236 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2237 synchronized (mProcessCpuThread) { 2238 mProcessCpuThread.notify(); 2239 } 2240 } 2241 } 2242 2243 void updateCpuStatsNow() { 2244 synchronized (mProcessCpuThread) { 2245 mProcessCpuMutexFree.set(false); 2246 final long now = SystemClock.uptimeMillis(); 2247 boolean haveNewCpuStats = false; 2248 2249 if (MONITOR_CPU_USAGE && 2250 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2251 mLastCpuTime.set(now); 2252 haveNewCpuStats = true; 2253 mProcessCpuTracker.update(); 2254 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2255 //Slog.i(TAG, "Total CPU usage: " 2256 // + mProcessCpu.getTotalCpuPercent() + "%"); 2257 2258 // Slog the cpu usage if the property is set. 2259 if ("true".equals(SystemProperties.get("events.cpu"))) { 2260 int user = mProcessCpuTracker.getLastUserTime(); 2261 int system = mProcessCpuTracker.getLastSystemTime(); 2262 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2263 int irq = mProcessCpuTracker.getLastIrqTime(); 2264 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2265 int idle = mProcessCpuTracker.getLastIdleTime(); 2266 2267 int total = user + system + iowait + irq + softIrq + idle; 2268 if (total == 0) total = 1; 2269 2270 EventLog.writeEvent(EventLogTags.CPU, 2271 ((user+system+iowait+irq+softIrq) * 100) / total, 2272 (user * 100) / total, 2273 (system * 100) / total, 2274 (iowait * 100) / total, 2275 (irq * 100) / total, 2276 (softIrq * 100) / total); 2277 } 2278 } 2279 2280 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2281 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2282 synchronized(bstats) { 2283 synchronized(mPidsSelfLocked) { 2284 if (haveNewCpuStats) { 2285 if (mOnBattery) { 2286 int perc = bstats.startAddingCpuLocked(); 2287 int totalUTime = 0; 2288 int totalSTime = 0; 2289 final int N = mProcessCpuTracker.countStats(); 2290 for (int i=0; i<N; i++) { 2291 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2292 if (!st.working) { 2293 continue; 2294 } 2295 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2296 int otherUTime = (st.rel_utime*perc)/100; 2297 int otherSTime = (st.rel_stime*perc)/100; 2298 totalUTime += otherUTime; 2299 totalSTime += otherSTime; 2300 if (pr != null) { 2301 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2302 if (ps == null || !ps.isActive()) { 2303 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2304 pr.info.uid, pr.processName); 2305 } 2306 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2307 st.rel_stime-otherSTime); 2308 ps.addSpeedStepTimes(cpuSpeedTimes); 2309 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2310 } else { 2311 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2312 if (ps == null || !ps.isActive()) { 2313 st.batteryStats = ps = bstats.getProcessStatsLocked( 2314 bstats.mapUid(st.uid), st.name); 2315 } 2316 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2317 st.rel_stime-otherSTime); 2318 ps.addSpeedStepTimes(cpuSpeedTimes); 2319 } 2320 } 2321 bstats.finishAddingCpuLocked(perc, totalUTime, 2322 totalSTime, cpuSpeedTimes); 2323 } 2324 } 2325 } 2326 2327 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2328 mLastWriteTime = now; 2329 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2330 } 2331 } 2332 } 2333 } 2334 2335 @Override 2336 public void batteryNeedsCpuUpdate() { 2337 updateCpuStatsNow(); 2338 } 2339 2340 @Override 2341 public void batteryPowerChanged(boolean onBattery) { 2342 // When plugging in, update the CPU stats first before changing 2343 // the plug state. 2344 updateCpuStatsNow(); 2345 synchronized (this) { 2346 synchronized(mPidsSelfLocked) { 2347 mOnBattery = DEBUG_POWER ? true : onBattery; 2348 } 2349 } 2350 } 2351 2352 /** 2353 * Initialize the application bind args. These are passed to each 2354 * process when the bindApplication() IPC is sent to the process. They're 2355 * lazily setup to make sure the services are running when they're asked for. 2356 */ 2357 private HashMap<String, IBinder> getCommonServicesLocked() { 2358 if (mAppBindArgs == null) { 2359 mAppBindArgs = new HashMap<String, IBinder>(); 2360 2361 // Setup the application init args 2362 mAppBindArgs.put("package", ServiceManager.getService("package")); 2363 mAppBindArgs.put("window", ServiceManager.getService("window")); 2364 mAppBindArgs.put(Context.ALARM_SERVICE, 2365 ServiceManager.getService(Context.ALARM_SERVICE)); 2366 } 2367 return mAppBindArgs; 2368 } 2369 2370 final void setFocusedActivityLocked(ActivityRecord r) { 2371 if (mFocusedActivity != r) { 2372 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2373 mFocusedActivity = r; 2374 if (r.task != null && r.task.voiceInteractor != null) { 2375 startRunningVoiceLocked(); 2376 } else { 2377 finishRunningVoiceLocked(); 2378 } 2379 mStackSupervisor.setFocusedStack(r); 2380 if (r != null) { 2381 mWindowManager.setFocusedApp(r.appToken, true); 2382 } 2383 applyUpdateLockStateLocked(r); 2384 } 2385 } 2386 2387 final void clearFocusedActivity(ActivityRecord r) { 2388 if (mFocusedActivity == r) { 2389 mFocusedActivity = null; 2390 } 2391 } 2392 2393 @Override 2394 public void setFocusedStack(int stackId) { 2395 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2396 synchronized (ActivityManagerService.this) { 2397 ActivityStack stack = mStackSupervisor.getStack(stackId); 2398 if (stack != null) { 2399 ActivityRecord r = stack.topRunningActivityLocked(null); 2400 if (r != null) { 2401 setFocusedActivityLocked(r); 2402 } 2403 } 2404 } 2405 } 2406 2407 @Override 2408 public void notifyActivityDrawn(IBinder token) { 2409 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2410 synchronized (this) { 2411 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2412 if (r != null) { 2413 r.task.stack.notifyActivityDrawnLocked(r); 2414 } 2415 } 2416 } 2417 2418 final void applyUpdateLockStateLocked(ActivityRecord r) { 2419 // Modifications to the UpdateLock state are done on our handler, outside 2420 // the activity manager's locks. The new state is determined based on the 2421 // state *now* of the relevant activity record. The object is passed to 2422 // the handler solely for logging detail, not to be consulted/modified. 2423 final boolean nextState = r != null && r.immersive; 2424 mHandler.sendMessage( 2425 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2426 } 2427 2428 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2429 Message msg = Message.obtain(); 2430 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2431 msg.obj = r.task.askedCompatMode ? null : r; 2432 mHandler.sendMessage(msg); 2433 } 2434 2435 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2436 String what, Object obj, ProcessRecord srcApp) { 2437 app.lastActivityTime = now; 2438 2439 if (app.activities.size() > 0) { 2440 // Don't want to touch dependent processes that are hosting activities. 2441 return index; 2442 } 2443 2444 int lrui = mLruProcesses.lastIndexOf(app); 2445 if (lrui < 0) { 2446 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2447 + what + " " + obj + " from " + srcApp); 2448 return index; 2449 } 2450 2451 if (lrui >= index) { 2452 // Don't want to cause this to move dependent processes *back* in the 2453 // list as if they were less frequently used. 2454 return index; 2455 } 2456 2457 if (lrui >= mLruProcessActivityStart) { 2458 // Don't want to touch dependent processes that are hosting activities. 2459 return index; 2460 } 2461 2462 mLruProcesses.remove(lrui); 2463 if (index > 0) { 2464 index--; 2465 } 2466 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2467 + " in LRU list: " + app); 2468 mLruProcesses.add(index, app); 2469 return index; 2470 } 2471 2472 final void removeLruProcessLocked(ProcessRecord app) { 2473 int lrui = mLruProcesses.lastIndexOf(app); 2474 if (lrui >= 0) { 2475 if (lrui <= mLruProcessActivityStart) { 2476 mLruProcessActivityStart--; 2477 } 2478 if (lrui <= mLruProcessServiceStart) { 2479 mLruProcessServiceStart--; 2480 } 2481 mLruProcesses.remove(lrui); 2482 } 2483 } 2484 2485 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2486 ProcessRecord client) { 2487 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2488 || app.treatLikeActivity; 2489 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2490 if (!activityChange && hasActivity) { 2491 // The process has activities, so we are only allowing activity-based adjustments 2492 // to move it. It should be kept in the front of the list with other 2493 // processes that have activities, and we don't want those to change their 2494 // order except due to activity operations. 2495 return; 2496 } 2497 2498 mLruSeq++; 2499 final long now = SystemClock.uptimeMillis(); 2500 app.lastActivityTime = now; 2501 2502 // First a quick reject: if the app is already at the position we will 2503 // put it, then there is nothing to do. 2504 if (hasActivity) { 2505 final int N = mLruProcesses.size(); 2506 if (N > 0 && mLruProcesses.get(N-1) == app) { 2507 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2508 return; 2509 } 2510 } else { 2511 if (mLruProcessServiceStart > 0 2512 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2513 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2514 return; 2515 } 2516 } 2517 2518 int lrui = mLruProcesses.lastIndexOf(app); 2519 2520 if (app.persistent && lrui >= 0) { 2521 // We don't care about the position of persistent processes, as long as 2522 // they are in the list. 2523 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2524 return; 2525 } 2526 2527 /* In progress: compute new position first, so we can avoid doing work 2528 if the process is not actually going to move. Not yet working. 2529 int addIndex; 2530 int nextIndex; 2531 boolean inActivity = false, inService = false; 2532 if (hasActivity) { 2533 // Process has activities, put it at the very tipsy-top. 2534 addIndex = mLruProcesses.size(); 2535 nextIndex = mLruProcessServiceStart; 2536 inActivity = true; 2537 } else if (hasService) { 2538 // Process has services, put it at the top of the service list. 2539 addIndex = mLruProcessActivityStart; 2540 nextIndex = mLruProcessServiceStart; 2541 inActivity = true; 2542 inService = true; 2543 } else { 2544 // Process not otherwise of interest, it goes to the top of the non-service area. 2545 addIndex = mLruProcessServiceStart; 2546 if (client != null) { 2547 int clientIndex = mLruProcesses.lastIndexOf(client); 2548 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2549 + app); 2550 if (clientIndex >= 0 && addIndex > clientIndex) { 2551 addIndex = clientIndex; 2552 } 2553 } 2554 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2555 } 2556 2557 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2558 + mLruProcessActivityStart + "): " + app); 2559 */ 2560 2561 if (lrui >= 0) { 2562 if (lrui < mLruProcessActivityStart) { 2563 mLruProcessActivityStart--; 2564 } 2565 if (lrui < mLruProcessServiceStart) { 2566 mLruProcessServiceStart--; 2567 } 2568 /* 2569 if (addIndex > lrui) { 2570 addIndex--; 2571 } 2572 if (nextIndex > lrui) { 2573 nextIndex--; 2574 } 2575 */ 2576 mLruProcesses.remove(lrui); 2577 } 2578 2579 /* 2580 mLruProcesses.add(addIndex, app); 2581 if (inActivity) { 2582 mLruProcessActivityStart++; 2583 } 2584 if (inService) { 2585 mLruProcessActivityStart++; 2586 } 2587 */ 2588 2589 int nextIndex; 2590 if (hasActivity) { 2591 final int N = mLruProcesses.size(); 2592 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2593 // Process doesn't have activities, but has clients with 2594 // activities... move it up, but one below the top (the top 2595 // should always have a real activity). 2596 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2597 mLruProcesses.add(N-1, app); 2598 // To keep it from spamming the LRU list (by making a bunch of clients), 2599 // we will push down any other entries owned by the app. 2600 final int uid = app.info.uid; 2601 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2602 ProcessRecord subProc = mLruProcesses.get(i); 2603 if (subProc.info.uid == uid) { 2604 // We want to push this one down the list. If the process after 2605 // it is for the same uid, however, don't do so, because we don't 2606 // want them internally to be re-ordered. 2607 if (mLruProcesses.get(i-1).info.uid != uid) { 2608 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2609 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2610 ProcessRecord tmp = mLruProcesses.get(i); 2611 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2612 mLruProcesses.set(i-1, tmp); 2613 i--; 2614 } 2615 } else { 2616 // A gap, we can stop here. 2617 break; 2618 } 2619 } 2620 } else { 2621 // Process has activities, put it at the very tipsy-top. 2622 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2623 mLruProcesses.add(app); 2624 } 2625 nextIndex = mLruProcessServiceStart; 2626 } else if (hasService) { 2627 // Process has services, put it at the top of the service list. 2628 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2629 mLruProcesses.add(mLruProcessActivityStart, app); 2630 nextIndex = mLruProcessServiceStart; 2631 mLruProcessActivityStart++; 2632 } else { 2633 // Process not otherwise of interest, it goes to the top of the non-service area. 2634 int index = mLruProcessServiceStart; 2635 if (client != null) { 2636 // If there is a client, don't allow the process to be moved up higher 2637 // in the list than that client. 2638 int clientIndex = mLruProcesses.lastIndexOf(client); 2639 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2640 + " when updating " + app); 2641 if (clientIndex <= lrui) { 2642 // Don't allow the client index restriction to push it down farther in the 2643 // list than it already is. 2644 clientIndex = lrui; 2645 } 2646 if (clientIndex >= 0 && index > clientIndex) { 2647 index = clientIndex; 2648 } 2649 } 2650 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2651 mLruProcesses.add(index, app); 2652 nextIndex = index-1; 2653 mLruProcessActivityStart++; 2654 mLruProcessServiceStart++; 2655 } 2656 2657 // If the app is currently using a content provider or service, 2658 // bump those processes as well. 2659 for (int j=app.connections.size()-1; j>=0; j--) { 2660 ConnectionRecord cr = app.connections.valueAt(j); 2661 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2662 && cr.binding.service.app != null 2663 && cr.binding.service.app.lruSeq != mLruSeq 2664 && !cr.binding.service.app.persistent) { 2665 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2666 "service connection", cr, app); 2667 } 2668 } 2669 for (int j=app.conProviders.size()-1; j>=0; j--) { 2670 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2671 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2672 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2673 "provider reference", cpr, app); 2674 } 2675 } 2676 } 2677 2678 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2679 if (uid == Process.SYSTEM_UID) { 2680 // The system gets to run in any process. If there are multiple 2681 // processes with the same uid, just pick the first (this 2682 // should never happen). 2683 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2684 if (procs == null) return null; 2685 final int N = procs.size(); 2686 for (int i = 0; i < N; i++) { 2687 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2688 } 2689 } 2690 ProcessRecord proc = mProcessNames.get(processName, uid); 2691 if (false && proc != null && !keepIfLarge 2692 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2693 && proc.lastCachedPss >= 4000) { 2694 // Turn this condition on to cause killing to happen regularly, for testing. 2695 if (proc.baseProcessTracker != null) { 2696 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2697 } 2698 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2699 + "k from cached"); 2700 } else if (proc != null && !keepIfLarge 2701 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2702 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2703 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2704 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2705 if (proc.baseProcessTracker != null) { 2706 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2707 } 2708 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2709 + "k from cached"); 2710 } 2711 } 2712 return proc; 2713 } 2714 2715 void ensurePackageDexOpt(String packageName) { 2716 IPackageManager pm = AppGlobals.getPackageManager(); 2717 try { 2718 if (pm.performDexOpt(packageName)) { 2719 mDidDexOpt = true; 2720 } 2721 } catch (RemoteException e) { 2722 } 2723 } 2724 2725 boolean isNextTransitionForward() { 2726 int transit = mWindowManager.getPendingAppTransition(); 2727 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2728 || transit == AppTransition.TRANSIT_TASK_OPEN 2729 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2730 } 2731 2732 final ProcessRecord startProcessLocked(String processName, 2733 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2734 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2735 boolean isolated, boolean keepIfLarge) { 2736 ProcessRecord app; 2737 if (!isolated) { 2738 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2739 } else { 2740 // If this is an isolated process, it can't re-use an existing process. 2741 app = null; 2742 } 2743 // We don't have to do anything more if: 2744 // (1) There is an existing application record; and 2745 // (2) The caller doesn't think it is dead, OR there is no thread 2746 // object attached to it so we know it couldn't have crashed; and 2747 // (3) There is a pid assigned to it, so it is either starting or 2748 // already running. 2749 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2750 + " app=" + app + " knownToBeDead=" + knownToBeDead 2751 + " thread=" + (app != null ? app.thread : null) 2752 + " pid=" + (app != null ? app.pid : -1)); 2753 if (app != null && app.pid > 0) { 2754 if (!knownToBeDead || app.thread == null) { 2755 // We already have the app running, or are waiting for it to 2756 // come up (we have a pid but not yet its thread), so keep it. 2757 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2758 // If this is a new package in the process, add the package to the list 2759 app.addPackage(info.packageName, mProcessStats); 2760 return app; 2761 } 2762 2763 // An application record is attached to a previous process, 2764 // clean it up now. 2765 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2766 handleAppDiedLocked(app, true, true); 2767 } 2768 2769 String hostingNameStr = hostingName != null 2770 ? hostingName.flattenToShortString() : null; 2771 2772 if (!isolated) { 2773 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2774 // If we are in the background, then check to see if this process 2775 // is bad. If so, we will just silently fail. 2776 if (mBadProcesses.get(info.processName, info.uid) != null) { 2777 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2778 + "/" + info.processName); 2779 return null; 2780 } 2781 } else { 2782 // When the user is explicitly starting a process, then clear its 2783 // crash count so that we won't make it bad until they see at 2784 // least one crash dialog again, and make the process good again 2785 // if it had been bad. 2786 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2787 + "/" + info.processName); 2788 mProcessCrashTimes.remove(info.processName, info.uid); 2789 if (mBadProcesses.get(info.processName, info.uid) != null) { 2790 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2791 UserHandle.getUserId(info.uid), info.uid, 2792 info.processName); 2793 mBadProcesses.remove(info.processName, info.uid); 2794 if (app != null) { 2795 app.bad = false; 2796 } 2797 } 2798 } 2799 } 2800 2801 if (app == null) { 2802 app = newProcessRecordLocked(info, processName, isolated); 2803 if (app == null) { 2804 Slog.w(TAG, "Failed making new process record for " 2805 + processName + "/" + info.uid + " isolated=" + isolated); 2806 return null; 2807 } 2808 mProcessNames.put(processName, app.uid, app); 2809 if (isolated) { 2810 mIsolatedProcesses.put(app.uid, app); 2811 } 2812 } else { 2813 // If this is a new package in the process, add the package to the list 2814 app.addPackage(info.packageName, mProcessStats); 2815 } 2816 2817 // If the system is not ready yet, then hold off on starting this 2818 // process until it is. 2819 if (!mProcessesReady 2820 && !isAllowedWhileBooting(info) 2821 && !allowWhileBooting) { 2822 if (!mProcessesOnHold.contains(app)) { 2823 mProcessesOnHold.add(app); 2824 } 2825 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2826 return app; 2827 } 2828 2829 startProcessLocked(app, hostingType, hostingNameStr); 2830 return (app.pid != 0) ? app : null; 2831 } 2832 2833 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2834 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2835 } 2836 2837 private final void startProcessLocked(ProcessRecord app, 2838 String hostingType, String hostingNameStr) { 2839 if (app.pid > 0 && app.pid != MY_PID) { 2840 synchronized (mPidsSelfLocked) { 2841 mPidsSelfLocked.remove(app.pid); 2842 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2843 } 2844 app.setPid(0); 2845 } 2846 2847 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2848 "startProcessLocked removing on hold: " + app); 2849 mProcessesOnHold.remove(app); 2850 2851 updateCpuStats(); 2852 2853 try { 2854 int uid = app.uid; 2855 2856 int[] gids = null; 2857 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2858 if (!app.isolated) { 2859 int[] permGids = null; 2860 try { 2861 final PackageManager pm = mContext.getPackageManager(); 2862 permGids = pm.getPackageGids(app.info.packageName); 2863 2864 if (Environment.isExternalStorageEmulated()) { 2865 if (pm.checkPermission( 2866 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2867 app.info.packageName) == PERMISSION_GRANTED) { 2868 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2869 } else { 2870 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2871 } 2872 } 2873 } catch (PackageManager.NameNotFoundException e) { 2874 Slog.w(TAG, "Unable to retrieve gids", e); 2875 } 2876 2877 /* 2878 * Add shared application GID so applications can share some 2879 * resources like shared libraries 2880 */ 2881 if (permGids == null) { 2882 gids = new int[1]; 2883 } else { 2884 gids = new int[permGids.length + 1]; 2885 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2886 } 2887 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2888 } 2889 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2890 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2891 && mTopComponent != null 2892 && app.processName.equals(mTopComponent.getPackageName())) { 2893 uid = 0; 2894 } 2895 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2896 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2897 uid = 0; 2898 } 2899 } 2900 int debugFlags = 0; 2901 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2902 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2903 // Also turn on CheckJNI for debuggable apps. It's quite 2904 // awkward to turn on otherwise. 2905 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2906 } 2907 // Run the app in safe mode if its manifest requests so or the 2908 // system is booted in safe mode. 2909 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2910 mSafeMode == true) { 2911 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2912 } 2913 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2914 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2915 } 2916 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2917 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2918 } 2919 if ("1".equals(SystemProperties.get("debug.assert"))) { 2920 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2921 } 2922 2923 String requiredAbi = app.info.requiredCpuAbi; 2924 if (requiredAbi == null) { 2925 requiredAbi = Build.SUPPORTED_ABIS[0]; 2926 } 2927 2928 // Start the process. It will either succeed and return a result containing 2929 // the PID of the new process, or else throw a RuntimeException. 2930 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2931 app.processName, uid, uid, gids, debugFlags, mountExternal, 2932 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2933 2934 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2935 synchronized (bs) { 2936 if (bs.isOnBattery()) { 2937 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2938 } 2939 } 2940 2941 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2942 UserHandle.getUserId(uid), startResult.pid, uid, 2943 app.processName, hostingType, 2944 hostingNameStr != null ? hostingNameStr : ""); 2945 2946 if (app.persistent) { 2947 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2948 } 2949 2950 StringBuilder buf = mStringBuilder; 2951 buf.setLength(0); 2952 buf.append("Start proc "); 2953 buf.append(app.processName); 2954 buf.append(" for "); 2955 buf.append(hostingType); 2956 if (hostingNameStr != null) { 2957 buf.append(" "); 2958 buf.append(hostingNameStr); 2959 } 2960 buf.append(": pid="); 2961 buf.append(startResult.pid); 2962 buf.append(" uid="); 2963 buf.append(uid); 2964 buf.append(" gids={"); 2965 if (gids != null) { 2966 for (int gi=0; gi<gids.length; gi++) { 2967 if (gi != 0) buf.append(", "); 2968 buf.append(gids[gi]); 2969 2970 } 2971 } 2972 buf.append("}"); 2973 Slog.i(TAG, buf.toString()); 2974 app.setPid(startResult.pid); 2975 app.usingWrapper = startResult.usingWrapper; 2976 app.removed = false; 2977 synchronized (mPidsSelfLocked) { 2978 this.mPidsSelfLocked.put(startResult.pid, app); 2979 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2980 msg.obj = app; 2981 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2982 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2983 } 2984 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2985 app.processName, app.info.uid); 2986 if (app.isolated) { 2987 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2988 } 2989 } catch (RuntimeException e) { 2990 // XXX do better error recovery. 2991 app.setPid(0); 2992 Slog.e(TAG, "Failure starting process " + app.processName, e); 2993 } 2994 } 2995 2996 void updateUsageStats(ActivityRecord component, boolean resumed) { 2997 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2998 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2999 if (resumed) { 3000 mUsageStatsService.noteResumeComponent(component.realActivity); 3001 synchronized (stats) { 3002 stats.noteActivityResumedLocked(component.app.uid); 3003 } 3004 } else { 3005 mUsageStatsService.notePauseComponent(component.realActivity); 3006 synchronized (stats) { 3007 stats.noteActivityPausedLocked(component.app.uid); 3008 } 3009 } 3010 } 3011 3012 Intent getHomeIntent() { 3013 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3014 intent.setComponent(mTopComponent); 3015 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3016 intent.addCategory(Intent.CATEGORY_HOME); 3017 } 3018 return intent; 3019 } 3020 3021 boolean startHomeActivityLocked(int userId) { 3022 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3023 && mTopAction == null) { 3024 // We are running in factory test mode, but unable to find 3025 // the factory test app, so just sit around displaying the 3026 // error message and don't try to start anything. 3027 return false; 3028 } 3029 Intent intent = getHomeIntent(); 3030 ActivityInfo aInfo = 3031 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3032 if (aInfo != null) { 3033 intent.setComponent(new ComponentName( 3034 aInfo.applicationInfo.packageName, aInfo.name)); 3035 // Don't do this if the home app is currently being 3036 // instrumented. 3037 aInfo = new ActivityInfo(aInfo); 3038 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3039 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3040 aInfo.applicationInfo.uid, true); 3041 if (app == null || app.instrumentationClass == null) { 3042 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3043 mStackSupervisor.startHomeActivity(intent, aInfo); 3044 } 3045 } 3046 3047 return true; 3048 } 3049 3050 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3051 ActivityInfo ai = null; 3052 ComponentName comp = intent.getComponent(); 3053 try { 3054 if (comp != null) { 3055 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3056 } else { 3057 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3058 intent, 3059 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3060 flags, userId); 3061 3062 if (info != null) { 3063 ai = info.activityInfo; 3064 } 3065 } 3066 } catch (RemoteException e) { 3067 // ignore 3068 } 3069 3070 return ai; 3071 } 3072 3073 /** 3074 * Starts the "new version setup screen" if appropriate. 3075 */ 3076 void startSetupActivityLocked() { 3077 // Only do this once per boot. 3078 if (mCheckedForSetup) { 3079 return; 3080 } 3081 3082 // We will show this screen if the current one is a different 3083 // version than the last one shown, and we are not running in 3084 // low-level factory test mode. 3085 final ContentResolver resolver = mContext.getContentResolver(); 3086 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3087 Settings.Global.getInt(resolver, 3088 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3089 mCheckedForSetup = true; 3090 3091 // See if we should be showing the platform update setup UI. 3092 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3093 List<ResolveInfo> ris = mContext.getPackageManager() 3094 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3095 3096 // We don't allow third party apps to replace this. 3097 ResolveInfo ri = null; 3098 for (int i=0; ris != null && i<ris.size(); i++) { 3099 if ((ris.get(i).activityInfo.applicationInfo.flags 3100 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3101 ri = ris.get(i); 3102 break; 3103 } 3104 } 3105 3106 if (ri != null) { 3107 String vers = ri.activityInfo.metaData != null 3108 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3109 : null; 3110 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3111 vers = ri.activityInfo.applicationInfo.metaData.getString( 3112 Intent.METADATA_SETUP_VERSION); 3113 } 3114 String lastVers = Settings.Secure.getString( 3115 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3116 if (vers != null && !vers.equals(lastVers)) { 3117 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3118 intent.setComponent(new ComponentName( 3119 ri.activityInfo.packageName, ri.activityInfo.name)); 3120 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3121 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3122 } 3123 } 3124 } 3125 } 3126 3127 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3128 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3129 } 3130 3131 void enforceNotIsolatedCaller(String caller) { 3132 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3133 throw new SecurityException("Isolated process not allowed to call " + caller); 3134 } 3135 } 3136 3137 @Override 3138 public int getFrontActivityScreenCompatMode() { 3139 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3140 synchronized (this) { 3141 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3142 } 3143 } 3144 3145 @Override 3146 public void setFrontActivityScreenCompatMode(int mode) { 3147 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3148 "setFrontActivityScreenCompatMode"); 3149 synchronized (this) { 3150 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3151 } 3152 } 3153 3154 @Override 3155 public int getPackageScreenCompatMode(String packageName) { 3156 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3157 synchronized (this) { 3158 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3159 } 3160 } 3161 3162 @Override 3163 public void setPackageScreenCompatMode(String packageName, int mode) { 3164 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3165 "setPackageScreenCompatMode"); 3166 synchronized (this) { 3167 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3168 } 3169 } 3170 3171 @Override 3172 public boolean getPackageAskScreenCompat(String packageName) { 3173 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3174 synchronized (this) { 3175 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3176 } 3177 } 3178 3179 @Override 3180 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3181 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3182 "setPackageAskScreenCompat"); 3183 synchronized (this) { 3184 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3185 } 3186 } 3187 3188 private void dispatchProcessesChanged() { 3189 int N; 3190 synchronized (this) { 3191 N = mPendingProcessChanges.size(); 3192 if (mActiveProcessChanges.length < N) { 3193 mActiveProcessChanges = new ProcessChangeItem[N]; 3194 } 3195 mPendingProcessChanges.toArray(mActiveProcessChanges); 3196 mAvailProcessChanges.addAll(mPendingProcessChanges); 3197 mPendingProcessChanges.clear(); 3198 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3199 } 3200 3201 int i = mProcessObservers.beginBroadcast(); 3202 while (i > 0) { 3203 i--; 3204 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3205 if (observer != null) { 3206 try { 3207 for (int j=0; j<N; j++) { 3208 ProcessChangeItem item = mActiveProcessChanges[j]; 3209 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3210 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3211 + item.pid + " uid=" + item.uid + ": " 3212 + item.foregroundActivities); 3213 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3214 item.foregroundActivities); 3215 } 3216 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3217 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3218 + item.pid + " uid=" + item.uid + ": " + item.processState); 3219 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3220 } 3221 } 3222 } catch (RemoteException e) { 3223 } 3224 } 3225 } 3226 mProcessObservers.finishBroadcast(); 3227 } 3228 3229 private void dispatchProcessDied(int pid, int uid) { 3230 int i = mProcessObservers.beginBroadcast(); 3231 while (i > 0) { 3232 i--; 3233 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3234 if (observer != null) { 3235 try { 3236 observer.onProcessDied(pid, uid); 3237 } catch (RemoteException e) { 3238 } 3239 } 3240 } 3241 mProcessObservers.finishBroadcast(); 3242 } 3243 3244 final void doPendingActivityLaunchesLocked(boolean doResume) { 3245 final int N = mPendingActivityLaunches.size(); 3246 if (N <= 0) { 3247 return; 3248 } 3249 for (int i=0; i<N; i++) { 3250 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3251 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3252 doResume && i == (N-1), null); 3253 } 3254 mPendingActivityLaunches.clear(); 3255 } 3256 3257 @Override 3258 public final int startActivity(IApplicationThread caller, String callingPackage, 3259 Intent intent, String resolvedType, IBinder resultTo, 3260 String resultWho, int requestCode, int startFlags, 3261 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3262 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3263 resultWho, requestCode, 3264 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3265 } 3266 3267 @Override 3268 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3269 Intent intent, String resolvedType, IBinder resultTo, 3270 String resultWho, int requestCode, int startFlags, 3271 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3272 enforceNotIsolatedCaller("startActivity"); 3273 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3274 false, true, "startActivity", null); 3275 // TODO: Switch to user app stacks here. 3276 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3277 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3278 null, null, options, userId, null); 3279 } 3280 3281 @Override 3282 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3283 Intent intent, String resolvedType, IBinder resultTo, 3284 String resultWho, int requestCode, int startFlags, String profileFile, 3285 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3286 enforceNotIsolatedCaller("startActivityAndWait"); 3287 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3288 false, true, "startActivityAndWait", null); 3289 WaitResult res = new WaitResult(); 3290 // TODO: Switch to user app stacks here. 3291 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3292 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3293 res, null, options, UserHandle.getCallingUserId(), null); 3294 return res; 3295 } 3296 3297 @Override 3298 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3299 Intent intent, String resolvedType, IBinder resultTo, 3300 String resultWho, int requestCode, int startFlags, Configuration config, 3301 Bundle options, int userId) { 3302 enforceNotIsolatedCaller("startActivityWithConfig"); 3303 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3304 false, true, "startActivityWithConfig", null); 3305 // TODO: Switch to user app stacks here. 3306 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3307 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3308 null, null, null, config, options, userId, null); 3309 return ret; 3310 } 3311 3312 @Override 3313 public int startActivityIntentSender(IApplicationThread caller, 3314 IntentSender intent, Intent fillInIntent, String resolvedType, 3315 IBinder resultTo, String resultWho, int requestCode, 3316 int flagsMask, int flagsValues, Bundle options) { 3317 enforceNotIsolatedCaller("startActivityIntentSender"); 3318 // Refuse possible leaked file descriptors 3319 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3320 throw new IllegalArgumentException("File descriptors passed in Intent"); 3321 } 3322 3323 IIntentSender sender = intent.getTarget(); 3324 if (!(sender instanceof PendingIntentRecord)) { 3325 throw new IllegalArgumentException("Bad PendingIntent object"); 3326 } 3327 3328 PendingIntentRecord pir = (PendingIntentRecord)sender; 3329 3330 synchronized (this) { 3331 // If this is coming from the currently resumed activity, it is 3332 // effectively saying that app switches are allowed at this point. 3333 final ActivityStack stack = getFocusedStack(); 3334 if (stack.mResumedActivity != null && 3335 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3336 mAppSwitchesAllowedTime = 0; 3337 } 3338 } 3339 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3340 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3341 return ret; 3342 } 3343 3344 @Override 3345 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3346 Intent intent, String resolvedType, IVoiceInteractionSession session, 3347 IVoiceInteractor interactor, int startFlags, String profileFile, 3348 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3349 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3350 != PackageManager.PERMISSION_GRANTED) { 3351 String msg = "Permission Denial: startVoiceActivity() from pid=" 3352 + Binder.getCallingPid() 3353 + ", uid=" + Binder.getCallingUid() 3354 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3355 Slog.w(TAG, msg); 3356 throw new SecurityException(msg); 3357 } 3358 if (session == null || interactor == null) { 3359 throw new NullPointerException("null session or interactor"); 3360 } 3361 userId = handleIncomingUser(callingPid, callingUid, userId, 3362 false, true, "startVoiceActivity", null); 3363 // TODO: Switch to user app stacks here. 3364 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3365 resolvedType, session, interactor, null, null, 0, startFlags, 3366 profileFile, profileFd, null, null, options, userId, null); 3367 } 3368 3369 @Override 3370 public boolean startNextMatchingActivity(IBinder callingActivity, 3371 Intent intent, Bundle options) { 3372 // Refuse possible leaked file descriptors 3373 if (intent != null && intent.hasFileDescriptors() == true) { 3374 throw new IllegalArgumentException("File descriptors passed in Intent"); 3375 } 3376 3377 synchronized (this) { 3378 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3379 if (r == null) { 3380 ActivityOptions.abort(options); 3381 return false; 3382 } 3383 if (r.app == null || r.app.thread == null) { 3384 // The caller is not running... d'oh! 3385 ActivityOptions.abort(options); 3386 return false; 3387 } 3388 intent = new Intent(intent); 3389 // The caller is not allowed to change the data. 3390 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3391 // And we are resetting to find the next component... 3392 intent.setComponent(null); 3393 3394 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3395 3396 ActivityInfo aInfo = null; 3397 try { 3398 List<ResolveInfo> resolves = 3399 AppGlobals.getPackageManager().queryIntentActivities( 3400 intent, r.resolvedType, 3401 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3402 UserHandle.getCallingUserId()); 3403 3404 // Look for the original activity in the list... 3405 final int N = resolves != null ? resolves.size() : 0; 3406 for (int i=0; i<N; i++) { 3407 ResolveInfo rInfo = resolves.get(i); 3408 if (rInfo.activityInfo.packageName.equals(r.packageName) 3409 && rInfo.activityInfo.name.equals(r.info.name)) { 3410 // We found the current one... the next matching is 3411 // after it. 3412 i++; 3413 if (i<N) { 3414 aInfo = resolves.get(i).activityInfo; 3415 } 3416 if (debug) { 3417 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3418 + "/" + r.info.name); 3419 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3420 + "/" + aInfo.name); 3421 } 3422 break; 3423 } 3424 } 3425 } catch (RemoteException e) { 3426 } 3427 3428 if (aInfo == null) { 3429 // Nobody who is next! 3430 ActivityOptions.abort(options); 3431 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3432 return false; 3433 } 3434 3435 intent.setComponent(new ComponentName( 3436 aInfo.applicationInfo.packageName, aInfo.name)); 3437 intent.setFlags(intent.getFlags()&~( 3438 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3439 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3440 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3441 Intent.FLAG_ACTIVITY_NEW_TASK)); 3442 3443 // Okay now we need to start the new activity, replacing the 3444 // currently running activity. This is a little tricky because 3445 // we want to start the new one as if the current one is finished, 3446 // but not finish the current one first so that there is no flicker. 3447 // And thus... 3448 final boolean wasFinishing = r.finishing; 3449 r.finishing = true; 3450 3451 // Propagate reply information over to the new activity. 3452 final ActivityRecord resultTo = r.resultTo; 3453 final String resultWho = r.resultWho; 3454 final int requestCode = r.requestCode; 3455 r.resultTo = null; 3456 if (resultTo != null) { 3457 resultTo.removeResultsLocked(r, resultWho, requestCode); 3458 } 3459 3460 final long origId = Binder.clearCallingIdentity(); 3461 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3462 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3463 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3464 options, false, null, null); 3465 Binder.restoreCallingIdentity(origId); 3466 3467 r.finishing = wasFinishing; 3468 if (res != ActivityManager.START_SUCCESS) { 3469 return false; 3470 } 3471 return true; 3472 } 3473 } 3474 3475 final int startActivityInPackage(int uid, String callingPackage, 3476 Intent intent, String resolvedType, IBinder resultTo, 3477 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3478 IActivityContainer container) { 3479 3480 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3481 false, true, "startActivityInPackage", null); 3482 3483 // TODO: Switch to user app stacks here. 3484 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3485 null, null, resultTo, resultWho, requestCode, startFlags, 3486 null, null, null, null, options, userId, container); 3487 return ret; 3488 } 3489 3490 @Override 3491 public final int startActivities(IApplicationThread caller, String callingPackage, 3492 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3493 int userId) { 3494 enforceNotIsolatedCaller("startActivities"); 3495 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3496 false, true, "startActivity", null); 3497 // TODO: Switch to user app stacks here. 3498 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3499 resolvedTypes, resultTo, options, userId); 3500 return ret; 3501 } 3502 3503 final int startActivitiesInPackage(int uid, String callingPackage, 3504 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3505 Bundle options, int userId) { 3506 3507 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3508 false, true, "startActivityInPackage", null); 3509 // TODO: Switch to user app stacks here. 3510 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3511 resultTo, options, userId); 3512 return ret; 3513 } 3514 3515 final void addRecentTaskLocked(TaskRecord task) { 3516 int N = mRecentTasks.size(); 3517 // Quick case: check if the top-most recent task is the same. 3518 if (N > 0 && mRecentTasks.get(0) == task) { 3519 return; 3520 } 3521 // Another quick case: never add voice sessions. 3522 if (task.voiceSession != null) { 3523 return; 3524 } 3525 // Remove any existing entries that are the same kind of task. 3526 final Intent intent = task.intent; 3527 final boolean document = intent != null && intent.isDocument(); 3528 for (int i=0; i<N; i++) { 3529 TaskRecord tr = mRecentTasks.get(i); 3530 if (task != tr) { 3531 if (task.userId != tr.userId) { 3532 continue; 3533 } 3534 final Intent trIntent = tr.intent; 3535 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3536 (intent == null || !intent.filterEquals(trIntent))) { 3537 continue; 3538 } 3539 if (document || trIntent != null && trIntent.isDocument()) { 3540 // Document tasks do not match other tasks. 3541 continue; 3542 } 3543 } 3544 3545 // Either task and tr are the same or, their affinities match or their intents match 3546 // and neither of them is a document. 3547 tr.disposeThumbnail(); 3548 mRecentTasks.remove(i); 3549 i--; 3550 N--; 3551 if (task.intent == null) { 3552 // If the new recent task we are adding is not fully 3553 // specified, then replace it with the existing recent task. 3554 task = tr; 3555 } 3556 } 3557 if (N >= MAX_RECENT_TASKS) { 3558 mRecentTasks.remove(N-1).disposeThumbnail(); 3559 } 3560 mRecentTasks.add(0, task); 3561 } 3562 3563 @Override 3564 public void reportActivityFullyDrawn(IBinder token) { 3565 synchronized (this) { 3566 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3567 if (r == null) { 3568 return; 3569 } 3570 r.reportFullyDrawnLocked(); 3571 } 3572 } 3573 3574 @Override 3575 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3576 synchronized (this) { 3577 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3578 if (r == null) { 3579 return; 3580 } 3581 final long origId = Binder.clearCallingIdentity(); 3582 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3583 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3584 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3585 if (config != null) { 3586 r.frozenBeforeDestroy = true; 3587 if (!updateConfigurationLocked(config, r, false, false)) { 3588 mStackSupervisor.resumeTopActivitiesLocked(); 3589 } 3590 } 3591 Binder.restoreCallingIdentity(origId); 3592 } 3593 } 3594 3595 @Override 3596 public int getRequestedOrientation(IBinder token) { 3597 synchronized (this) { 3598 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3599 if (r == null) { 3600 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3601 } 3602 return mWindowManager.getAppOrientation(r.appToken); 3603 } 3604 } 3605 3606 /** 3607 * This is the internal entry point for handling Activity.finish(). 3608 * 3609 * @param token The Binder token referencing the Activity we want to finish. 3610 * @param resultCode Result code, if any, from this Activity. 3611 * @param resultData Result data (Intent), if any, from this Activity. 3612 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3613 * the root Activity in the task. 3614 * 3615 * @return Returns true if the activity successfully finished, or false if it is still running. 3616 */ 3617 @Override 3618 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3619 boolean finishTask) { 3620 // Refuse possible leaked file descriptors 3621 if (resultData != null && resultData.hasFileDescriptors() == true) { 3622 throw new IllegalArgumentException("File descriptors passed in Intent"); 3623 } 3624 3625 synchronized(this) { 3626 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3627 if (r == null) { 3628 return true; 3629 } 3630 // Keep track of the root activity of the task before we finish it 3631 TaskRecord tr = r.task; 3632 ActivityRecord rootR = tr.getRootActivity(); 3633 if (mController != null) { 3634 // Find the first activity that is not finishing. 3635 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3636 if (next != null) { 3637 // ask watcher if this is allowed 3638 boolean resumeOK = true; 3639 try { 3640 resumeOK = mController.activityResuming(next.packageName); 3641 } catch (RemoteException e) { 3642 mController = null; 3643 Watchdog.getInstance().setActivityController(null); 3644 } 3645 3646 if (!resumeOK) { 3647 return false; 3648 } 3649 } 3650 } 3651 final long origId = Binder.clearCallingIdentity(); 3652 try { 3653 boolean res; 3654 if (finishTask && r == rootR) { 3655 // If requested, remove the task that is associated to this activity only if it 3656 // was the root activity in the task. The result code and data is ignored because 3657 // we don't support returning them across task boundaries. 3658 res = removeTaskByIdLocked(tr.taskId, 0); 3659 } else { 3660 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3661 resultData, "app-request", true); 3662 } 3663 return res; 3664 } finally { 3665 Binder.restoreCallingIdentity(origId); 3666 } 3667 } 3668 } 3669 3670 @Override 3671 public final void finishHeavyWeightApp() { 3672 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3673 != PackageManager.PERMISSION_GRANTED) { 3674 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3675 + Binder.getCallingPid() 3676 + ", uid=" + Binder.getCallingUid() 3677 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3678 Slog.w(TAG, msg); 3679 throw new SecurityException(msg); 3680 } 3681 3682 synchronized(this) { 3683 if (mHeavyWeightProcess == null) { 3684 return; 3685 } 3686 3687 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3688 mHeavyWeightProcess.activities); 3689 for (int i=0; i<activities.size(); i++) { 3690 ActivityRecord r = activities.get(i); 3691 if (!r.finishing) { 3692 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3693 null, "finish-heavy", true); 3694 } 3695 } 3696 3697 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3698 mHeavyWeightProcess.userId, 0)); 3699 mHeavyWeightProcess = null; 3700 } 3701 } 3702 3703 @Override 3704 public void crashApplication(int uid, int initialPid, String packageName, 3705 String message) { 3706 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3707 != PackageManager.PERMISSION_GRANTED) { 3708 String msg = "Permission Denial: crashApplication() from pid=" 3709 + Binder.getCallingPid() 3710 + ", uid=" + Binder.getCallingUid() 3711 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3712 Slog.w(TAG, msg); 3713 throw new SecurityException(msg); 3714 } 3715 3716 synchronized(this) { 3717 ProcessRecord proc = null; 3718 3719 // Figure out which process to kill. We don't trust that initialPid 3720 // still has any relation to current pids, so must scan through the 3721 // list. 3722 synchronized (mPidsSelfLocked) { 3723 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3724 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3725 if (p.uid != uid) { 3726 continue; 3727 } 3728 if (p.pid == initialPid) { 3729 proc = p; 3730 break; 3731 } 3732 if (p.pkgList.containsKey(packageName)) { 3733 proc = p; 3734 } 3735 } 3736 } 3737 3738 if (proc == null) { 3739 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3740 + " initialPid=" + initialPid 3741 + " packageName=" + packageName); 3742 return; 3743 } 3744 3745 if (proc.thread != null) { 3746 if (proc.pid == Process.myPid()) { 3747 Log.w(TAG, "crashApplication: trying to crash self!"); 3748 return; 3749 } 3750 long ident = Binder.clearCallingIdentity(); 3751 try { 3752 proc.thread.scheduleCrash(message); 3753 } catch (RemoteException e) { 3754 } 3755 Binder.restoreCallingIdentity(ident); 3756 } 3757 } 3758 } 3759 3760 @Override 3761 public final void finishSubActivity(IBinder token, String resultWho, 3762 int requestCode) { 3763 synchronized(this) { 3764 final long origId = Binder.clearCallingIdentity(); 3765 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3766 if (r != null) { 3767 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3768 } 3769 Binder.restoreCallingIdentity(origId); 3770 } 3771 } 3772 3773 @Override 3774 public boolean finishActivityAffinity(IBinder token) { 3775 synchronized(this) { 3776 final long origId = Binder.clearCallingIdentity(); 3777 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3778 boolean res = false; 3779 if (r != null) { 3780 res = r.task.stack.finishActivityAffinityLocked(r); 3781 } 3782 Binder.restoreCallingIdentity(origId); 3783 return res; 3784 } 3785 } 3786 3787 @Override 3788 public boolean willActivityBeVisible(IBinder token) { 3789 synchronized(this) { 3790 ActivityStack stack = ActivityRecord.getStackLocked(token); 3791 if (stack != null) { 3792 return stack.willActivityBeVisibleLocked(token); 3793 } 3794 return false; 3795 } 3796 } 3797 3798 @Override 3799 public void overridePendingTransition(IBinder token, String packageName, 3800 int enterAnim, int exitAnim) { 3801 synchronized(this) { 3802 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3803 if (self == null) { 3804 return; 3805 } 3806 3807 final long origId = Binder.clearCallingIdentity(); 3808 3809 if (self.state == ActivityState.RESUMED 3810 || self.state == ActivityState.PAUSING) { 3811 mWindowManager.overridePendingAppTransition(packageName, 3812 enterAnim, exitAnim, null); 3813 } 3814 3815 Binder.restoreCallingIdentity(origId); 3816 } 3817 } 3818 3819 /** 3820 * Main function for removing an existing process from the activity manager 3821 * as a result of that process going away. Clears out all connections 3822 * to the process. 3823 */ 3824 private final void handleAppDiedLocked(ProcessRecord app, 3825 boolean restarting, boolean allowRestart) { 3826 int pid = app.pid; 3827 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3828 if (!restarting) { 3829 removeLruProcessLocked(app); 3830 if (pid > 0) { 3831 ProcessList.remove(pid); 3832 } 3833 } 3834 3835 if (mProfileProc == app) { 3836 clearProfilerLocked(); 3837 } 3838 3839 // Remove this application's activities from active lists. 3840 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3841 3842 app.activities.clear(); 3843 3844 if (app.instrumentationClass != null) { 3845 Slog.w(TAG, "Crash of app " + app.processName 3846 + " running instrumentation " + app.instrumentationClass); 3847 Bundle info = new Bundle(); 3848 info.putString("shortMsg", "Process crashed."); 3849 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3850 } 3851 3852 if (!restarting) { 3853 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3854 // If there was nothing to resume, and we are not already 3855 // restarting this process, but there is a visible activity that 3856 // is hosted by the process... then make sure all visible 3857 // activities are running, taking care of restarting this 3858 // process. 3859 if (hasVisibleActivities) { 3860 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3861 } 3862 } 3863 } 3864 } 3865 3866 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3867 IBinder threadBinder = thread.asBinder(); 3868 // Find the application record. 3869 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3870 ProcessRecord rec = mLruProcesses.get(i); 3871 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3872 return i; 3873 } 3874 } 3875 return -1; 3876 } 3877 3878 final ProcessRecord getRecordForAppLocked( 3879 IApplicationThread thread) { 3880 if (thread == null) { 3881 return null; 3882 } 3883 3884 int appIndex = getLRURecordIndexForAppLocked(thread); 3885 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3886 } 3887 3888 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3889 // If there are no longer any background processes running, 3890 // and the app that died was not running instrumentation, 3891 // then tell everyone we are now low on memory. 3892 boolean haveBg = false; 3893 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3894 ProcessRecord rec = mLruProcesses.get(i); 3895 if (rec.thread != null 3896 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3897 haveBg = true; 3898 break; 3899 } 3900 } 3901 3902 if (!haveBg) { 3903 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3904 if (doReport) { 3905 long now = SystemClock.uptimeMillis(); 3906 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3907 doReport = false; 3908 } else { 3909 mLastMemUsageReportTime = now; 3910 } 3911 } 3912 final ArrayList<ProcessMemInfo> memInfos 3913 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3914 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3915 long now = SystemClock.uptimeMillis(); 3916 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3917 ProcessRecord rec = mLruProcesses.get(i); 3918 if (rec == dyingProc || rec.thread == null) { 3919 continue; 3920 } 3921 if (doReport) { 3922 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3923 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3924 } 3925 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3926 // The low memory report is overriding any current 3927 // state for a GC request. Make sure to do 3928 // heavy/important/visible/foreground processes first. 3929 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3930 rec.lastRequestedGc = 0; 3931 } else { 3932 rec.lastRequestedGc = rec.lastLowMemory; 3933 } 3934 rec.reportLowMemory = true; 3935 rec.lastLowMemory = now; 3936 mProcessesToGc.remove(rec); 3937 addProcessToGcListLocked(rec); 3938 } 3939 } 3940 if (doReport) { 3941 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3942 mHandler.sendMessage(msg); 3943 } 3944 scheduleAppGcsLocked(); 3945 } 3946 } 3947 3948 final void appDiedLocked(ProcessRecord app, int pid, 3949 IApplicationThread thread) { 3950 3951 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3952 synchronized (stats) { 3953 stats.noteProcessDiedLocked(app.info.uid, pid); 3954 } 3955 3956 // Clean up already done if the process has been re-started. 3957 if (app.pid == pid && app.thread != null && 3958 app.thread.asBinder() == thread.asBinder()) { 3959 boolean doLowMem = app.instrumentationClass == null; 3960 boolean doOomAdj = doLowMem; 3961 if (!app.killedByAm) { 3962 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3963 + ") has died."); 3964 mAllowLowerMemLevel = true; 3965 } else { 3966 // Note that we always want to do oom adj to update our state with the 3967 // new number of procs. 3968 mAllowLowerMemLevel = false; 3969 doLowMem = false; 3970 } 3971 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3972 if (DEBUG_CLEANUP) Slog.v( 3973 TAG, "Dying app: " + app + ", pid: " + pid 3974 + ", thread: " + thread.asBinder()); 3975 handleAppDiedLocked(app, false, true); 3976 3977 if (doOomAdj) { 3978 updateOomAdjLocked(); 3979 } 3980 if (doLowMem) { 3981 doLowMemReportIfNeededLocked(app); 3982 } 3983 } else if (app.pid != pid) { 3984 // A new process has already been started. 3985 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3986 + ") has died and restarted (pid " + app.pid + ")."); 3987 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3988 } else if (DEBUG_PROCESSES) { 3989 Slog.d(TAG, "Received spurious death notification for thread " 3990 + thread.asBinder()); 3991 } 3992 } 3993 3994 /** 3995 * If a stack trace dump file is configured, dump process stack traces. 3996 * @param clearTraces causes the dump file to be erased prior to the new 3997 * traces being written, if true; when false, the new traces will be 3998 * appended to any existing file content. 3999 * @param firstPids of dalvik VM processes to dump stack traces for first 4000 * @param lastPids of dalvik VM processes to dump stack traces for last 4001 * @param nativeProcs optional list of native process names to dump stack crawls 4002 * @return file containing stack traces, or null if no dump file is configured 4003 */ 4004 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4005 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4006 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4007 if (tracesPath == null || tracesPath.length() == 0) { 4008 return null; 4009 } 4010 4011 File tracesFile = new File(tracesPath); 4012 try { 4013 File tracesDir = tracesFile.getParentFile(); 4014 if (!tracesDir.exists()) { 4015 tracesFile.mkdirs(); 4016 if (!SELinux.restorecon(tracesDir)) { 4017 return null; 4018 } 4019 } 4020 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4021 4022 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4023 tracesFile.createNewFile(); 4024 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4025 } catch (IOException e) { 4026 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4027 return null; 4028 } 4029 4030 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4031 return tracesFile; 4032 } 4033 4034 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4035 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4036 // Use a FileObserver to detect when traces finish writing. 4037 // The order of traces is considered important to maintain for legibility. 4038 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4039 @Override 4040 public synchronized void onEvent(int event, String path) { notify(); } 4041 }; 4042 4043 try { 4044 observer.startWatching(); 4045 4046 // First collect all of the stacks of the most important pids. 4047 if (firstPids != null) { 4048 try { 4049 int num = firstPids.size(); 4050 for (int i = 0; i < num; i++) { 4051 synchronized (observer) { 4052 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4053 observer.wait(200); // Wait for write-close, give up after 200msec 4054 } 4055 } 4056 } catch (InterruptedException e) { 4057 Log.wtf(TAG, e); 4058 } 4059 } 4060 4061 // Next collect the stacks of the native pids 4062 if (nativeProcs != null) { 4063 int[] pids = Process.getPidsForCommands(nativeProcs); 4064 if (pids != null) { 4065 for (int pid : pids) { 4066 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4067 } 4068 } 4069 } 4070 4071 // Lastly, measure CPU usage. 4072 if (processCpuTracker != null) { 4073 processCpuTracker.init(); 4074 System.gc(); 4075 processCpuTracker.update(); 4076 try { 4077 synchronized (processCpuTracker) { 4078 processCpuTracker.wait(500); // measure over 1/2 second. 4079 } 4080 } catch (InterruptedException e) { 4081 } 4082 processCpuTracker.update(); 4083 4084 // We'll take the stack crawls of just the top apps using CPU. 4085 final int N = processCpuTracker.countWorkingStats(); 4086 int numProcs = 0; 4087 for (int i=0; i<N && numProcs<5; i++) { 4088 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4089 if (lastPids.indexOfKey(stats.pid) >= 0) { 4090 numProcs++; 4091 try { 4092 synchronized (observer) { 4093 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4094 observer.wait(200); // Wait for write-close, give up after 200msec 4095 } 4096 } catch (InterruptedException e) { 4097 Log.wtf(TAG, e); 4098 } 4099 4100 } 4101 } 4102 } 4103 } finally { 4104 observer.stopWatching(); 4105 } 4106 } 4107 4108 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4109 if (true || IS_USER_BUILD) { 4110 return; 4111 } 4112 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4113 if (tracesPath == null || tracesPath.length() == 0) { 4114 return; 4115 } 4116 4117 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4118 StrictMode.allowThreadDiskWrites(); 4119 try { 4120 final File tracesFile = new File(tracesPath); 4121 final File tracesDir = tracesFile.getParentFile(); 4122 final File tracesTmp = new File(tracesDir, "__tmp__"); 4123 try { 4124 if (!tracesDir.exists()) { 4125 tracesFile.mkdirs(); 4126 if (!SELinux.restorecon(tracesDir.getPath())) { 4127 return; 4128 } 4129 } 4130 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4131 4132 if (tracesFile.exists()) { 4133 tracesTmp.delete(); 4134 tracesFile.renameTo(tracesTmp); 4135 } 4136 StringBuilder sb = new StringBuilder(); 4137 Time tobj = new Time(); 4138 tobj.set(System.currentTimeMillis()); 4139 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4140 sb.append(": "); 4141 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4142 sb.append(" since "); 4143 sb.append(msg); 4144 FileOutputStream fos = new FileOutputStream(tracesFile); 4145 fos.write(sb.toString().getBytes()); 4146 if (app == null) { 4147 fos.write("\n*** No application process!".getBytes()); 4148 } 4149 fos.close(); 4150 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4151 } catch (IOException e) { 4152 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4153 return; 4154 } 4155 4156 if (app != null) { 4157 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4158 firstPids.add(app.pid); 4159 dumpStackTraces(tracesPath, firstPids, null, null, null); 4160 } 4161 4162 File lastTracesFile = null; 4163 File curTracesFile = null; 4164 for (int i=9; i>=0; i--) { 4165 String name = String.format(Locale.US, "slow%02d.txt", i); 4166 curTracesFile = new File(tracesDir, name); 4167 if (curTracesFile.exists()) { 4168 if (lastTracesFile != null) { 4169 curTracesFile.renameTo(lastTracesFile); 4170 } else { 4171 curTracesFile.delete(); 4172 } 4173 } 4174 lastTracesFile = curTracesFile; 4175 } 4176 tracesFile.renameTo(curTracesFile); 4177 if (tracesTmp.exists()) { 4178 tracesTmp.renameTo(tracesFile); 4179 } 4180 } finally { 4181 StrictMode.setThreadPolicy(oldPolicy); 4182 } 4183 } 4184 4185 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4186 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4187 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4188 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4189 4190 if (mController != null) { 4191 try { 4192 // 0 == continue, -1 = kill process immediately 4193 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4194 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4195 } catch (RemoteException e) { 4196 mController = null; 4197 Watchdog.getInstance().setActivityController(null); 4198 } 4199 } 4200 4201 long anrTime = SystemClock.uptimeMillis(); 4202 if (MONITOR_CPU_USAGE) { 4203 updateCpuStatsNow(); 4204 } 4205 4206 synchronized (this) { 4207 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4208 if (mShuttingDown) { 4209 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4210 return; 4211 } else if (app.notResponding) { 4212 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4213 return; 4214 } else if (app.crashing) { 4215 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4216 return; 4217 } 4218 4219 // In case we come through here for the same app before completing 4220 // this one, mark as anring now so we will bail out. 4221 app.notResponding = true; 4222 4223 // Log the ANR to the event log. 4224 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4225 app.processName, app.info.flags, annotation); 4226 4227 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4228 firstPids.add(app.pid); 4229 4230 int parentPid = app.pid; 4231 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4232 if (parentPid != app.pid) firstPids.add(parentPid); 4233 4234 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4235 4236 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4237 ProcessRecord r = mLruProcesses.get(i); 4238 if (r != null && r.thread != null) { 4239 int pid = r.pid; 4240 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4241 if (r.persistent) { 4242 firstPids.add(pid); 4243 } else { 4244 lastPids.put(pid, Boolean.TRUE); 4245 } 4246 } 4247 } 4248 } 4249 } 4250 4251 // Log the ANR to the main log. 4252 StringBuilder info = new StringBuilder(); 4253 info.setLength(0); 4254 info.append("ANR in ").append(app.processName); 4255 if (activity != null && activity.shortComponentName != null) { 4256 info.append(" (").append(activity.shortComponentName).append(")"); 4257 } 4258 info.append("\n"); 4259 info.append("PID: ").append(app.pid).append("\n"); 4260 if (annotation != null) { 4261 info.append("Reason: ").append(annotation).append("\n"); 4262 } 4263 if (parent != null && parent != activity) { 4264 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4265 } 4266 4267 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4268 4269 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4270 NATIVE_STACKS_OF_INTEREST); 4271 4272 String cpuInfo = null; 4273 if (MONITOR_CPU_USAGE) { 4274 updateCpuStatsNow(); 4275 synchronized (mProcessCpuThread) { 4276 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4277 } 4278 info.append(processCpuTracker.printCurrentLoad()); 4279 info.append(cpuInfo); 4280 } 4281 4282 info.append(processCpuTracker.printCurrentState(anrTime)); 4283 4284 Slog.e(TAG, info.toString()); 4285 if (tracesFile == null) { 4286 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4287 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4288 } 4289 4290 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4291 cpuInfo, tracesFile, null); 4292 4293 if (mController != null) { 4294 try { 4295 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4296 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4297 if (res != 0) { 4298 if (res < 0 && app.pid != MY_PID) { 4299 Process.killProcess(app.pid); 4300 } else { 4301 synchronized (this) { 4302 mServices.scheduleServiceTimeoutLocked(app); 4303 } 4304 } 4305 return; 4306 } 4307 } catch (RemoteException e) { 4308 mController = null; 4309 Watchdog.getInstance().setActivityController(null); 4310 } 4311 } 4312 4313 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4314 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4315 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4316 4317 synchronized (this) { 4318 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4319 killUnneededProcessLocked(app, "background ANR"); 4320 return; 4321 } 4322 4323 // Set the app's notResponding state, and look up the errorReportReceiver 4324 makeAppNotRespondingLocked(app, 4325 activity != null ? activity.shortComponentName : null, 4326 annotation != null ? "ANR " + annotation : "ANR", 4327 info.toString()); 4328 4329 // Bring up the infamous App Not Responding dialog 4330 Message msg = Message.obtain(); 4331 HashMap<String, Object> map = new HashMap<String, Object>(); 4332 msg.what = SHOW_NOT_RESPONDING_MSG; 4333 msg.obj = map; 4334 msg.arg1 = aboveSystem ? 1 : 0; 4335 map.put("app", app); 4336 if (activity != null) { 4337 map.put("activity", activity); 4338 } 4339 4340 mHandler.sendMessage(msg); 4341 } 4342 } 4343 4344 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4345 if (!mLaunchWarningShown) { 4346 mLaunchWarningShown = true; 4347 mHandler.post(new Runnable() { 4348 @Override 4349 public void run() { 4350 synchronized (ActivityManagerService.this) { 4351 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4352 d.show(); 4353 mHandler.postDelayed(new Runnable() { 4354 @Override 4355 public void run() { 4356 synchronized (ActivityManagerService.this) { 4357 d.dismiss(); 4358 mLaunchWarningShown = false; 4359 } 4360 } 4361 }, 4000); 4362 } 4363 } 4364 }); 4365 } 4366 } 4367 4368 @Override 4369 public boolean clearApplicationUserData(final String packageName, 4370 final IPackageDataObserver observer, int userId) { 4371 enforceNotIsolatedCaller("clearApplicationUserData"); 4372 int uid = Binder.getCallingUid(); 4373 int pid = Binder.getCallingPid(); 4374 userId = handleIncomingUser(pid, uid, 4375 userId, false, true, "clearApplicationUserData", null); 4376 long callingId = Binder.clearCallingIdentity(); 4377 try { 4378 IPackageManager pm = AppGlobals.getPackageManager(); 4379 int pkgUid = -1; 4380 synchronized(this) { 4381 try { 4382 pkgUid = pm.getPackageUid(packageName, userId); 4383 } catch (RemoteException e) { 4384 } 4385 if (pkgUid == -1) { 4386 Slog.w(TAG, "Invalid packageName: " + packageName); 4387 if (observer != null) { 4388 try { 4389 observer.onRemoveCompleted(packageName, false); 4390 } catch (RemoteException e) { 4391 Slog.i(TAG, "Observer no longer exists."); 4392 } 4393 } 4394 return false; 4395 } 4396 if (uid == pkgUid || checkComponentPermission( 4397 android.Manifest.permission.CLEAR_APP_USER_DATA, 4398 pid, uid, -1, true) 4399 == PackageManager.PERMISSION_GRANTED) { 4400 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4401 } else { 4402 throw new SecurityException("PID " + pid + " does not have permission " 4403 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4404 + " of package " + packageName); 4405 } 4406 } 4407 4408 try { 4409 // Clear application user data 4410 pm.clearApplicationUserData(packageName, observer, userId); 4411 4412 // Remove all permissions granted from/to this package 4413 removeUriPermissionsForPackageLocked(packageName, userId, true); 4414 4415 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4416 Uri.fromParts("package", packageName, null)); 4417 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4418 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4419 null, null, 0, null, null, null, false, false, userId); 4420 } catch (RemoteException e) { 4421 } 4422 } finally { 4423 Binder.restoreCallingIdentity(callingId); 4424 } 4425 return true; 4426 } 4427 4428 @Override 4429 public void killBackgroundProcesses(final String packageName, int userId) { 4430 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4431 != PackageManager.PERMISSION_GRANTED && 4432 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4433 != PackageManager.PERMISSION_GRANTED) { 4434 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4435 + Binder.getCallingPid() 4436 + ", uid=" + Binder.getCallingUid() 4437 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4438 Slog.w(TAG, msg); 4439 throw new SecurityException(msg); 4440 } 4441 4442 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4443 userId, true, true, "killBackgroundProcesses", null); 4444 long callingId = Binder.clearCallingIdentity(); 4445 try { 4446 IPackageManager pm = AppGlobals.getPackageManager(); 4447 synchronized(this) { 4448 int appId = -1; 4449 try { 4450 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4451 } catch (RemoteException e) { 4452 } 4453 if (appId == -1) { 4454 Slog.w(TAG, "Invalid packageName: " + packageName); 4455 return; 4456 } 4457 killPackageProcessesLocked(packageName, appId, userId, 4458 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4459 } 4460 } finally { 4461 Binder.restoreCallingIdentity(callingId); 4462 } 4463 } 4464 4465 @Override 4466 public void killAllBackgroundProcesses() { 4467 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4468 != PackageManager.PERMISSION_GRANTED) { 4469 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4470 + Binder.getCallingPid() 4471 + ", uid=" + Binder.getCallingUid() 4472 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4473 Slog.w(TAG, msg); 4474 throw new SecurityException(msg); 4475 } 4476 4477 long callingId = Binder.clearCallingIdentity(); 4478 try { 4479 synchronized(this) { 4480 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4481 final int NP = mProcessNames.getMap().size(); 4482 for (int ip=0; ip<NP; ip++) { 4483 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4484 final int NA = apps.size(); 4485 for (int ia=0; ia<NA; ia++) { 4486 ProcessRecord app = apps.valueAt(ia); 4487 if (app.persistent) { 4488 // we don't kill persistent processes 4489 continue; 4490 } 4491 if (app.removed) { 4492 procs.add(app); 4493 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4494 app.removed = true; 4495 procs.add(app); 4496 } 4497 } 4498 } 4499 4500 int N = procs.size(); 4501 for (int i=0; i<N; i++) { 4502 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4503 } 4504 mAllowLowerMemLevel = true; 4505 updateOomAdjLocked(); 4506 doLowMemReportIfNeededLocked(null); 4507 } 4508 } finally { 4509 Binder.restoreCallingIdentity(callingId); 4510 } 4511 } 4512 4513 @Override 4514 public void forceStopPackage(final String packageName, int userId) { 4515 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4516 != PackageManager.PERMISSION_GRANTED) { 4517 String msg = "Permission Denial: forceStopPackage() from pid=" 4518 + Binder.getCallingPid() 4519 + ", uid=" + Binder.getCallingUid() 4520 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4521 Slog.w(TAG, msg); 4522 throw new SecurityException(msg); 4523 } 4524 final int callingPid = Binder.getCallingPid(); 4525 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4526 userId, true, true, "forceStopPackage", null); 4527 long callingId = Binder.clearCallingIdentity(); 4528 try { 4529 IPackageManager pm = AppGlobals.getPackageManager(); 4530 synchronized(this) { 4531 int[] users = userId == UserHandle.USER_ALL 4532 ? getUsersLocked() : new int[] { userId }; 4533 for (int user : users) { 4534 int pkgUid = -1; 4535 try { 4536 pkgUid = pm.getPackageUid(packageName, user); 4537 } catch (RemoteException e) { 4538 } 4539 if (pkgUid == -1) { 4540 Slog.w(TAG, "Invalid packageName: " + packageName); 4541 continue; 4542 } 4543 try { 4544 pm.setPackageStoppedState(packageName, true, user); 4545 } catch (RemoteException e) { 4546 } catch (IllegalArgumentException e) { 4547 Slog.w(TAG, "Failed trying to unstop package " 4548 + packageName + ": " + e); 4549 } 4550 if (isUserRunningLocked(user, false)) { 4551 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4552 } 4553 } 4554 } 4555 } finally { 4556 Binder.restoreCallingIdentity(callingId); 4557 } 4558 } 4559 4560 /* 4561 * The pkg name and app id have to be specified. 4562 */ 4563 @Override 4564 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4565 if (pkg == null) { 4566 return; 4567 } 4568 // Make sure the uid is valid. 4569 if (appid < 0) { 4570 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4571 return; 4572 } 4573 int callerUid = Binder.getCallingUid(); 4574 // Only the system server can kill an application 4575 if (callerUid == Process.SYSTEM_UID) { 4576 // Post an aysnc message to kill the application 4577 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4578 msg.arg1 = appid; 4579 msg.arg2 = 0; 4580 Bundle bundle = new Bundle(); 4581 bundle.putString("pkg", pkg); 4582 bundle.putString("reason", reason); 4583 msg.obj = bundle; 4584 mHandler.sendMessage(msg); 4585 } else { 4586 throw new SecurityException(callerUid + " cannot kill pkg: " + 4587 pkg); 4588 } 4589 } 4590 4591 @Override 4592 public void closeSystemDialogs(String reason) { 4593 enforceNotIsolatedCaller("closeSystemDialogs"); 4594 4595 final int pid = Binder.getCallingPid(); 4596 final int uid = Binder.getCallingUid(); 4597 final long origId = Binder.clearCallingIdentity(); 4598 try { 4599 synchronized (this) { 4600 // Only allow this from foreground processes, so that background 4601 // applications can't abuse it to prevent system UI from being shown. 4602 if (uid >= Process.FIRST_APPLICATION_UID) { 4603 ProcessRecord proc; 4604 synchronized (mPidsSelfLocked) { 4605 proc = mPidsSelfLocked.get(pid); 4606 } 4607 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4608 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4609 + " from background process " + proc); 4610 return; 4611 } 4612 } 4613 closeSystemDialogsLocked(reason); 4614 } 4615 } finally { 4616 Binder.restoreCallingIdentity(origId); 4617 } 4618 } 4619 4620 void closeSystemDialogsLocked(String reason) { 4621 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4622 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4623 | Intent.FLAG_RECEIVER_FOREGROUND); 4624 if (reason != null) { 4625 intent.putExtra("reason", reason); 4626 } 4627 mWindowManager.closeSystemDialogs(reason); 4628 4629 mStackSupervisor.closeSystemDialogsLocked(); 4630 4631 broadcastIntentLocked(null, null, intent, null, 4632 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4633 Process.SYSTEM_UID, UserHandle.USER_ALL); 4634 } 4635 4636 @Override 4637 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4638 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4639 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4640 for (int i=pids.length-1; i>=0; i--) { 4641 ProcessRecord proc; 4642 int oomAdj; 4643 synchronized (this) { 4644 synchronized (mPidsSelfLocked) { 4645 proc = mPidsSelfLocked.get(pids[i]); 4646 oomAdj = proc != null ? proc.setAdj : 0; 4647 } 4648 } 4649 infos[i] = new Debug.MemoryInfo(); 4650 Debug.getMemoryInfo(pids[i], infos[i]); 4651 if (proc != null) { 4652 synchronized (this) { 4653 if (proc.thread != null && proc.setAdj == oomAdj) { 4654 // Record this for posterity if the process has been stable. 4655 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4656 infos[i].getTotalUss(), false, proc.pkgList); 4657 } 4658 } 4659 } 4660 } 4661 return infos; 4662 } 4663 4664 @Override 4665 public long[] getProcessPss(int[] pids) { 4666 enforceNotIsolatedCaller("getProcessPss"); 4667 long[] pss = new long[pids.length]; 4668 for (int i=pids.length-1; i>=0; i--) { 4669 ProcessRecord proc; 4670 int oomAdj; 4671 synchronized (this) { 4672 synchronized (mPidsSelfLocked) { 4673 proc = mPidsSelfLocked.get(pids[i]); 4674 oomAdj = proc != null ? proc.setAdj : 0; 4675 } 4676 } 4677 long[] tmpUss = new long[1]; 4678 pss[i] = Debug.getPss(pids[i], tmpUss); 4679 if (proc != null) { 4680 synchronized (this) { 4681 if (proc.thread != null && proc.setAdj == oomAdj) { 4682 // Record this for posterity if the process has been stable. 4683 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4684 } 4685 } 4686 } 4687 } 4688 return pss; 4689 } 4690 4691 @Override 4692 public void killApplicationProcess(String processName, int uid) { 4693 if (processName == null) { 4694 return; 4695 } 4696 4697 int callerUid = Binder.getCallingUid(); 4698 // Only the system server can kill an application 4699 if (callerUid == Process.SYSTEM_UID) { 4700 synchronized (this) { 4701 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4702 if (app != null && app.thread != null) { 4703 try { 4704 app.thread.scheduleSuicide(); 4705 } catch (RemoteException e) { 4706 // If the other end already died, then our work here is done. 4707 } 4708 } else { 4709 Slog.w(TAG, "Process/uid not found attempting kill of " 4710 + processName + " / " + uid); 4711 } 4712 } 4713 } else { 4714 throw new SecurityException(callerUid + " cannot kill app process: " + 4715 processName); 4716 } 4717 } 4718 4719 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4720 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4721 false, true, false, false, UserHandle.getUserId(uid), reason); 4722 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4723 Uri.fromParts("package", packageName, null)); 4724 if (!mProcessesReady) { 4725 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4726 | Intent.FLAG_RECEIVER_FOREGROUND); 4727 } 4728 intent.putExtra(Intent.EXTRA_UID, uid); 4729 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4730 broadcastIntentLocked(null, null, intent, 4731 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4732 false, false, 4733 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4734 } 4735 4736 private void forceStopUserLocked(int userId, String reason) { 4737 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4738 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4739 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4740 | Intent.FLAG_RECEIVER_FOREGROUND); 4741 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4742 broadcastIntentLocked(null, null, intent, 4743 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4744 false, false, 4745 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4746 } 4747 4748 private final boolean killPackageProcessesLocked(String packageName, int appId, 4749 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4750 boolean doit, boolean evenPersistent, String reason) { 4751 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4752 4753 // Remove all processes this package may have touched: all with the 4754 // same UID (except for the system or root user), and all whose name 4755 // matches the package name. 4756 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4757 final int NP = mProcessNames.getMap().size(); 4758 for (int ip=0; ip<NP; ip++) { 4759 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4760 final int NA = apps.size(); 4761 for (int ia=0; ia<NA; ia++) { 4762 ProcessRecord app = apps.valueAt(ia); 4763 if (app.persistent && !evenPersistent) { 4764 // we don't kill persistent processes 4765 continue; 4766 } 4767 if (app.removed) { 4768 if (doit) { 4769 procs.add(app); 4770 } 4771 continue; 4772 } 4773 4774 // Skip process if it doesn't meet our oom adj requirement. 4775 if (app.setAdj < minOomAdj) { 4776 continue; 4777 } 4778 4779 // If no package is specified, we call all processes under the 4780 // give user id. 4781 if (packageName == null) { 4782 if (app.userId != userId) { 4783 continue; 4784 } 4785 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4786 continue; 4787 } 4788 // Package has been specified, we want to hit all processes 4789 // that match it. We need to qualify this by the processes 4790 // that are running under the specified app and user ID. 4791 } else { 4792 if (UserHandle.getAppId(app.uid) != appId) { 4793 continue; 4794 } 4795 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4796 continue; 4797 } 4798 if (!app.pkgList.containsKey(packageName)) { 4799 continue; 4800 } 4801 } 4802 4803 // Process has passed all conditions, kill it! 4804 if (!doit) { 4805 return true; 4806 } 4807 app.removed = true; 4808 procs.add(app); 4809 } 4810 } 4811 4812 int N = procs.size(); 4813 for (int i=0; i<N; i++) { 4814 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4815 } 4816 updateOomAdjLocked(); 4817 return N > 0; 4818 } 4819 4820 private final boolean forceStopPackageLocked(String name, int appId, 4821 boolean callerWillRestart, boolean purgeCache, boolean doit, 4822 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4823 int i; 4824 int N; 4825 4826 if (userId == UserHandle.USER_ALL && name == null) { 4827 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4828 } 4829 4830 if (appId < 0 && name != null) { 4831 try { 4832 appId = UserHandle.getAppId( 4833 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4834 } catch (RemoteException e) { 4835 } 4836 } 4837 4838 if (doit) { 4839 if (name != null) { 4840 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4841 + " user=" + userId + ": " + reason); 4842 } else { 4843 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4844 } 4845 4846 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4847 for (int ip=pmap.size()-1; ip>=0; ip--) { 4848 SparseArray<Long> ba = pmap.valueAt(ip); 4849 for (i=ba.size()-1; i>=0; i--) { 4850 boolean remove = false; 4851 final int entUid = ba.keyAt(i); 4852 if (name != null) { 4853 if (userId == UserHandle.USER_ALL) { 4854 if (UserHandle.getAppId(entUid) == appId) { 4855 remove = true; 4856 } 4857 } else { 4858 if (entUid == UserHandle.getUid(userId, appId)) { 4859 remove = true; 4860 } 4861 } 4862 } else if (UserHandle.getUserId(entUid) == userId) { 4863 remove = true; 4864 } 4865 if (remove) { 4866 ba.removeAt(i); 4867 } 4868 } 4869 if (ba.size() == 0) { 4870 pmap.removeAt(ip); 4871 } 4872 } 4873 } 4874 4875 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4876 -100, callerWillRestart, true, doit, evenPersistent, 4877 name == null ? ("stop user " + userId) : ("stop " + name)); 4878 4879 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4880 if (!doit) { 4881 return true; 4882 } 4883 didSomething = true; 4884 } 4885 4886 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4887 if (!doit) { 4888 return true; 4889 } 4890 didSomething = true; 4891 } 4892 4893 if (name == null) { 4894 // Remove all sticky broadcasts from this user. 4895 mStickyBroadcasts.remove(userId); 4896 } 4897 4898 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4899 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4900 userId, providers)) { 4901 if (!doit) { 4902 return true; 4903 } 4904 didSomething = true; 4905 } 4906 N = providers.size(); 4907 for (i=0; i<N; i++) { 4908 removeDyingProviderLocked(null, providers.get(i), true); 4909 } 4910 4911 // Remove transient permissions granted from/to this package/user 4912 removeUriPermissionsForPackageLocked(name, userId, false); 4913 4914 if (name == null || uninstalling) { 4915 // Remove pending intents. For now we only do this when force 4916 // stopping users, because we have some problems when doing this 4917 // for packages -- app widgets are not currently cleaned up for 4918 // such packages, so they can be left with bad pending intents. 4919 if (mIntentSenderRecords.size() > 0) { 4920 Iterator<WeakReference<PendingIntentRecord>> it 4921 = mIntentSenderRecords.values().iterator(); 4922 while (it.hasNext()) { 4923 WeakReference<PendingIntentRecord> wpir = it.next(); 4924 if (wpir == null) { 4925 it.remove(); 4926 continue; 4927 } 4928 PendingIntentRecord pir = wpir.get(); 4929 if (pir == null) { 4930 it.remove(); 4931 continue; 4932 } 4933 if (name == null) { 4934 // Stopping user, remove all objects for the user. 4935 if (pir.key.userId != userId) { 4936 // Not the same user, skip it. 4937 continue; 4938 } 4939 } else { 4940 if (UserHandle.getAppId(pir.uid) != appId) { 4941 // Different app id, skip it. 4942 continue; 4943 } 4944 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4945 // Different user, skip it. 4946 continue; 4947 } 4948 if (!pir.key.packageName.equals(name)) { 4949 // Different package, skip it. 4950 continue; 4951 } 4952 } 4953 if (!doit) { 4954 return true; 4955 } 4956 didSomething = true; 4957 it.remove(); 4958 pir.canceled = true; 4959 if (pir.key.activity != null) { 4960 pir.key.activity.pendingResults.remove(pir.ref); 4961 } 4962 } 4963 } 4964 } 4965 4966 if (doit) { 4967 if (purgeCache && name != null) { 4968 AttributeCache ac = AttributeCache.instance(); 4969 if (ac != null) { 4970 ac.removePackage(name); 4971 } 4972 } 4973 if (mBooted) { 4974 mStackSupervisor.resumeTopActivitiesLocked(); 4975 mStackSupervisor.scheduleIdleLocked(); 4976 } 4977 } 4978 4979 return didSomething; 4980 } 4981 4982 private final boolean removeProcessLocked(ProcessRecord app, 4983 boolean callerWillRestart, boolean allowRestart, String reason) { 4984 final String name = app.processName; 4985 final int uid = app.uid; 4986 if (DEBUG_PROCESSES) Slog.d( 4987 TAG, "Force removing proc " + app.toShortString() + " (" + name 4988 + "/" + uid + ")"); 4989 4990 mProcessNames.remove(name, uid); 4991 mIsolatedProcesses.remove(app.uid); 4992 if (mHeavyWeightProcess == app) { 4993 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4994 mHeavyWeightProcess.userId, 0)); 4995 mHeavyWeightProcess = null; 4996 } 4997 boolean needRestart = false; 4998 if (app.pid > 0 && app.pid != MY_PID) { 4999 int pid = app.pid; 5000 synchronized (mPidsSelfLocked) { 5001 mPidsSelfLocked.remove(pid); 5002 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5003 } 5004 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5005 app.processName, app.info.uid); 5006 if (app.isolated) { 5007 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5008 } 5009 killUnneededProcessLocked(app, reason); 5010 handleAppDiedLocked(app, true, allowRestart); 5011 removeLruProcessLocked(app); 5012 5013 if (app.persistent && !app.isolated) { 5014 if (!callerWillRestart) { 5015 addAppLocked(app.info, false); 5016 } else { 5017 needRestart = true; 5018 } 5019 } 5020 } else { 5021 mRemovedProcesses.add(app); 5022 } 5023 5024 return needRestart; 5025 } 5026 5027 private final void processStartTimedOutLocked(ProcessRecord app) { 5028 final int pid = app.pid; 5029 boolean gone = false; 5030 synchronized (mPidsSelfLocked) { 5031 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5032 if (knownApp != null && knownApp.thread == null) { 5033 mPidsSelfLocked.remove(pid); 5034 gone = true; 5035 } 5036 } 5037 5038 if (gone) { 5039 Slog.w(TAG, "Process " + app + " failed to attach"); 5040 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5041 pid, app.uid, app.processName); 5042 mProcessNames.remove(app.processName, app.uid); 5043 mIsolatedProcesses.remove(app.uid); 5044 if (mHeavyWeightProcess == app) { 5045 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5046 mHeavyWeightProcess.userId, 0)); 5047 mHeavyWeightProcess = null; 5048 } 5049 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5050 app.processName, app.info.uid); 5051 if (app.isolated) { 5052 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5053 } 5054 // Take care of any launching providers waiting for this process. 5055 checkAppInLaunchingProvidersLocked(app, true); 5056 // Take care of any services that are waiting for the process. 5057 mServices.processStartTimedOutLocked(app); 5058 killUnneededProcessLocked(app, "start timeout"); 5059 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5060 Slog.w(TAG, "Unattached app died before backup, skipping"); 5061 try { 5062 IBackupManager bm = IBackupManager.Stub.asInterface( 5063 ServiceManager.getService(Context.BACKUP_SERVICE)); 5064 bm.agentDisconnected(app.info.packageName); 5065 } catch (RemoteException e) { 5066 // Can't happen; the backup manager is local 5067 } 5068 } 5069 if (isPendingBroadcastProcessLocked(pid)) { 5070 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5071 skipPendingBroadcastLocked(pid); 5072 } 5073 } else { 5074 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5075 } 5076 } 5077 5078 private final boolean attachApplicationLocked(IApplicationThread thread, 5079 int pid) { 5080 5081 // Find the application record that is being attached... either via 5082 // the pid if we are running in multiple processes, or just pull the 5083 // next app record if we are emulating process with anonymous threads. 5084 ProcessRecord app; 5085 if (pid != MY_PID && pid >= 0) { 5086 synchronized (mPidsSelfLocked) { 5087 app = mPidsSelfLocked.get(pid); 5088 } 5089 } else { 5090 app = null; 5091 } 5092 5093 if (app == null) { 5094 Slog.w(TAG, "No pending application record for pid " + pid 5095 + " (IApplicationThread " + thread + "); dropping process"); 5096 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5097 if (pid > 0 && pid != MY_PID) { 5098 Process.killProcessQuiet(pid); 5099 } else { 5100 try { 5101 thread.scheduleExit(); 5102 } catch (Exception e) { 5103 // Ignore exceptions. 5104 } 5105 } 5106 return false; 5107 } 5108 5109 // If this application record is still attached to a previous 5110 // process, clean it up now. 5111 if (app.thread != null) { 5112 handleAppDiedLocked(app, true, true); 5113 } 5114 5115 // Tell the process all about itself. 5116 5117 if (localLOGV) Slog.v( 5118 TAG, "Binding process pid " + pid + " to record " + app); 5119 5120 final String processName = app.processName; 5121 try { 5122 AppDeathRecipient adr = new AppDeathRecipient( 5123 app, pid, thread); 5124 thread.asBinder().linkToDeath(adr, 0); 5125 app.deathRecipient = adr; 5126 } catch (RemoteException e) { 5127 app.resetPackageList(mProcessStats); 5128 startProcessLocked(app, "link fail", processName); 5129 return false; 5130 } 5131 5132 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5133 5134 app.makeActive(thread, mProcessStats); 5135 app.curAdj = app.setAdj = -100; 5136 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5137 app.forcingToForeground = null; 5138 updateProcessForegroundLocked(app, false, false); 5139 app.hasShownUi = false; 5140 app.debugging = false; 5141 app.cached = false; 5142 5143 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5144 5145 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5146 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5147 5148 if (!normalMode) { 5149 Slog.i(TAG, "Launching preboot mode app: " + app); 5150 } 5151 5152 if (localLOGV) Slog.v( 5153 TAG, "New app record " + app 5154 + " thread=" + thread.asBinder() + " pid=" + pid); 5155 try { 5156 int testMode = IApplicationThread.DEBUG_OFF; 5157 if (mDebugApp != null && mDebugApp.equals(processName)) { 5158 testMode = mWaitForDebugger 5159 ? IApplicationThread.DEBUG_WAIT 5160 : IApplicationThread.DEBUG_ON; 5161 app.debugging = true; 5162 if (mDebugTransient) { 5163 mDebugApp = mOrigDebugApp; 5164 mWaitForDebugger = mOrigWaitForDebugger; 5165 } 5166 } 5167 String profileFile = app.instrumentationProfileFile; 5168 ParcelFileDescriptor profileFd = null; 5169 boolean profileAutoStop = false; 5170 if (mProfileApp != null && mProfileApp.equals(processName)) { 5171 mProfileProc = app; 5172 profileFile = mProfileFile; 5173 profileFd = mProfileFd; 5174 profileAutoStop = mAutoStopProfiler; 5175 } 5176 boolean enableOpenGlTrace = false; 5177 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5178 enableOpenGlTrace = true; 5179 mOpenGlTraceApp = null; 5180 } 5181 5182 // If the app is being launched for restore or full backup, set it up specially 5183 boolean isRestrictedBackupMode = false; 5184 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5185 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5186 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5187 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5188 } 5189 5190 ensurePackageDexOpt(app.instrumentationInfo != null 5191 ? app.instrumentationInfo.packageName 5192 : app.info.packageName); 5193 if (app.instrumentationClass != null) { 5194 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5195 } 5196 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5197 + processName + " with config " + mConfiguration); 5198 ApplicationInfo appInfo = app.instrumentationInfo != null 5199 ? app.instrumentationInfo : app.info; 5200 app.compat = compatibilityInfoForPackageLocked(appInfo); 5201 if (profileFd != null) { 5202 profileFd = profileFd.dup(); 5203 } 5204 thread.bindApplication(processName, appInfo, providers, 5205 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5206 app.instrumentationArguments, app.instrumentationWatcher, 5207 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5208 isRestrictedBackupMode || !normalMode, app.persistent, 5209 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5210 mCoreSettingsObserver.getCoreSettingsLocked()); 5211 updateLruProcessLocked(app, false, null); 5212 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5213 } catch (Exception e) { 5214 // todo: Yikes! What should we do? For now we will try to 5215 // start another process, but that could easily get us in 5216 // an infinite loop of restarting processes... 5217 Slog.w(TAG, "Exception thrown during bind!", e); 5218 5219 app.resetPackageList(mProcessStats); 5220 app.unlinkDeathRecipient(); 5221 startProcessLocked(app, "bind fail", processName); 5222 return false; 5223 } 5224 5225 // Remove this record from the list of starting applications. 5226 mPersistentStartingProcesses.remove(app); 5227 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5228 "Attach application locked removing on hold: " + app); 5229 mProcessesOnHold.remove(app); 5230 5231 boolean badApp = false; 5232 boolean didSomething = false; 5233 5234 // See if the top visible activity is waiting to run in this process... 5235 if (normalMode) { 5236 try { 5237 if (mStackSupervisor.attachApplicationLocked(app)) { 5238 didSomething = true; 5239 } 5240 } catch (Exception e) { 5241 badApp = true; 5242 } 5243 } 5244 5245 // Find any services that should be running in this process... 5246 if (!badApp) { 5247 try { 5248 didSomething |= mServices.attachApplicationLocked(app, processName); 5249 } catch (Exception e) { 5250 badApp = true; 5251 } 5252 } 5253 5254 // Check if a next-broadcast receiver is in this process... 5255 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5256 try { 5257 didSomething |= sendPendingBroadcastsLocked(app); 5258 } catch (Exception e) { 5259 // If the app died trying to launch the receiver we declare it 'bad' 5260 badApp = true; 5261 } 5262 } 5263 5264 // Check whether the next backup agent is in this process... 5265 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5266 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5267 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5268 try { 5269 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5270 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5271 mBackupTarget.backupMode); 5272 } catch (Exception e) { 5273 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5274 e.printStackTrace(); 5275 } 5276 } 5277 5278 if (badApp) { 5279 // todo: Also need to kill application to deal with all 5280 // kinds of exceptions. 5281 handleAppDiedLocked(app, false, true); 5282 return false; 5283 } 5284 5285 if (!didSomething) { 5286 updateOomAdjLocked(); 5287 } 5288 5289 return true; 5290 } 5291 5292 @Override 5293 public final void attachApplication(IApplicationThread thread) { 5294 synchronized (this) { 5295 int callingPid = Binder.getCallingPid(); 5296 final long origId = Binder.clearCallingIdentity(); 5297 attachApplicationLocked(thread, callingPid); 5298 Binder.restoreCallingIdentity(origId); 5299 } 5300 } 5301 5302 @Override 5303 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5304 final long origId = Binder.clearCallingIdentity(); 5305 synchronized (this) { 5306 ActivityStack stack = ActivityRecord.getStackLocked(token); 5307 if (stack != null) { 5308 ActivityRecord r = 5309 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5310 if (stopProfiling) { 5311 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5312 try { 5313 mProfileFd.close(); 5314 } catch (IOException e) { 5315 } 5316 clearProfilerLocked(); 5317 } 5318 } 5319 } 5320 } 5321 Binder.restoreCallingIdentity(origId); 5322 } 5323 5324 void enableScreenAfterBoot() { 5325 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5326 SystemClock.uptimeMillis()); 5327 mWindowManager.enableScreenAfterBoot(); 5328 5329 synchronized (this) { 5330 updateEventDispatchingLocked(); 5331 } 5332 } 5333 5334 @Override 5335 public void showBootMessage(final CharSequence msg, final boolean always) { 5336 enforceNotIsolatedCaller("showBootMessage"); 5337 mWindowManager.showBootMessage(msg, always); 5338 } 5339 5340 @Override 5341 public void dismissKeyguardOnNextActivity() { 5342 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5343 final long token = Binder.clearCallingIdentity(); 5344 try { 5345 synchronized (this) { 5346 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5347 if (mLockScreenShown) { 5348 mLockScreenShown = false; 5349 comeOutOfSleepIfNeededLocked(); 5350 } 5351 mStackSupervisor.setDismissKeyguard(true); 5352 } 5353 } finally { 5354 Binder.restoreCallingIdentity(token); 5355 } 5356 } 5357 5358 final void finishBooting() { 5359 // Register receivers to handle package update events 5360 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5361 5362 synchronized (this) { 5363 // Ensure that any processes we had put on hold are now started 5364 // up. 5365 final int NP = mProcessesOnHold.size(); 5366 if (NP > 0) { 5367 ArrayList<ProcessRecord> procs = 5368 new ArrayList<ProcessRecord>(mProcessesOnHold); 5369 for (int ip=0; ip<NP; ip++) { 5370 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5371 + procs.get(ip)); 5372 startProcessLocked(procs.get(ip), "on-hold", null); 5373 } 5374 } 5375 5376 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5377 // Start looking for apps that are abusing wake locks. 5378 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5379 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5380 // Tell anyone interested that we are done booting! 5381 SystemProperties.set("sys.boot_completed", "1"); 5382 SystemProperties.set("dev.bootcomplete", "1"); 5383 for (int i=0; i<mStartedUsers.size(); i++) { 5384 UserStartedState uss = mStartedUsers.valueAt(i); 5385 if (uss.mState == UserStartedState.STATE_BOOTING) { 5386 uss.mState = UserStartedState.STATE_RUNNING; 5387 final int userId = mStartedUsers.keyAt(i); 5388 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5389 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5390 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5391 broadcastIntentLocked(null, null, intent, null, 5392 new IIntentReceiver.Stub() { 5393 @Override 5394 public void performReceive(Intent intent, int resultCode, 5395 String data, Bundle extras, boolean ordered, 5396 boolean sticky, int sendingUser) { 5397 synchronized (ActivityManagerService.this) { 5398 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5399 true, false); 5400 } 5401 } 5402 }, 5403 0, null, null, 5404 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5405 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5406 userId); 5407 } 5408 } 5409 scheduleStartProfilesLocked(); 5410 } 5411 } 5412 } 5413 5414 final void ensureBootCompleted() { 5415 boolean booting; 5416 boolean enableScreen; 5417 synchronized (this) { 5418 booting = mBooting; 5419 mBooting = false; 5420 enableScreen = !mBooted; 5421 mBooted = true; 5422 } 5423 5424 if (booting) { 5425 finishBooting(); 5426 } 5427 5428 if (enableScreen) { 5429 enableScreenAfterBoot(); 5430 } 5431 } 5432 5433 @Override 5434 public final void activityResumed(IBinder token) { 5435 final long origId = Binder.clearCallingIdentity(); 5436 synchronized(this) { 5437 ActivityStack stack = ActivityRecord.getStackLocked(token); 5438 if (stack != null) { 5439 ActivityRecord.activityResumedLocked(token); 5440 } 5441 } 5442 Binder.restoreCallingIdentity(origId); 5443 } 5444 5445 @Override 5446 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5447 final long origId = Binder.clearCallingIdentity(); 5448 synchronized(this) { 5449 ActivityStack stack = ActivityRecord.getStackLocked(token); 5450 if (stack != null) { 5451 stack.activityPausedLocked(token, false, persistentState); 5452 } 5453 } 5454 Binder.restoreCallingIdentity(origId); 5455 } 5456 5457 @Override 5458 public final void activityStopped(IBinder token, Bundle icicle, 5459 PersistableBundle persistentState, CharSequence description) { 5460 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5461 5462 // Refuse possible leaked file descriptors 5463 if (icicle != null && icicle.hasFileDescriptors()) { 5464 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5465 } 5466 5467 final long origId = Binder.clearCallingIdentity(); 5468 5469 synchronized (this) { 5470 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5471 if (r != null) { 5472 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5473 } 5474 } 5475 5476 trimApplications(); 5477 5478 Binder.restoreCallingIdentity(origId); 5479 } 5480 5481 @Override 5482 public final void activityDestroyed(IBinder token) { 5483 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5484 synchronized (this) { 5485 ActivityStack stack = ActivityRecord.getStackLocked(token); 5486 if (stack != null) { 5487 stack.activityDestroyedLocked(token); 5488 } 5489 } 5490 } 5491 5492 @Override 5493 public String getCallingPackage(IBinder token) { 5494 synchronized (this) { 5495 ActivityRecord r = getCallingRecordLocked(token); 5496 return r != null ? r.info.packageName : null; 5497 } 5498 } 5499 5500 @Override 5501 public ComponentName getCallingActivity(IBinder token) { 5502 synchronized (this) { 5503 ActivityRecord r = getCallingRecordLocked(token); 5504 return r != null ? r.intent.getComponent() : null; 5505 } 5506 } 5507 5508 private ActivityRecord getCallingRecordLocked(IBinder token) { 5509 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5510 if (r == null) { 5511 return null; 5512 } 5513 return r.resultTo; 5514 } 5515 5516 @Override 5517 public ComponentName getActivityClassForToken(IBinder token) { 5518 synchronized(this) { 5519 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5520 if (r == null) { 5521 return null; 5522 } 5523 return r.intent.getComponent(); 5524 } 5525 } 5526 5527 @Override 5528 public String getPackageForToken(IBinder token) { 5529 synchronized(this) { 5530 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5531 if (r == null) { 5532 return null; 5533 } 5534 return r.packageName; 5535 } 5536 } 5537 5538 @Override 5539 public IIntentSender getIntentSender(int type, 5540 String packageName, IBinder token, String resultWho, 5541 int requestCode, Intent[] intents, String[] resolvedTypes, 5542 int flags, Bundle options, int userId) { 5543 enforceNotIsolatedCaller("getIntentSender"); 5544 // Refuse possible leaked file descriptors 5545 if (intents != null) { 5546 if (intents.length < 1) { 5547 throw new IllegalArgumentException("Intents array length must be >= 1"); 5548 } 5549 for (int i=0; i<intents.length; i++) { 5550 Intent intent = intents[i]; 5551 if (intent != null) { 5552 if (intent.hasFileDescriptors()) { 5553 throw new IllegalArgumentException("File descriptors passed in Intent"); 5554 } 5555 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5556 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5557 throw new IllegalArgumentException( 5558 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5559 } 5560 intents[i] = new Intent(intent); 5561 } 5562 } 5563 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5564 throw new IllegalArgumentException( 5565 "Intent array length does not match resolvedTypes length"); 5566 } 5567 } 5568 if (options != null) { 5569 if (options.hasFileDescriptors()) { 5570 throw new IllegalArgumentException("File descriptors passed in options"); 5571 } 5572 } 5573 5574 synchronized(this) { 5575 int callingUid = Binder.getCallingUid(); 5576 int origUserId = userId; 5577 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5578 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5579 "getIntentSender", null); 5580 if (origUserId == UserHandle.USER_CURRENT) { 5581 // We don't want to evaluate this until the pending intent is 5582 // actually executed. However, we do want to always do the 5583 // security checking for it above. 5584 userId = UserHandle.USER_CURRENT; 5585 } 5586 try { 5587 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5588 int uid = AppGlobals.getPackageManager() 5589 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5590 if (!UserHandle.isSameApp(callingUid, uid)) { 5591 String msg = "Permission Denial: getIntentSender() from pid=" 5592 + Binder.getCallingPid() 5593 + ", uid=" + Binder.getCallingUid() 5594 + ", (need uid=" + uid + ")" 5595 + " is not allowed to send as package " + packageName; 5596 Slog.w(TAG, msg); 5597 throw new SecurityException(msg); 5598 } 5599 } 5600 5601 return getIntentSenderLocked(type, packageName, callingUid, userId, 5602 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5603 5604 } catch (RemoteException e) { 5605 throw new SecurityException(e); 5606 } 5607 } 5608 } 5609 5610 IIntentSender getIntentSenderLocked(int type, String packageName, 5611 int callingUid, int userId, IBinder token, String resultWho, 5612 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5613 Bundle options) { 5614 if (DEBUG_MU) 5615 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5616 ActivityRecord activity = null; 5617 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5618 activity = ActivityRecord.isInStackLocked(token); 5619 if (activity == null) { 5620 return null; 5621 } 5622 if (activity.finishing) { 5623 return null; 5624 } 5625 } 5626 5627 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5628 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5629 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5630 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5631 |PendingIntent.FLAG_UPDATE_CURRENT); 5632 5633 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5634 type, packageName, activity, resultWho, 5635 requestCode, intents, resolvedTypes, flags, options, userId); 5636 WeakReference<PendingIntentRecord> ref; 5637 ref = mIntentSenderRecords.get(key); 5638 PendingIntentRecord rec = ref != null ? ref.get() : null; 5639 if (rec != null) { 5640 if (!cancelCurrent) { 5641 if (updateCurrent) { 5642 if (rec.key.requestIntent != null) { 5643 rec.key.requestIntent.replaceExtras(intents != null ? 5644 intents[intents.length - 1] : null); 5645 } 5646 if (intents != null) { 5647 intents[intents.length-1] = rec.key.requestIntent; 5648 rec.key.allIntents = intents; 5649 rec.key.allResolvedTypes = resolvedTypes; 5650 } else { 5651 rec.key.allIntents = null; 5652 rec.key.allResolvedTypes = null; 5653 } 5654 } 5655 return rec; 5656 } 5657 rec.canceled = true; 5658 mIntentSenderRecords.remove(key); 5659 } 5660 if (noCreate) { 5661 return rec; 5662 } 5663 rec = new PendingIntentRecord(this, key, callingUid); 5664 mIntentSenderRecords.put(key, rec.ref); 5665 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5666 if (activity.pendingResults == null) { 5667 activity.pendingResults 5668 = new HashSet<WeakReference<PendingIntentRecord>>(); 5669 } 5670 activity.pendingResults.add(rec.ref); 5671 } 5672 return rec; 5673 } 5674 5675 @Override 5676 public void cancelIntentSender(IIntentSender sender) { 5677 if (!(sender instanceof PendingIntentRecord)) { 5678 return; 5679 } 5680 synchronized(this) { 5681 PendingIntentRecord rec = (PendingIntentRecord)sender; 5682 try { 5683 int uid = AppGlobals.getPackageManager() 5684 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5685 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5686 String msg = "Permission Denial: cancelIntentSender() from pid=" 5687 + Binder.getCallingPid() 5688 + ", uid=" + Binder.getCallingUid() 5689 + " is not allowed to cancel packges " 5690 + rec.key.packageName; 5691 Slog.w(TAG, msg); 5692 throw new SecurityException(msg); 5693 } 5694 } catch (RemoteException e) { 5695 throw new SecurityException(e); 5696 } 5697 cancelIntentSenderLocked(rec, true); 5698 } 5699 } 5700 5701 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5702 rec.canceled = true; 5703 mIntentSenderRecords.remove(rec.key); 5704 if (cleanActivity && rec.key.activity != null) { 5705 rec.key.activity.pendingResults.remove(rec.ref); 5706 } 5707 } 5708 5709 @Override 5710 public String getPackageForIntentSender(IIntentSender pendingResult) { 5711 if (!(pendingResult instanceof PendingIntentRecord)) { 5712 return null; 5713 } 5714 try { 5715 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5716 return res.key.packageName; 5717 } catch (ClassCastException e) { 5718 } 5719 return null; 5720 } 5721 5722 @Override 5723 public int getUidForIntentSender(IIntentSender sender) { 5724 if (sender instanceof PendingIntentRecord) { 5725 try { 5726 PendingIntentRecord res = (PendingIntentRecord)sender; 5727 return res.uid; 5728 } catch (ClassCastException e) { 5729 } 5730 } 5731 return -1; 5732 } 5733 5734 @Override 5735 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5736 if (!(pendingResult instanceof PendingIntentRecord)) { 5737 return false; 5738 } 5739 try { 5740 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5741 if (res.key.allIntents == null) { 5742 return false; 5743 } 5744 for (int i=0; i<res.key.allIntents.length; i++) { 5745 Intent intent = res.key.allIntents[i]; 5746 if (intent.getPackage() != null && intent.getComponent() != null) { 5747 return false; 5748 } 5749 } 5750 return true; 5751 } catch (ClassCastException e) { 5752 } 5753 return false; 5754 } 5755 5756 @Override 5757 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5758 if (!(pendingResult instanceof PendingIntentRecord)) { 5759 return false; 5760 } 5761 try { 5762 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5763 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5764 return true; 5765 } 5766 return false; 5767 } catch (ClassCastException e) { 5768 } 5769 return false; 5770 } 5771 5772 @Override 5773 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5774 if (!(pendingResult instanceof PendingIntentRecord)) { 5775 return null; 5776 } 5777 try { 5778 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5779 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5780 } catch (ClassCastException e) { 5781 } 5782 return null; 5783 } 5784 5785 @Override 5786 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5787 if (!(pendingResult instanceof PendingIntentRecord)) { 5788 return null; 5789 } 5790 try { 5791 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5792 Intent intent = res.key.requestIntent; 5793 if (intent != null) { 5794 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5795 || res.lastTagPrefix.equals(prefix))) { 5796 return res.lastTag; 5797 } 5798 res.lastTagPrefix = prefix; 5799 StringBuilder sb = new StringBuilder(128); 5800 if (prefix != null) { 5801 sb.append(prefix); 5802 } 5803 if (intent.getAction() != null) { 5804 sb.append(intent.getAction()); 5805 } else if (intent.getComponent() != null) { 5806 intent.getComponent().appendShortString(sb); 5807 } else { 5808 sb.append("?"); 5809 } 5810 return res.lastTag = sb.toString(); 5811 } 5812 } catch (ClassCastException e) { 5813 } 5814 return null; 5815 } 5816 5817 @Override 5818 public void setProcessLimit(int max) { 5819 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5820 "setProcessLimit()"); 5821 synchronized (this) { 5822 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5823 mProcessLimitOverride = max; 5824 } 5825 trimApplications(); 5826 } 5827 5828 @Override 5829 public int getProcessLimit() { 5830 synchronized (this) { 5831 return mProcessLimitOverride; 5832 } 5833 } 5834 5835 void foregroundTokenDied(ForegroundToken token) { 5836 synchronized (ActivityManagerService.this) { 5837 synchronized (mPidsSelfLocked) { 5838 ForegroundToken cur 5839 = mForegroundProcesses.get(token.pid); 5840 if (cur != token) { 5841 return; 5842 } 5843 mForegroundProcesses.remove(token.pid); 5844 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5845 if (pr == null) { 5846 return; 5847 } 5848 pr.forcingToForeground = null; 5849 updateProcessForegroundLocked(pr, false, false); 5850 } 5851 updateOomAdjLocked(); 5852 } 5853 } 5854 5855 @Override 5856 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5857 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5858 "setProcessForeground()"); 5859 synchronized(this) { 5860 boolean changed = false; 5861 5862 synchronized (mPidsSelfLocked) { 5863 ProcessRecord pr = mPidsSelfLocked.get(pid); 5864 if (pr == null && isForeground) { 5865 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5866 return; 5867 } 5868 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5869 if (oldToken != null) { 5870 oldToken.token.unlinkToDeath(oldToken, 0); 5871 mForegroundProcesses.remove(pid); 5872 if (pr != null) { 5873 pr.forcingToForeground = null; 5874 } 5875 changed = true; 5876 } 5877 if (isForeground && token != null) { 5878 ForegroundToken newToken = new ForegroundToken() { 5879 @Override 5880 public void binderDied() { 5881 foregroundTokenDied(this); 5882 } 5883 }; 5884 newToken.pid = pid; 5885 newToken.token = token; 5886 try { 5887 token.linkToDeath(newToken, 0); 5888 mForegroundProcesses.put(pid, newToken); 5889 pr.forcingToForeground = token; 5890 changed = true; 5891 } catch (RemoteException e) { 5892 // If the process died while doing this, we will later 5893 // do the cleanup with the process death link. 5894 } 5895 } 5896 } 5897 5898 if (changed) { 5899 updateOomAdjLocked(); 5900 } 5901 } 5902 } 5903 5904 // ========================================================= 5905 // PERMISSIONS 5906 // ========================================================= 5907 5908 static class PermissionController extends IPermissionController.Stub { 5909 ActivityManagerService mActivityManagerService; 5910 PermissionController(ActivityManagerService activityManagerService) { 5911 mActivityManagerService = activityManagerService; 5912 } 5913 5914 @Override 5915 public boolean checkPermission(String permission, int pid, int uid) { 5916 return mActivityManagerService.checkPermission(permission, pid, 5917 uid) == PackageManager.PERMISSION_GRANTED; 5918 } 5919 } 5920 5921 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5922 @Override 5923 public int checkComponentPermission(String permission, int pid, int uid, 5924 int owningUid, boolean exported) { 5925 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5926 owningUid, exported); 5927 } 5928 5929 @Override 5930 public Object getAMSLock() { 5931 return ActivityManagerService.this; 5932 } 5933 } 5934 5935 /** 5936 * This can be called with or without the global lock held. 5937 */ 5938 int checkComponentPermission(String permission, int pid, int uid, 5939 int owningUid, boolean exported) { 5940 // We might be performing an operation on behalf of an indirect binder 5941 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5942 // client identity accordingly before proceeding. 5943 Identity tlsIdentity = sCallerIdentity.get(); 5944 if (tlsIdentity != null) { 5945 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5946 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5947 uid = tlsIdentity.uid; 5948 pid = tlsIdentity.pid; 5949 } 5950 5951 if (pid == MY_PID) { 5952 return PackageManager.PERMISSION_GRANTED; 5953 } 5954 5955 return ActivityManager.checkComponentPermission(permission, uid, 5956 owningUid, exported); 5957 } 5958 5959 /** 5960 * As the only public entry point for permissions checking, this method 5961 * can enforce the semantic that requesting a check on a null global 5962 * permission is automatically denied. (Internally a null permission 5963 * string is used when calling {@link #checkComponentPermission} in cases 5964 * when only uid-based security is needed.) 5965 * 5966 * This can be called with or without the global lock held. 5967 */ 5968 @Override 5969 public int checkPermission(String permission, int pid, int uid) { 5970 if (permission == null) { 5971 return PackageManager.PERMISSION_DENIED; 5972 } 5973 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5974 } 5975 5976 /** 5977 * Binder IPC calls go through the public entry point. 5978 * This can be called with or without the global lock held. 5979 */ 5980 int checkCallingPermission(String permission) { 5981 return checkPermission(permission, 5982 Binder.getCallingPid(), 5983 UserHandle.getAppId(Binder.getCallingUid())); 5984 } 5985 5986 /** 5987 * This can be called with or without the global lock held. 5988 */ 5989 void enforceCallingPermission(String permission, String func) { 5990 if (checkCallingPermission(permission) 5991 == PackageManager.PERMISSION_GRANTED) { 5992 return; 5993 } 5994 5995 String msg = "Permission Denial: " + func + " from pid=" 5996 + Binder.getCallingPid() 5997 + ", uid=" + Binder.getCallingUid() 5998 + " requires " + permission; 5999 Slog.w(TAG, msg); 6000 throw new SecurityException(msg); 6001 } 6002 6003 /** 6004 * Determine if UID is holding permissions required to access {@link Uri} in 6005 * the given {@link ProviderInfo}. Final permission checking is always done 6006 * in {@link ContentProvider}. 6007 */ 6008 private final boolean checkHoldingPermissionsLocked( 6009 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6010 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6011 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6012 6013 if (pi.applicationInfo.uid == uid) { 6014 return true; 6015 } else if (!pi.exported) { 6016 return false; 6017 } 6018 6019 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6020 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6021 try { 6022 // check if target holds top-level <provider> permissions 6023 if (!readMet && pi.readPermission != null 6024 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6025 readMet = true; 6026 } 6027 if (!writeMet && pi.writePermission != null 6028 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6029 writeMet = true; 6030 } 6031 6032 // track if unprotected read/write is allowed; any denied 6033 // <path-permission> below removes this ability 6034 boolean allowDefaultRead = pi.readPermission == null; 6035 boolean allowDefaultWrite = pi.writePermission == null; 6036 6037 // check if target holds any <path-permission> that match uri 6038 final PathPermission[] pps = pi.pathPermissions; 6039 if (pps != null) { 6040 final String path = grantUri.uri.getPath(); 6041 int i = pps.length; 6042 while (i > 0 && (!readMet || !writeMet)) { 6043 i--; 6044 PathPermission pp = pps[i]; 6045 if (pp.match(path)) { 6046 if (!readMet) { 6047 final String pprperm = pp.getReadPermission(); 6048 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6049 + pprperm + " for " + pp.getPath() 6050 + ": match=" + pp.match(path) 6051 + " check=" + pm.checkUidPermission(pprperm, uid)); 6052 if (pprperm != null) { 6053 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 6054 readMet = true; 6055 } else { 6056 allowDefaultRead = false; 6057 } 6058 } 6059 } 6060 if (!writeMet) { 6061 final String ppwperm = pp.getWritePermission(); 6062 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6063 + ppwperm + " for " + pp.getPath() 6064 + ": match=" + pp.match(path) 6065 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6066 if (ppwperm != null) { 6067 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 6068 writeMet = true; 6069 } else { 6070 allowDefaultWrite = false; 6071 } 6072 } 6073 } 6074 } 6075 } 6076 } 6077 6078 // grant unprotected <provider> read/write, if not blocked by 6079 // <path-permission> above 6080 if (allowDefaultRead) readMet = true; 6081 if (allowDefaultWrite) writeMet = true; 6082 6083 } catch (RemoteException e) { 6084 return false; 6085 } 6086 6087 return readMet && writeMet; 6088 } 6089 6090 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6091 ProviderInfo pi = null; 6092 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6093 if (cpr != null) { 6094 pi = cpr.info; 6095 } else { 6096 try { 6097 pi = AppGlobals.getPackageManager().resolveContentProvider( 6098 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6099 } catch (RemoteException ex) { 6100 } 6101 } 6102 return pi; 6103 } 6104 6105 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6106 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6107 if (targetUris != null) { 6108 return targetUris.get(grantUri); 6109 } 6110 return null; 6111 } 6112 6113 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6114 String targetPkg, int targetUid, GrantUri grantUri) { 6115 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6116 if (targetUris == null) { 6117 targetUris = Maps.newArrayMap(); 6118 mGrantedUriPermissions.put(targetUid, targetUris); 6119 } 6120 6121 UriPermission perm = targetUris.get(grantUri); 6122 if (perm == null) { 6123 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6124 targetUris.put(grantUri, perm); 6125 } 6126 6127 return perm; 6128 } 6129 6130 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6131 final int modeFlags) { 6132 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6133 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6134 : UriPermission.STRENGTH_OWNED; 6135 6136 // Root gets to do everything. 6137 if (uid == 0) { 6138 return true; 6139 } 6140 6141 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6142 if (perms == null) return false; 6143 6144 // First look for exact match 6145 final UriPermission exactPerm = perms.get(grantUri); 6146 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6147 return true; 6148 } 6149 6150 // No exact match, look for prefixes 6151 final int N = perms.size(); 6152 for (int i = 0; i < N; i++) { 6153 final UriPermission perm = perms.valueAt(i); 6154 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6155 && perm.getStrength(modeFlags) >= minStrength) { 6156 return true; 6157 } 6158 } 6159 6160 return false; 6161 } 6162 6163 @Override 6164 public int checkUriPermission(Uri uri, int pid, int uid, 6165 final int modeFlags, int userId) { 6166 enforceNotIsolatedCaller("checkUriPermission"); 6167 6168 // Another redirected-binder-call permissions check as in 6169 // {@link checkComponentPermission}. 6170 Identity tlsIdentity = sCallerIdentity.get(); 6171 if (tlsIdentity != null) { 6172 uid = tlsIdentity.uid; 6173 pid = tlsIdentity.pid; 6174 } 6175 6176 // Our own process gets to do everything. 6177 if (pid == MY_PID) { 6178 return PackageManager.PERMISSION_GRANTED; 6179 } 6180 synchronized (this) { 6181 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6182 ? PackageManager.PERMISSION_GRANTED 6183 : PackageManager.PERMISSION_DENIED; 6184 } 6185 } 6186 6187 /** 6188 * Check if the targetPkg can be granted permission to access uri by 6189 * the callingUid using the given modeFlags. Throws a security exception 6190 * if callingUid is not allowed to do this. Returns the uid of the target 6191 * if the URI permission grant should be performed; returns -1 if it is not 6192 * needed (for example targetPkg already has permission to access the URI). 6193 * If you already know the uid of the target, you can supply it in 6194 * lastTargetUid else set that to -1. 6195 */ 6196 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6197 final int modeFlags, int lastTargetUid) { 6198 if (!Intent.isAccessUriMode(modeFlags)) { 6199 return -1; 6200 } 6201 6202 if (targetPkg != null) { 6203 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6204 "Checking grant " + targetPkg + " permission to " + grantUri); 6205 } 6206 6207 final IPackageManager pm = AppGlobals.getPackageManager(); 6208 6209 // If this is not a content: uri, we can't do anything with it. 6210 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6211 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6212 "Can't grant URI permission for non-content URI: " + grantUri); 6213 return -1; 6214 } 6215 6216 final String authority = grantUri.uri.getAuthority(); 6217 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6218 if (pi == null) { 6219 Slog.w(TAG, "No content provider found for permission check: " + 6220 grantUri.uri.toSafeString()); 6221 return -1; 6222 } 6223 6224 int targetUid = lastTargetUid; 6225 if (targetUid < 0 && targetPkg != null) { 6226 try { 6227 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6228 if (targetUid < 0) { 6229 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6230 "Can't grant URI permission no uid for: " + targetPkg); 6231 return -1; 6232 } 6233 } catch (RemoteException ex) { 6234 return -1; 6235 } 6236 } 6237 6238 if (targetUid >= 0) { 6239 // First... does the target actually need this permission? 6240 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6241 // No need to grant the target this permission. 6242 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6243 "Target " + targetPkg + " already has full permission to " + grantUri); 6244 return -1; 6245 } 6246 } else { 6247 // First... there is no target package, so can anyone access it? 6248 boolean allowed = pi.exported; 6249 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6250 if (pi.readPermission != null) { 6251 allowed = false; 6252 } 6253 } 6254 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6255 if (pi.writePermission != null) { 6256 allowed = false; 6257 } 6258 } 6259 if (allowed) { 6260 return -1; 6261 } 6262 } 6263 6264 // Second... is the provider allowing granting of URI permissions? 6265 if (!pi.grantUriPermissions) { 6266 throw new SecurityException("Provider " + pi.packageName 6267 + "/" + pi.name 6268 + " does not allow granting of Uri permissions (uri " 6269 + grantUri + ")"); 6270 } 6271 if (pi.uriPermissionPatterns != null) { 6272 final int N = pi.uriPermissionPatterns.length; 6273 boolean allowed = false; 6274 for (int i=0; i<N; i++) { 6275 if (pi.uriPermissionPatterns[i] != null 6276 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6277 allowed = true; 6278 break; 6279 } 6280 } 6281 if (!allowed) { 6282 throw new SecurityException("Provider " + pi.packageName 6283 + "/" + pi.name 6284 + " does not allow granting of permission to path of Uri " 6285 + grantUri); 6286 } 6287 } 6288 6289 // Third... does the caller itself have permission to access 6290 // this uri? 6291 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6292 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6293 // Require they hold a strong enough Uri permission 6294 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6295 throw new SecurityException("Uid " + callingUid 6296 + " does not have permission to uri " + grantUri); 6297 } 6298 } 6299 } 6300 return targetUid; 6301 } 6302 6303 @Override 6304 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6305 final int modeFlags, int userId) { 6306 enforceNotIsolatedCaller("checkGrantUriPermission"); 6307 synchronized(this) { 6308 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6309 new GrantUri(userId, uri, false), modeFlags, -1); 6310 } 6311 } 6312 6313 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6314 final int modeFlags, UriPermissionOwner owner) { 6315 if (!Intent.isAccessUriMode(modeFlags)) { 6316 return; 6317 } 6318 6319 // So here we are: the caller has the assumed permission 6320 // to the uri, and the target doesn't. Let's now give this to 6321 // the target. 6322 6323 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6324 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6325 6326 final String authority = grantUri.uri.getAuthority(); 6327 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6328 if (pi == null) { 6329 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6330 return; 6331 } 6332 6333 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6334 grantUri.prefix = true; 6335 } 6336 final UriPermission perm = findOrCreateUriPermissionLocked( 6337 pi.packageName, targetPkg, targetUid, grantUri); 6338 perm.grantModes(modeFlags, owner); 6339 } 6340 6341 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6342 final int modeFlags, UriPermissionOwner owner) { 6343 if (targetPkg == null) { 6344 throw new NullPointerException("targetPkg"); 6345 } 6346 6347 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6348 -1); 6349 if (targetUid < 0) { 6350 return; 6351 } 6352 6353 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6354 owner); 6355 } 6356 6357 static class NeededUriGrants extends ArrayList<GrantUri> { 6358 final String targetPkg; 6359 final int targetUid; 6360 final int flags; 6361 6362 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6363 this.targetPkg = targetPkg; 6364 this.targetUid = targetUid; 6365 this.flags = flags; 6366 } 6367 } 6368 6369 /** 6370 * Like checkGrantUriPermissionLocked, but takes an Intent. 6371 */ 6372 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6373 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6374 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6375 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6376 + " clip=" + (intent != null ? intent.getClipData() : null) 6377 + " from " + intent + "; flags=0x" 6378 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6379 6380 if (targetPkg == null) { 6381 throw new NullPointerException("targetPkg"); 6382 } 6383 6384 if (intent == null) { 6385 return null; 6386 } 6387 Uri data = intent.getData(); 6388 ClipData clip = intent.getClipData(); 6389 if (data == null && clip == null) { 6390 return null; 6391 } 6392 6393 if (data != null) { 6394 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data); 6395 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6396 needed != null ? needed.targetUid : -1); 6397 if (targetUid > 0) { 6398 if (needed == null) { 6399 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6400 } 6401 needed.add(grantUri); 6402 } 6403 } 6404 if (clip != null) { 6405 for (int i=0; i<clip.getItemCount(); i++) { 6406 Uri uri = clip.getItemAt(i).getUri(); 6407 if (uri != null) { 6408 int targetUid = -1; 6409 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri); 6410 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6411 needed != null ? needed.targetUid : -1); 6412 if (targetUid > 0) { 6413 if (needed == null) { 6414 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6415 } 6416 needed.add(grantUri); 6417 } 6418 } else { 6419 Intent clipIntent = clip.getItemAt(i).getIntent(); 6420 if (clipIntent != null) { 6421 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6422 callingUid, targetPkg, clipIntent, mode, needed); 6423 if (newNeeded != null) { 6424 needed = newNeeded; 6425 } 6426 } 6427 } 6428 } 6429 } 6430 6431 return needed; 6432 } 6433 6434 /** 6435 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6436 */ 6437 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6438 UriPermissionOwner owner) { 6439 if (needed != null) { 6440 for (int i=0; i<needed.size(); i++) { 6441 GrantUri grantUri = needed.get(i); 6442 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6443 grantUri, needed.flags, owner); 6444 } 6445 } 6446 } 6447 6448 void grantUriPermissionFromIntentLocked(int callingUid, 6449 String targetPkg, Intent intent, UriPermissionOwner owner) { 6450 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6451 intent, intent != null ? intent.getFlags() : 0, null); 6452 if (needed == null) { 6453 return; 6454 } 6455 6456 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6457 } 6458 6459 @Override 6460 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6461 final int modeFlags, int userId) { 6462 enforceNotIsolatedCaller("grantUriPermission"); 6463 GrantUri grantUri = new GrantUri(userId, uri, false); 6464 synchronized(this) { 6465 final ProcessRecord r = getRecordForAppLocked(caller); 6466 if (r == null) { 6467 throw new SecurityException("Unable to find app for caller " 6468 + caller 6469 + " when granting permission to uri " + grantUri); 6470 } 6471 if (targetPkg == null) { 6472 throw new IllegalArgumentException("null target"); 6473 } 6474 if (grantUri == null) { 6475 throw new IllegalArgumentException("null uri"); 6476 } 6477 6478 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6479 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6480 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6481 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6482 6483 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null); 6484 } 6485 } 6486 6487 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6488 if (perm.modeFlags == 0) { 6489 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6490 perm.targetUid); 6491 if (perms != null) { 6492 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6493 "Removing " + perm.targetUid + " permission to " + perm.uri); 6494 6495 perms.remove(perm.uri); 6496 if (perms.isEmpty()) { 6497 mGrantedUriPermissions.remove(perm.targetUid); 6498 } 6499 } 6500 } 6501 } 6502 6503 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 6504 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 6505 6506 final IPackageManager pm = AppGlobals.getPackageManager(); 6507 final String authority = grantUri.uri.getAuthority(); 6508 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6509 if (pi == null) { 6510 Slog.w(TAG, "No content provider found for permission revoke: " 6511 + grantUri.toSafeString()); 6512 return; 6513 } 6514 6515 // Does the caller have this permission on the URI? 6516 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6517 // Right now, if you are not the original owner of the permission, 6518 // you are not allowed to revoke it. 6519 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6520 throw new SecurityException("Uid " + callingUid 6521 + " does not have permission to uri " + grantUri); 6522 //} 6523 } 6524 6525 boolean persistChanged = false; 6526 6527 // Go through all of the permissions and remove any that match. 6528 int N = mGrantedUriPermissions.size(); 6529 for (int i = 0; i < N; i++) { 6530 final int targetUid = mGrantedUriPermissions.keyAt(i); 6531 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6532 6533 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6534 final UriPermission perm = it.next(); 6535 if (perm.uri.sourceUserId == grantUri.sourceUserId 6536 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 6537 if (DEBUG_URI_PERMISSION) 6538 Slog.v(TAG, 6539 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6540 persistChanged |= perm.revokeModes( 6541 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6542 if (perm.modeFlags == 0) { 6543 it.remove(); 6544 } 6545 } 6546 } 6547 6548 if (perms.isEmpty()) { 6549 mGrantedUriPermissions.remove(targetUid); 6550 N--; 6551 i--; 6552 } 6553 } 6554 6555 if (persistChanged) { 6556 schedulePersistUriGrants(); 6557 } 6558 } 6559 6560 @Override 6561 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 6562 int userId) { 6563 enforceNotIsolatedCaller("revokeUriPermission"); 6564 synchronized(this) { 6565 final ProcessRecord r = getRecordForAppLocked(caller); 6566 if (r == null) { 6567 throw new SecurityException("Unable to find app for caller " 6568 + caller 6569 + " when revoking permission to uri " + uri); 6570 } 6571 if (uri == null) { 6572 Slog.w(TAG, "revokeUriPermission: null uri"); 6573 return; 6574 } 6575 6576 if (!Intent.isAccessUriMode(modeFlags)) { 6577 return; 6578 } 6579 6580 final IPackageManager pm = AppGlobals.getPackageManager(); 6581 final String authority = uri.getAuthority(); 6582 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 6583 if (pi == null) { 6584 Slog.w(TAG, "No content provider found for permission revoke: " 6585 + uri.toSafeString()); 6586 return; 6587 } 6588 6589 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 6590 } 6591 } 6592 6593 /** 6594 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6595 * given package. 6596 * 6597 * @param packageName Package name to match, or {@code null} to apply to all 6598 * packages. 6599 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6600 * to all users. 6601 * @param persistable If persistable grants should be removed. 6602 */ 6603 private void removeUriPermissionsForPackageLocked( 6604 String packageName, int userHandle, boolean persistable) { 6605 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6606 throw new IllegalArgumentException("Must narrow by either package or user"); 6607 } 6608 6609 boolean persistChanged = false; 6610 6611 int N = mGrantedUriPermissions.size(); 6612 for (int i = 0; i < N; i++) { 6613 final int targetUid = mGrantedUriPermissions.keyAt(i); 6614 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6615 6616 // Only inspect grants matching user 6617 if (userHandle == UserHandle.USER_ALL 6618 || userHandle == UserHandle.getUserId(targetUid)) { 6619 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6620 final UriPermission perm = it.next(); 6621 6622 // Only inspect grants matching package 6623 if (packageName == null || perm.sourcePkg.equals(packageName) 6624 || perm.targetPkg.equals(packageName)) { 6625 persistChanged |= perm.revokeModes( 6626 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6627 6628 // Only remove when no modes remain; any persisted grants 6629 // will keep this alive. 6630 if (perm.modeFlags == 0) { 6631 it.remove(); 6632 } 6633 } 6634 } 6635 6636 if (perms.isEmpty()) { 6637 mGrantedUriPermissions.remove(targetUid); 6638 N--; 6639 i--; 6640 } 6641 } 6642 } 6643 6644 if (persistChanged) { 6645 schedulePersistUriGrants(); 6646 } 6647 } 6648 6649 @Override 6650 public IBinder newUriPermissionOwner(String name) { 6651 enforceNotIsolatedCaller("newUriPermissionOwner"); 6652 synchronized(this) { 6653 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6654 return owner.getExternalTokenLocked(); 6655 } 6656 } 6657 6658 @Override 6659 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 6660 final int modeFlags, int userId) { 6661 synchronized(this) { 6662 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6663 if (owner == null) { 6664 throw new IllegalArgumentException("Unknown owner: " + token); 6665 } 6666 if (fromUid != Binder.getCallingUid()) { 6667 if (Binder.getCallingUid() != Process.myUid()) { 6668 // Only system code can grant URI permissions on behalf 6669 // of other users. 6670 throw new SecurityException("nice try"); 6671 } 6672 } 6673 if (targetPkg == null) { 6674 throw new IllegalArgumentException("null target"); 6675 } 6676 if (uri == null) { 6677 throw new IllegalArgumentException("null uri"); 6678 } 6679 6680 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false), 6681 modeFlags, owner); 6682 } 6683 } 6684 6685 @Override 6686 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 6687 synchronized(this) { 6688 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6689 if (owner == null) { 6690 throw new IllegalArgumentException("Unknown owner: " + token); 6691 } 6692 6693 if (uri == null) { 6694 owner.removeUriPermissionsLocked(mode); 6695 } else { 6696 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 6697 } 6698 } 6699 } 6700 6701 private void schedulePersistUriGrants() { 6702 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6703 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6704 10 * DateUtils.SECOND_IN_MILLIS); 6705 } 6706 } 6707 6708 private void writeGrantedUriPermissions() { 6709 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6710 6711 // Snapshot permissions so we can persist without lock 6712 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6713 synchronized (this) { 6714 final int size = mGrantedUriPermissions.size(); 6715 for (int i = 0; i < size; i++) { 6716 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6717 for (UriPermission perm : perms.values()) { 6718 if (perm.persistedModeFlags != 0) { 6719 persist.add(perm.snapshot()); 6720 } 6721 } 6722 } 6723 } 6724 6725 FileOutputStream fos = null; 6726 try { 6727 fos = mGrantFile.startWrite(); 6728 6729 XmlSerializer out = new FastXmlSerializer(); 6730 out.setOutput(fos, "utf-8"); 6731 out.startDocument(null, true); 6732 out.startTag(null, TAG_URI_GRANTS); 6733 for (UriPermission.Snapshot perm : persist) { 6734 out.startTag(null, TAG_URI_GRANT); 6735 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 6736 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 6737 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6738 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6739 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6740 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6741 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6742 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6743 out.endTag(null, TAG_URI_GRANT); 6744 } 6745 out.endTag(null, TAG_URI_GRANTS); 6746 out.endDocument(); 6747 6748 mGrantFile.finishWrite(fos); 6749 } catch (IOException e) { 6750 if (fos != null) { 6751 mGrantFile.failWrite(fos); 6752 } 6753 } 6754 } 6755 6756 private void readGrantedUriPermissionsLocked() { 6757 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6758 6759 final long now = System.currentTimeMillis(); 6760 6761 FileInputStream fis = null; 6762 try { 6763 fis = mGrantFile.openRead(); 6764 final XmlPullParser in = Xml.newPullParser(); 6765 in.setInput(fis, null); 6766 6767 int type; 6768 while ((type = in.next()) != END_DOCUMENT) { 6769 final String tag = in.getName(); 6770 if (type == START_TAG) { 6771 if (TAG_URI_GRANT.equals(tag)) { 6772 final int sourceUserId; 6773 final int targetUserId; 6774 final int userHandle = readIntAttribute(in, 6775 ATTR_USER_HANDLE, UserHandle.USER_NULL); 6776 if (userHandle != UserHandle.USER_NULL) { 6777 // For backwards compatibility. 6778 sourceUserId = userHandle; 6779 targetUserId = userHandle; 6780 } else { 6781 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 6782 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 6783 } 6784 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6785 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6786 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6787 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6788 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6789 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6790 6791 // Sanity check that provider still belongs to source package 6792 final ProviderInfo pi = getProviderInfoLocked( 6793 uri.getAuthority(), sourceUserId); 6794 if (pi != null && sourcePkg.equals(pi.packageName)) { 6795 int targetUid = -1; 6796 try { 6797 targetUid = AppGlobals.getPackageManager() 6798 .getPackageUid(targetPkg, targetUserId); 6799 } catch (RemoteException e) { 6800 } 6801 if (targetUid != -1) { 6802 final UriPermission perm = findOrCreateUriPermissionLocked( 6803 sourcePkg, targetPkg, targetUid, 6804 new GrantUri(sourceUserId, uri, prefix)); 6805 perm.initPersistedModes(modeFlags, createdTime); 6806 } 6807 } else { 6808 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6809 + " but instead found " + pi); 6810 } 6811 } 6812 } 6813 } 6814 } catch (FileNotFoundException e) { 6815 // Missing grants is okay 6816 } catch (IOException e) { 6817 Log.wtf(TAG, "Failed reading Uri grants", e); 6818 } catch (XmlPullParserException e) { 6819 Log.wtf(TAG, "Failed reading Uri grants", e); 6820 } finally { 6821 IoUtils.closeQuietly(fis); 6822 } 6823 } 6824 6825 @Override 6826 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6827 enforceNotIsolatedCaller("takePersistableUriPermission"); 6828 6829 Preconditions.checkFlagsArgument(modeFlags, 6830 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6831 6832 synchronized (this) { 6833 final int callingUid = Binder.getCallingUid(); 6834 boolean persistChanged = false; 6835 GrantUri grantUri = new GrantUri(userId, uri, false); 6836 6837 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6838 new GrantUri(userId, uri, false)); 6839 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6840 new GrantUri(userId, uri, true)); 6841 6842 final boolean exactValid = (exactPerm != null) 6843 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6844 final boolean prefixValid = (prefixPerm != null) 6845 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6846 6847 if (!(exactValid || prefixValid)) { 6848 throw new SecurityException("No persistable permission grants found for UID " 6849 + callingUid + " and Uri " + grantUri.toSafeString()); 6850 } 6851 6852 if (exactValid) { 6853 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6854 } 6855 if (prefixValid) { 6856 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6857 } 6858 6859 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6860 6861 if (persistChanged) { 6862 schedulePersistUriGrants(); 6863 } 6864 } 6865 } 6866 6867 @Override 6868 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6869 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6870 6871 Preconditions.checkFlagsArgument(modeFlags, 6872 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6873 6874 synchronized (this) { 6875 final int callingUid = Binder.getCallingUid(); 6876 boolean persistChanged = false; 6877 6878 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6879 new GrantUri(userId, uri, false)); 6880 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6881 new GrantUri(userId, uri, true)); 6882 if (exactPerm == null && prefixPerm == null) { 6883 throw new SecurityException("No permission grants found for UID " + callingUid 6884 + " and Uri " + uri.toSafeString()); 6885 } 6886 6887 if (exactPerm != null) { 6888 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6889 removeUriPermissionIfNeededLocked(exactPerm); 6890 } 6891 if (prefixPerm != null) { 6892 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6893 removeUriPermissionIfNeededLocked(prefixPerm); 6894 } 6895 6896 if (persistChanged) { 6897 schedulePersistUriGrants(); 6898 } 6899 } 6900 } 6901 6902 /** 6903 * Prune any older {@link UriPermission} for the given UID until outstanding 6904 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6905 * 6906 * @return if any mutations occured that require persisting. 6907 */ 6908 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6909 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6910 if (perms == null) return false; 6911 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6912 6913 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6914 for (UriPermission perm : perms.values()) { 6915 if (perm.persistedModeFlags != 0) { 6916 persisted.add(perm); 6917 } 6918 } 6919 6920 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6921 if (trimCount <= 0) return false; 6922 6923 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6924 for (int i = 0; i < trimCount; i++) { 6925 final UriPermission perm = persisted.get(i); 6926 6927 if (DEBUG_URI_PERMISSION) { 6928 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6929 } 6930 6931 perm.releasePersistableModes(~0); 6932 removeUriPermissionIfNeededLocked(perm); 6933 } 6934 6935 return true; 6936 } 6937 6938 @Override 6939 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6940 String packageName, boolean incoming) { 6941 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6942 Preconditions.checkNotNull(packageName, "packageName"); 6943 6944 final int callingUid = Binder.getCallingUid(); 6945 final IPackageManager pm = AppGlobals.getPackageManager(); 6946 try { 6947 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6948 if (packageUid != callingUid) { 6949 throw new SecurityException( 6950 "Package " + packageName + " does not belong to calling UID " + callingUid); 6951 } 6952 } catch (RemoteException e) { 6953 throw new SecurityException("Failed to verify package name ownership"); 6954 } 6955 6956 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6957 synchronized (this) { 6958 if (incoming) { 6959 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6960 callingUid); 6961 if (perms == null) { 6962 Slog.w(TAG, "No permission grants found for " + packageName); 6963 } else { 6964 for (UriPermission perm : perms.values()) { 6965 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6966 result.add(perm.buildPersistedPublicApiObject()); 6967 } 6968 } 6969 } 6970 } else { 6971 final int size = mGrantedUriPermissions.size(); 6972 for (int i = 0; i < size; i++) { 6973 final ArrayMap<GrantUri, UriPermission> perms = 6974 mGrantedUriPermissions.valueAt(i); 6975 for (UriPermission perm : perms.values()) { 6976 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6977 result.add(perm.buildPersistedPublicApiObject()); 6978 } 6979 } 6980 } 6981 } 6982 } 6983 return new ParceledListSlice<android.content.UriPermission>(result); 6984 } 6985 6986 @Override 6987 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6988 synchronized (this) { 6989 ProcessRecord app = 6990 who != null ? getRecordForAppLocked(who) : null; 6991 if (app == null) return; 6992 6993 Message msg = Message.obtain(); 6994 msg.what = WAIT_FOR_DEBUGGER_MSG; 6995 msg.obj = app; 6996 msg.arg1 = waiting ? 1 : 0; 6997 mHandler.sendMessage(msg); 6998 } 6999 } 7000 7001 @Override 7002 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7003 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7004 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7005 outInfo.availMem = Process.getFreeMemory(); 7006 outInfo.totalMem = Process.getTotalMemory(); 7007 outInfo.threshold = homeAppMem; 7008 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7009 outInfo.hiddenAppThreshold = cachedAppMem; 7010 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7011 ProcessList.SERVICE_ADJ); 7012 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7013 ProcessList.VISIBLE_APP_ADJ); 7014 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7015 ProcessList.FOREGROUND_APP_ADJ); 7016 } 7017 7018 // ========================================================= 7019 // TASK MANAGEMENT 7020 // ========================================================= 7021 7022 @Override 7023 public List<IAppTask> getAppTasks() { 7024 int callingUid = Binder.getCallingUid(); 7025 long ident = Binder.clearCallingIdentity(); 7026 synchronized(this) { 7027 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7028 try { 7029 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7030 7031 final int N = mRecentTasks.size(); 7032 for (int i = 0; i < N; i++) { 7033 TaskRecord tr = mRecentTasks.get(i); 7034 // Skip tasks that are not created by the caller 7035 if (tr.creatorUid == callingUid) { 7036 ActivityManager.RecentTaskInfo taskInfo = 7037 createRecentTaskInfoFromTaskRecord(tr); 7038 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7039 list.add(taskImpl); 7040 } 7041 } 7042 } finally { 7043 Binder.restoreCallingIdentity(ident); 7044 } 7045 return list; 7046 } 7047 } 7048 7049 @Override 7050 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7051 final int callingUid = Binder.getCallingUid(); 7052 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7053 7054 synchronized(this) { 7055 if (localLOGV) Slog.v( 7056 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7057 7058 final boolean allowed = checkCallingPermission( 7059 android.Manifest.permission.GET_TASKS) 7060 == PackageManager.PERMISSION_GRANTED; 7061 if (!allowed) { 7062 Slog.w(TAG, "getTasks: caller " + callingUid 7063 + " does not hold GET_TASKS; limiting output"); 7064 } 7065 7066 // TODO: Improve with MRU list from all ActivityStacks. 7067 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7068 } 7069 7070 return list; 7071 } 7072 7073 TaskRecord getMostRecentTask() { 7074 return mRecentTasks.get(0); 7075 } 7076 7077 /** 7078 * Creates a new RecentTaskInfo from a TaskRecord. 7079 */ 7080 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7081 ActivityManager.RecentTaskInfo rti 7082 = new ActivityManager.RecentTaskInfo(); 7083 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 7084 rti.persistentId = tr.taskId; 7085 rti.baseIntent = new Intent(tr.getBaseIntent()); 7086 rti.origActivity = tr.origActivity; 7087 rti.description = tr.lastDescription; 7088 rti.stackId = tr.stack.mStackId; 7089 rti.userId = tr.userId; 7090 7091 // Traverse upwards looking for any break between main task activities and 7092 // utility activities. 7093 final ArrayList<ActivityRecord> activities = tr.mActivities; 7094 int activityNdx; 7095 final int numActivities = activities.size(); 7096 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities; 7097 ++activityNdx) { 7098 final ActivityRecord r = activities.get(activityNdx); 7099 if (r.intent != null && 7100 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) 7101 != 0) { 7102 break; 7103 } 7104 } 7105 if (activityNdx > 0) { 7106 // Traverse downwards starting below break looking for set label, icon. 7107 // Note that if there are activities in the task but none of them set the 7108 // recent activity values, then we do not fall back to the last set 7109 // values in the TaskRecord. 7110 rti.activityValues = new ActivityManager.RecentsActivityValues(); 7111 for (--activityNdx; activityNdx >= 0; --activityNdx) { 7112 final ActivityRecord r = activities.get(activityNdx); 7113 if (r.activityValues != null) { 7114 if (rti.activityValues.label == null) { 7115 rti.activityValues.label = r.activityValues.label; 7116 tr.lastActivityValues.label = r.activityValues.label; 7117 } 7118 if (rti.activityValues.icon == null) { 7119 rti.activityValues.icon = r.activityValues.icon; 7120 tr.lastActivityValues.icon = r.activityValues.icon; 7121 } 7122 if (rti.activityValues.colorPrimary == 0) { 7123 rti.activityValues.colorPrimary = r.activityValues.colorPrimary; 7124 tr.lastActivityValues.colorPrimary = r.activityValues.colorPrimary; 7125 } 7126 } 7127 } 7128 } else { 7129 // If there are no activity records in this task, then we use the last 7130 // resolved values 7131 rti.activityValues = 7132 new ActivityManager.RecentsActivityValues(tr.lastActivityValues); 7133 } 7134 return rti; 7135 } 7136 7137 @Override 7138 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7139 int flags, int userId) { 7140 final int callingUid = Binder.getCallingUid(); 7141 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7142 false, true, "getRecentTasks", null); 7143 7144 synchronized (this) { 7145 final boolean allowed = checkCallingPermission( 7146 android.Manifest.permission.GET_TASKS) 7147 == PackageManager.PERMISSION_GRANTED; 7148 if (!allowed) { 7149 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7150 + " does not hold GET_TASKS; limiting output"); 7151 } 7152 final boolean detailed = checkCallingPermission( 7153 android.Manifest.permission.GET_DETAILED_TASKS) 7154 == PackageManager.PERMISSION_GRANTED; 7155 7156 IPackageManager pm = AppGlobals.getPackageManager(); 7157 7158 final int N = mRecentTasks.size(); 7159 ArrayList<ActivityManager.RecentTaskInfo> res 7160 = new ArrayList<ActivityManager.RecentTaskInfo>( 7161 maxNum < N ? maxNum : N); 7162 7163 final Set<Integer> includedUsers; 7164 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7165 includedUsers = getProfileIdsLocked(userId); 7166 } else { 7167 includedUsers = new HashSet<Integer>(); 7168 } 7169 includedUsers.add(Integer.valueOf(userId)); 7170 for (int i=0; i<N && maxNum > 0; i++) { 7171 TaskRecord tr = mRecentTasks.get(i); 7172 // Only add calling user or related users recent tasks 7173 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7174 7175 // Return the entry if desired by the caller. We always return 7176 // the first entry, because callers always expect this to be the 7177 // foreground app. We may filter others if the caller has 7178 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7179 // we should exclude the entry. 7180 7181 if (i == 0 7182 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7183 || (tr.intent == null) 7184 || ((tr.intent.getFlags() 7185 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7186 if (!allowed) { 7187 // If the caller doesn't have the GET_TASKS permission, then only 7188 // allow them to see a small subset of tasks -- their own and home. 7189 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7190 continue; 7191 } 7192 } 7193 7194 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7195 if (!detailed) { 7196 rti.baseIntent.replaceExtras((Bundle)null); 7197 } 7198 7199 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7200 // Check whether this activity is currently available. 7201 try { 7202 if (rti.origActivity != null) { 7203 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7204 == null) { 7205 continue; 7206 } 7207 } else if (rti.baseIntent != null) { 7208 if (pm.queryIntentActivities(rti.baseIntent, 7209 null, 0, userId) == null) { 7210 continue; 7211 } 7212 } 7213 } catch (RemoteException e) { 7214 // Will never happen. 7215 } 7216 } 7217 7218 res.add(rti); 7219 maxNum--; 7220 } 7221 } 7222 return res; 7223 } 7224 } 7225 7226 private TaskRecord recentTaskForIdLocked(int id) { 7227 final int N = mRecentTasks.size(); 7228 for (int i=0; i<N; i++) { 7229 TaskRecord tr = mRecentTasks.get(i); 7230 if (tr.taskId == id) { 7231 return tr; 7232 } 7233 } 7234 return null; 7235 } 7236 7237 @Override 7238 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7239 synchronized (this) { 7240 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7241 "getTaskThumbnails()"); 7242 TaskRecord tr = recentTaskForIdLocked(id); 7243 if (tr != null) { 7244 return tr.getTaskThumbnailsLocked(); 7245 } 7246 } 7247 return null; 7248 } 7249 7250 @Override 7251 public Bitmap getTaskTopThumbnail(int id) { 7252 synchronized (this) { 7253 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7254 "getTaskTopThumbnail()"); 7255 TaskRecord tr = recentTaskForIdLocked(id); 7256 if (tr != null) { 7257 return tr.getTaskTopThumbnailLocked(); 7258 } 7259 } 7260 return null; 7261 } 7262 7263 @Override 7264 public void setRecentsActivityValues(IBinder token, ActivityManager.RecentsActivityValues rav) { 7265 synchronized (this) { 7266 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7267 if (r != null) { 7268 r.activityValues = rav; 7269 } 7270 } 7271 } 7272 7273 @Override 7274 public boolean removeSubTask(int taskId, int subTaskIndex) { 7275 synchronized (this) { 7276 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7277 "removeSubTask()"); 7278 long ident = Binder.clearCallingIdentity(); 7279 try { 7280 TaskRecord tr = recentTaskForIdLocked(taskId); 7281 if (tr != null) { 7282 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7283 } 7284 return false; 7285 } finally { 7286 Binder.restoreCallingIdentity(ident); 7287 } 7288 } 7289 } 7290 7291 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7292 if (!pr.killedByAm) { 7293 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7294 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7295 pr.processName, pr.setAdj, reason); 7296 pr.killedByAm = true; 7297 Process.killProcessQuiet(pr.pid); 7298 } 7299 } 7300 7301 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7302 tr.disposeThumbnail(); 7303 mRecentTasks.remove(tr); 7304 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7305 Intent baseIntent = new Intent( 7306 tr.intent != null ? tr.intent : tr.affinityIntent); 7307 ComponentName component = baseIntent.getComponent(); 7308 if (component == null) { 7309 Slog.w(TAG, "Now component for base intent of task: " + tr); 7310 return; 7311 } 7312 7313 // Find any running services associated with this app. 7314 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7315 7316 if (killProcesses) { 7317 // Find any running processes associated with this app. 7318 final String pkg = component.getPackageName(); 7319 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7320 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7321 for (int i=0; i<pmap.size(); i++) { 7322 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7323 for (int j=0; j<uids.size(); j++) { 7324 ProcessRecord proc = uids.valueAt(j); 7325 if (proc.userId != tr.userId) { 7326 continue; 7327 } 7328 if (!proc.pkgList.containsKey(pkg)) { 7329 continue; 7330 } 7331 procs.add(proc); 7332 } 7333 } 7334 7335 // Kill the running processes. 7336 for (int i=0; i<procs.size(); i++) { 7337 ProcessRecord pr = procs.get(i); 7338 if (pr == mHomeProcess) { 7339 // Don't kill the home process along with tasks from the same package. 7340 continue; 7341 } 7342 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7343 killUnneededProcessLocked(pr, "remove task"); 7344 } else { 7345 pr.waitingToKill = "remove task"; 7346 } 7347 } 7348 } 7349 } 7350 7351 /** 7352 * Removes the task with the specified task id. 7353 * 7354 * @param taskId Identifier of the task to be removed. 7355 * @param flags Additional operational flags. May be 0 or 7356 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7357 * @return Returns true if the given task was found and removed. 7358 */ 7359 private boolean removeTaskByIdLocked(int taskId, int flags) { 7360 TaskRecord tr = recentTaskForIdLocked(taskId); 7361 if (tr != null) { 7362 tr.removeTaskActivitiesLocked(-1, false); 7363 cleanUpRemovedTaskLocked(tr, flags); 7364 return true; 7365 } 7366 return false; 7367 } 7368 7369 @Override 7370 public boolean removeTask(int taskId, int flags) { 7371 synchronized (this) { 7372 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7373 "removeTask()"); 7374 long ident = Binder.clearCallingIdentity(); 7375 try { 7376 return removeTaskByIdLocked(taskId, flags); 7377 } finally { 7378 Binder.restoreCallingIdentity(ident); 7379 } 7380 } 7381 } 7382 7383 /** 7384 * TODO: Add mController hook 7385 */ 7386 @Override 7387 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7388 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7389 "moveTaskToFront()"); 7390 7391 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7392 synchronized(this) { 7393 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7394 Binder.getCallingUid(), "Task to front")) { 7395 ActivityOptions.abort(options); 7396 return; 7397 } 7398 final long origId = Binder.clearCallingIdentity(); 7399 try { 7400 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7401 if (task == null) { 7402 return; 7403 } 7404 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7405 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7406 return; 7407 } 7408 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7409 } finally { 7410 Binder.restoreCallingIdentity(origId); 7411 } 7412 ActivityOptions.abort(options); 7413 } 7414 } 7415 7416 @Override 7417 public void moveTaskToBack(int taskId) { 7418 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7419 "moveTaskToBack()"); 7420 7421 synchronized(this) { 7422 TaskRecord tr = recentTaskForIdLocked(taskId); 7423 if (tr != null) { 7424 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7425 ActivityStack stack = tr.stack; 7426 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7427 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7428 Binder.getCallingUid(), "Task to back")) { 7429 return; 7430 } 7431 } 7432 final long origId = Binder.clearCallingIdentity(); 7433 try { 7434 stack.moveTaskToBackLocked(taskId, null); 7435 } finally { 7436 Binder.restoreCallingIdentity(origId); 7437 } 7438 } 7439 } 7440 } 7441 7442 /** 7443 * Moves an activity, and all of the other activities within the same task, to the bottom 7444 * of the history stack. The activity's order within the task is unchanged. 7445 * 7446 * @param token A reference to the activity we wish to move 7447 * @param nonRoot If false then this only works if the activity is the root 7448 * of a task; if true it will work for any activity in a task. 7449 * @return Returns true if the move completed, false if not. 7450 */ 7451 @Override 7452 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7453 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7454 synchronized(this) { 7455 final long origId = Binder.clearCallingIdentity(); 7456 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7457 if (taskId >= 0) { 7458 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7459 } 7460 Binder.restoreCallingIdentity(origId); 7461 } 7462 return false; 7463 } 7464 7465 @Override 7466 public void moveTaskBackwards(int task) { 7467 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7468 "moveTaskBackwards()"); 7469 7470 synchronized(this) { 7471 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7472 Binder.getCallingUid(), "Task backwards")) { 7473 return; 7474 } 7475 final long origId = Binder.clearCallingIdentity(); 7476 moveTaskBackwardsLocked(task); 7477 Binder.restoreCallingIdentity(origId); 7478 } 7479 } 7480 7481 private final void moveTaskBackwardsLocked(int task) { 7482 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7483 } 7484 7485 @Override 7486 public IBinder getHomeActivityToken() throws RemoteException { 7487 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7488 "getHomeActivityToken()"); 7489 synchronized (this) { 7490 return mStackSupervisor.getHomeActivityToken(); 7491 } 7492 } 7493 7494 @Override 7495 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7496 IActivityContainerCallback callback) throws RemoteException { 7497 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7498 "createActivityContainer()"); 7499 synchronized (this) { 7500 if (parentActivityToken == null) { 7501 throw new IllegalArgumentException("parent token must not be null"); 7502 } 7503 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7504 if (r == null) { 7505 return null; 7506 } 7507 if (callback == null) { 7508 throw new IllegalArgumentException("callback must not be null"); 7509 } 7510 return mStackSupervisor.createActivityContainer(r, callback); 7511 } 7512 } 7513 7514 @Override 7515 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7516 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7517 "deleteActivityContainer()"); 7518 synchronized (this) { 7519 mStackSupervisor.deleteActivityContainer(container); 7520 } 7521 } 7522 7523 @Override 7524 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7525 throws RemoteException { 7526 synchronized (this) { 7527 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7528 if (stack != null) { 7529 return stack.mActivityContainer; 7530 } 7531 return null; 7532 } 7533 } 7534 7535 @Override 7536 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7537 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7538 "moveTaskToStack()"); 7539 if (stackId == HOME_STACK_ID) { 7540 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7541 new RuntimeException("here").fillInStackTrace()); 7542 } 7543 synchronized (this) { 7544 long ident = Binder.clearCallingIdentity(); 7545 try { 7546 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7547 + stackId + " toTop=" + toTop); 7548 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7549 } finally { 7550 Binder.restoreCallingIdentity(ident); 7551 } 7552 } 7553 } 7554 7555 @Override 7556 public void resizeStack(int stackBoxId, Rect bounds) { 7557 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7558 "resizeStackBox()"); 7559 long ident = Binder.clearCallingIdentity(); 7560 try { 7561 mWindowManager.resizeStack(stackBoxId, bounds); 7562 } finally { 7563 Binder.restoreCallingIdentity(ident); 7564 } 7565 } 7566 7567 @Override 7568 public List<StackInfo> getAllStackInfos() { 7569 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7570 "getAllStackInfos()"); 7571 long ident = Binder.clearCallingIdentity(); 7572 try { 7573 synchronized (this) { 7574 return mStackSupervisor.getAllStackInfosLocked(); 7575 } 7576 } finally { 7577 Binder.restoreCallingIdentity(ident); 7578 } 7579 } 7580 7581 @Override 7582 public StackInfo getStackInfo(int stackId) { 7583 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7584 "getStackInfo()"); 7585 long ident = Binder.clearCallingIdentity(); 7586 try { 7587 synchronized (this) { 7588 return mStackSupervisor.getStackInfoLocked(stackId); 7589 } 7590 } finally { 7591 Binder.restoreCallingIdentity(ident); 7592 } 7593 } 7594 7595 @Override 7596 public boolean isInHomeStack(int taskId) { 7597 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7598 "getStackInfo()"); 7599 long ident = Binder.clearCallingIdentity(); 7600 try { 7601 synchronized (this) { 7602 TaskRecord tr = recentTaskForIdLocked(taskId); 7603 if (tr != null) { 7604 return tr.stack.isHomeStack(); 7605 } 7606 } 7607 } finally { 7608 Binder.restoreCallingIdentity(ident); 7609 } 7610 return false; 7611 } 7612 7613 @Override 7614 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7615 synchronized(this) { 7616 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7617 } 7618 } 7619 7620 private boolean isLockTaskAuthorized(ComponentName name) { 7621// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7622// "startLockTaskMode()"); 7623// DevicePolicyManager dpm = (DevicePolicyManager) 7624// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7625// return dpm != null && dpm.isLockTaskPermitted(name); 7626 return true; 7627 } 7628 7629 private void startLockTaskMode(TaskRecord task) { 7630 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7631 return; 7632 } 7633 long ident = Binder.clearCallingIdentity(); 7634 try { 7635 synchronized (this) { 7636 // Since we lost lock on task, make sure it is still there. 7637 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7638 if (task != null) { 7639 mStackSupervisor.setLockTaskModeLocked(task); 7640 } 7641 } 7642 } finally { 7643 Binder.restoreCallingIdentity(ident); 7644 } 7645 } 7646 7647 @Override 7648 public void startLockTaskMode(int taskId) { 7649 long ident = Binder.clearCallingIdentity(); 7650 try { 7651 final TaskRecord task; 7652 synchronized (this) { 7653 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7654 } 7655 if (task != null) { 7656 startLockTaskMode(task); 7657 } 7658 } finally { 7659 Binder.restoreCallingIdentity(ident); 7660 } 7661 } 7662 7663 @Override 7664 public void startLockTaskMode(IBinder token) { 7665 long ident = Binder.clearCallingIdentity(); 7666 try { 7667 final TaskRecord task; 7668 synchronized (this) { 7669 final ActivityRecord r = ActivityRecord.forToken(token); 7670 if (r == null) { 7671 return; 7672 } 7673 task = r.task; 7674 } 7675 if (task != null) { 7676 startLockTaskMode(task); 7677 } 7678 } finally { 7679 Binder.restoreCallingIdentity(ident); 7680 } 7681 } 7682 7683 @Override 7684 public void stopLockTaskMode() { 7685// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7686// "stopLockTaskMode()"); 7687 synchronized (this) { 7688 mStackSupervisor.setLockTaskModeLocked(null); 7689 } 7690 } 7691 7692 @Override 7693 public boolean isInLockTaskMode() { 7694 synchronized (this) { 7695 return mStackSupervisor.isInLockTaskMode(); 7696 } 7697 } 7698 7699 // ========================================================= 7700 // CONTENT PROVIDERS 7701 // ========================================================= 7702 7703 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7704 List<ProviderInfo> providers = null; 7705 try { 7706 providers = AppGlobals.getPackageManager(). 7707 queryContentProviders(app.processName, app.uid, 7708 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7709 } catch (RemoteException ex) { 7710 } 7711 if (DEBUG_MU) 7712 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7713 int userId = app.userId; 7714 if (providers != null) { 7715 int N = providers.size(); 7716 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7717 for (int i=0; i<N; i++) { 7718 ProviderInfo cpi = 7719 (ProviderInfo)providers.get(i); 7720 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7721 cpi.name, cpi.flags); 7722 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7723 // This is a singleton provider, but a user besides the 7724 // default user is asking to initialize a process it runs 7725 // in... well, no, it doesn't actually run in this process, 7726 // it runs in the process of the default user. Get rid of it. 7727 providers.remove(i); 7728 N--; 7729 i--; 7730 continue; 7731 } 7732 7733 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7734 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7735 if (cpr == null) { 7736 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7737 mProviderMap.putProviderByClass(comp, cpr); 7738 } 7739 if (DEBUG_MU) 7740 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7741 app.pubProviders.put(cpi.name, cpr); 7742 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7743 // Don't add this if it is a platform component that is marked 7744 // to run in multiple processes, because this is actually 7745 // part of the framework so doesn't make sense to track as a 7746 // separate apk in the process. 7747 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7748 } 7749 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7750 } 7751 } 7752 return providers; 7753 } 7754 7755 /** 7756 * Check if {@link ProcessRecord} has a possible chance at accessing the 7757 * given {@link ProviderInfo}. Final permission checking is always done 7758 * in {@link ContentProvider}. 7759 */ 7760 private final String checkContentProviderPermissionLocked( 7761 ProviderInfo cpi, ProcessRecord r, int userId) { 7762 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7763 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7764 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7765 // Looking for cross-user grants before to enforce the typical cross-users permissions 7766 if (userId != UserHandle.getUserId(callingUid)) { 7767 if (perms != null) { 7768 for (GrantUri grantUri : perms.keySet()) { 7769 if (grantUri.sourceUserId == userId) { 7770 String authority = grantUri.uri.getAuthority(); 7771 if (authority.equals(cpi.authority)) { 7772 return null; 7773 } 7774 } 7775 } 7776 } 7777 } 7778 userId = handleIncomingUser(callingPid, callingUid, userId, 7779 false, true, "checkContentProviderPermissionLocked", null); 7780 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7781 cpi.applicationInfo.uid, cpi.exported) 7782 == PackageManager.PERMISSION_GRANTED) { 7783 return null; 7784 } 7785 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7786 cpi.applicationInfo.uid, cpi.exported) 7787 == PackageManager.PERMISSION_GRANTED) { 7788 return null; 7789 } 7790 7791 PathPermission[] pps = cpi.pathPermissions; 7792 if (pps != null) { 7793 int i = pps.length; 7794 while (i > 0) { 7795 i--; 7796 PathPermission pp = pps[i]; 7797 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7798 cpi.applicationInfo.uid, cpi.exported) 7799 == PackageManager.PERMISSION_GRANTED) { 7800 return null; 7801 } 7802 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7803 cpi.applicationInfo.uid, cpi.exported) 7804 == PackageManager.PERMISSION_GRANTED) { 7805 return null; 7806 } 7807 } 7808 } 7809 7810 if (perms != null) { 7811 for (GrantUri grantUri : perms.keySet()) { 7812 if (grantUri.uri.getAuthority().equals(cpi.authority)) { 7813 return null; 7814 } 7815 } 7816 } 7817 7818 String msg; 7819 if (!cpi.exported) { 7820 msg = "Permission Denial: opening provider " + cpi.name 7821 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7822 + ", uid=" + callingUid + ") that is not exported from uid " 7823 + cpi.applicationInfo.uid; 7824 } else { 7825 msg = "Permission Denial: opening provider " + cpi.name 7826 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7827 + ", uid=" + callingUid + ") requires " 7828 + cpi.readPermission + " or " + cpi.writePermission; 7829 } 7830 Slog.w(TAG, msg); 7831 return msg; 7832 } 7833 7834 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7835 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7836 if (r != null) { 7837 for (int i=0; i<r.conProviders.size(); i++) { 7838 ContentProviderConnection conn = r.conProviders.get(i); 7839 if (conn.provider == cpr) { 7840 if (DEBUG_PROVIDER) Slog.v(TAG, 7841 "Adding provider requested by " 7842 + r.processName + " from process " 7843 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7844 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7845 if (stable) { 7846 conn.stableCount++; 7847 conn.numStableIncs++; 7848 } else { 7849 conn.unstableCount++; 7850 conn.numUnstableIncs++; 7851 } 7852 return conn; 7853 } 7854 } 7855 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7856 if (stable) { 7857 conn.stableCount = 1; 7858 conn.numStableIncs = 1; 7859 } else { 7860 conn.unstableCount = 1; 7861 conn.numUnstableIncs = 1; 7862 } 7863 cpr.connections.add(conn); 7864 r.conProviders.add(conn); 7865 return conn; 7866 } 7867 cpr.addExternalProcessHandleLocked(externalProcessToken); 7868 return null; 7869 } 7870 7871 boolean decProviderCountLocked(ContentProviderConnection conn, 7872 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7873 if (conn != null) { 7874 cpr = conn.provider; 7875 if (DEBUG_PROVIDER) Slog.v(TAG, 7876 "Removing provider requested by " 7877 + conn.client.processName + " from process " 7878 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7879 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7880 if (stable) { 7881 conn.stableCount--; 7882 } else { 7883 conn.unstableCount--; 7884 } 7885 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7886 cpr.connections.remove(conn); 7887 conn.client.conProviders.remove(conn); 7888 return true; 7889 } 7890 return false; 7891 } 7892 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7893 return false; 7894 } 7895 7896 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7897 String name, IBinder token, boolean stable, int userId) { 7898 ContentProviderRecord cpr; 7899 ContentProviderConnection conn = null; 7900 ProviderInfo cpi = null; 7901 7902 synchronized(this) { 7903 ProcessRecord r = null; 7904 if (caller != null) { 7905 r = getRecordForAppLocked(caller); 7906 if (r == null) { 7907 throw new SecurityException( 7908 "Unable to find app for caller " + caller 7909 + " (pid=" + Binder.getCallingPid() 7910 + ") when getting content provider " + name); 7911 } 7912 } 7913 7914 // First check if this content provider has been published... 7915 cpr = mProviderMap.getProviderByName(name, userId); 7916 boolean providerRunning = cpr != null; 7917 if (providerRunning) { 7918 cpi = cpr.info; 7919 String msg; 7920 if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) { 7921 throw new SecurityException(msg); 7922 } 7923 7924 if (r != null && cpr.canRunHere(r)) { 7925 // This provider has been published or is in the process 7926 // of being published... but it is also allowed to run 7927 // in the caller's process, so don't make a connection 7928 // and just let the caller instantiate its own instance. 7929 ContentProviderHolder holder = cpr.newHolder(null); 7930 // don't give caller the provider object, it needs 7931 // to make its own. 7932 holder.provider = null; 7933 return holder; 7934 } 7935 7936 final long origId = Binder.clearCallingIdentity(); 7937 7938 // In this case the provider instance already exists, so we can 7939 // return it right away. 7940 conn = incProviderCountLocked(r, cpr, token, stable); 7941 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7942 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7943 // If this is a perceptible app accessing the provider, 7944 // make sure to count it as being accessed and thus 7945 // back up on the LRU list. This is good because 7946 // content providers are often expensive to start. 7947 updateLruProcessLocked(cpr.proc, false, null); 7948 } 7949 } 7950 7951 if (cpr.proc != null) { 7952 if (false) { 7953 if (cpr.name.flattenToShortString().equals( 7954 "com.android.providers.calendar/.CalendarProvider2")) { 7955 Slog.v(TAG, "****************** KILLING " 7956 + cpr.name.flattenToShortString()); 7957 Process.killProcess(cpr.proc.pid); 7958 } 7959 } 7960 boolean success = updateOomAdjLocked(cpr.proc); 7961 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7962 // NOTE: there is still a race here where a signal could be 7963 // pending on the process even though we managed to update its 7964 // adj level. Not sure what to do about this, but at least 7965 // the race is now smaller. 7966 if (!success) { 7967 // Uh oh... it looks like the provider's process 7968 // has been killed on us. We need to wait for a new 7969 // process to be started, and make sure its death 7970 // doesn't kill our process. 7971 Slog.i(TAG, 7972 "Existing provider " + cpr.name.flattenToShortString() 7973 + " is crashing; detaching " + r); 7974 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7975 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7976 if (!lastRef) { 7977 // This wasn't the last ref our process had on 7978 // the provider... we have now been killed, bail. 7979 return null; 7980 } 7981 providerRunning = false; 7982 conn = null; 7983 } 7984 } 7985 7986 Binder.restoreCallingIdentity(origId); 7987 } 7988 7989 boolean singleton; 7990 if (!providerRunning) { 7991 try { 7992 cpi = AppGlobals.getPackageManager(). 7993 resolveContentProvider(name, 7994 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7995 } catch (RemoteException ex) { 7996 } 7997 if (cpi == null) { 7998 return null; 7999 } 8000 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8001 cpi.name, cpi.flags); 8002 if (singleton) { 8003 userId = 0; 8004 } 8005 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 8006 8007 String msg; 8008 if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) { 8009 throw new SecurityException(msg); 8010 } 8011 8012 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 8013 && !cpi.processName.equals("system")) { 8014 // If this content provider does not run in the system 8015 // process, and the system is not yet ready to run other 8016 // processes, then fail fast instead of hanging. 8017 throw new IllegalArgumentException( 8018 "Attempt to launch content provider before system ready"); 8019 } 8020 8021 // Make sure that the user who owns this provider is started. If not, 8022 // we don't want to allow it to run. 8023 if (mStartedUsers.get(userId) == null) { 8024 Slog.w(TAG, "Unable to launch app " 8025 + cpi.applicationInfo.packageName + "/" 8026 + cpi.applicationInfo.uid + " for provider " 8027 + name + ": user " + userId + " is stopped"); 8028 return null; 8029 } 8030 8031 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8032 cpr = mProviderMap.getProviderByClass(comp, userId); 8033 final boolean firstClass = cpr == null; 8034 if (firstClass) { 8035 try { 8036 ApplicationInfo ai = 8037 AppGlobals.getPackageManager(). 8038 getApplicationInfo( 8039 cpi.applicationInfo.packageName, 8040 STOCK_PM_FLAGS, userId); 8041 if (ai == null) { 8042 Slog.w(TAG, "No package info for content provider " 8043 + cpi.name); 8044 return null; 8045 } 8046 ai = getAppInfoForUser(ai, userId); 8047 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8048 } catch (RemoteException ex) { 8049 // pm is in same process, this will never happen. 8050 } 8051 } 8052 8053 if (r != null && cpr.canRunHere(r)) { 8054 // If this is a multiprocess provider, then just return its 8055 // info and allow the caller to instantiate it. Only do 8056 // this if the provider is the same user as the caller's 8057 // process, or can run as root (so can be in any process). 8058 return cpr.newHolder(null); 8059 } 8060 8061 if (DEBUG_PROVIDER) { 8062 RuntimeException e = new RuntimeException("here"); 8063 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8064 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8065 } 8066 8067 // This is single process, and our app is now connecting to it. 8068 // See if we are already in the process of launching this 8069 // provider. 8070 final int N = mLaunchingProviders.size(); 8071 int i; 8072 for (i=0; i<N; i++) { 8073 if (mLaunchingProviders.get(i) == cpr) { 8074 break; 8075 } 8076 } 8077 8078 // If the provider is not already being launched, then get it 8079 // started. 8080 if (i >= N) { 8081 final long origId = Binder.clearCallingIdentity(); 8082 8083 try { 8084 // Content provider is now in use, its package can't be stopped. 8085 try { 8086 AppGlobals.getPackageManager().setPackageStoppedState( 8087 cpr.appInfo.packageName, false, userId); 8088 } catch (RemoteException e) { 8089 } catch (IllegalArgumentException e) { 8090 Slog.w(TAG, "Failed trying to unstop package " 8091 + cpr.appInfo.packageName + ": " + e); 8092 } 8093 8094 // Use existing process if already started 8095 ProcessRecord proc = getProcessRecordLocked( 8096 cpi.processName, cpr.appInfo.uid, false); 8097 if (proc != null && proc.thread != null) { 8098 if (DEBUG_PROVIDER) { 8099 Slog.d(TAG, "Installing in existing process " + proc); 8100 } 8101 proc.pubProviders.put(cpi.name, cpr); 8102 try { 8103 proc.thread.scheduleInstallProvider(cpi); 8104 } catch (RemoteException e) { 8105 } 8106 } else { 8107 proc = startProcessLocked(cpi.processName, 8108 cpr.appInfo, false, 0, "content provider", 8109 new ComponentName(cpi.applicationInfo.packageName, 8110 cpi.name), false, false, false); 8111 if (proc == null) { 8112 Slog.w(TAG, "Unable to launch app " 8113 + cpi.applicationInfo.packageName + "/" 8114 + cpi.applicationInfo.uid + " for provider " 8115 + name + ": process is bad"); 8116 return null; 8117 } 8118 } 8119 cpr.launchingApp = proc; 8120 mLaunchingProviders.add(cpr); 8121 } finally { 8122 Binder.restoreCallingIdentity(origId); 8123 } 8124 } 8125 8126 // Make sure the provider is published (the same provider class 8127 // may be published under multiple names). 8128 if (firstClass) { 8129 mProviderMap.putProviderByClass(comp, cpr); 8130 } 8131 8132 mProviderMap.putProviderByName(name, cpr); 8133 conn = incProviderCountLocked(r, cpr, token, stable); 8134 if (conn != null) { 8135 conn.waiting = true; 8136 } 8137 } 8138 } 8139 8140 // Wait for the provider to be published... 8141 synchronized (cpr) { 8142 while (cpr.provider == null) { 8143 if (cpr.launchingApp == null) { 8144 Slog.w(TAG, "Unable to launch app " 8145 + cpi.applicationInfo.packageName + "/" 8146 + cpi.applicationInfo.uid + " for provider " 8147 + name + ": launching app became null"); 8148 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8149 UserHandle.getUserId(cpi.applicationInfo.uid), 8150 cpi.applicationInfo.packageName, 8151 cpi.applicationInfo.uid, name); 8152 return null; 8153 } 8154 try { 8155 if (DEBUG_MU) { 8156 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8157 + cpr.launchingApp); 8158 } 8159 if (conn != null) { 8160 conn.waiting = true; 8161 } 8162 cpr.wait(); 8163 } catch (InterruptedException ex) { 8164 } finally { 8165 if (conn != null) { 8166 conn.waiting = false; 8167 } 8168 } 8169 } 8170 } 8171 return cpr != null ? cpr.newHolder(conn) : null; 8172 } 8173 8174 @Override 8175 public final ContentProviderHolder getContentProvider( 8176 IApplicationThread caller, String name, int userId, boolean stable) { 8177 enforceNotIsolatedCaller("getContentProvider"); 8178 if (caller == null) { 8179 String msg = "null IApplicationThread when getting content provider " 8180 + name; 8181 Slog.w(TAG, msg); 8182 throw new SecurityException(msg); 8183 } 8184 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8185 // with cross-user grant. 8186 return getContentProviderImpl(caller, name, null, stable, userId); 8187 } 8188 8189 public ContentProviderHolder getContentProviderExternal( 8190 String name, int userId, IBinder token) { 8191 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8192 "Do not have permission in call getContentProviderExternal()"); 8193 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8194 false, true, "getContentProvider", null); 8195 return getContentProviderExternalUnchecked(name, token, userId); 8196 } 8197 8198 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8199 IBinder token, int userId) { 8200 return getContentProviderImpl(null, name, token, true, userId); 8201 } 8202 8203 /** 8204 * Drop a content provider from a ProcessRecord's bookkeeping 8205 */ 8206 public void removeContentProvider(IBinder connection, boolean stable) { 8207 enforceNotIsolatedCaller("removeContentProvider"); 8208 long ident = Binder.clearCallingIdentity(); 8209 try { 8210 synchronized (this) { 8211 ContentProviderConnection conn; 8212 try { 8213 conn = (ContentProviderConnection)connection; 8214 } catch (ClassCastException e) { 8215 String msg ="removeContentProvider: " + connection 8216 + " not a ContentProviderConnection"; 8217 Slog.w(TAG, msg); 8218 throw new IllegalArgumentException(msg); 8219 } 8220 if (conn == null) { 8221 throw new NullPointerException("connection is null"); 8222 } 8223 if (decProviderCountLocked(conn, null, null, stable)) { 8224 updateOomAdjLocked(); 8225 } 8226 } 8227 } finally { 8228 Binder.restoreCallingIdentity(ident); 8229 } 8230 } 8231 8232 public void removeContentProviderExternal(String name, IBinder token) { 8233 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8234 "Do not have permission in call removeContentProviderExternal()"); 8235 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8236 } 8237 8238 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8239 synchronized (this) { 8240 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8241 if(cpr == null) { 8242 //remove from mProvidersByClass 8243 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8244 return; 8245 } 8246 8247 //update content provider record entry info 8248 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8249 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8250 if (localCpr.hasExternalProcessHandles()) { 8251 if (localCpr.removeExternalProcessHandleLocked(token)) { 8252 updateOomAdjLocked(); 8253 } else { 8254 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8255 + " with no external reference for token: " 8256 + token + "."); 8257 } 8258 } else { 8259 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8260 + " with no external references."); 8261 } 8262 } 8263 } 8264 8265 public final void publishContentProviders(IApplicationThread caller, 8266 List<ContentProviderHolder> providers) { 8267 if (providers == null) { 8268 return; 8269 } 8270 8271 enforceNotIsolatedCaller("publishContentProviders"); 8272 synchronized (this) { 8273 final ProcessRecord r = getRecordForAppLocked(caller); 8274 if (DEBUG_MU) 8275 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8276 if (r == null) { 8277 throw new SecurityException( 8278 "Unable to find app for caller " + caller 8279 + " (pid=" + Binder.getCallingPid() 8280 + ") when publishing content providers"); 8281 } 8282 8283 final long origId = Binder.clearCallingIdentity(); 8284 8285 final int N = providers.size(); 8286 for (int i=0; i<N; i++) { 8287 ContentProviderHolder src = providers.get(i); 8288 if (src == null || src.info == null || src.provider == null) { 8289 continue; 8290 } 8291 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8292 if (DEBUG_MU) 8293 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8294 if (dst != null) { 8295 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8296 mProviderMap.putProviderByClass(comp, dst); 8297 String names[] = dst.info.authority.split(";"); 8298 for (int j = 0; j < names.length; j++) { 8299 mProviderMap.putProviderByName(names[j], dst); 8300 } 8301 8302 int NL = mLaunchingProviders.size(); 8303 int j; 8304 for (j=0; j<NL; j++) { 8305 if (mLaunchingProviders.get(j) == dst) { 8306 mLaunchingProviders.remove(j); 8307 j--; 8308 NL--; 8309 } 8310 } 8311 synchronized (dst) { 8312 dst.provider = src.provider; 8313 dst.proc = r; 8314 dst.notifyAll(); 8315 } 8316 updateOomAdjLocked(r); 8317 } 8318 } 8319 8320 Binder.restoreCallingIdentity(origId); 8321 } 8322 } 8323 8324 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8325 ContentProviderConnection conn; 8326 try { 8327 conn = (ContentProviderConnection)connection; 8328 } catch (ClassCastException e) { 8329 String msg ="refContentProvider: " + connection 8330 + " not a ContentProviderConnection"; 8331 Slog.w(TAG, msg); 8332 throw new IllegalArgumentException(msg); 8333 } 8334 if (conn == null) { 8335 throw new NullPointerException("connection is null"); 8336 } 8337 8338 synchronized (this) { 8339 if (stable > 0) { 8340 conn.numStableIncs += stable; 8341 } 8342 stable = conn.stableCount + stable; 8343 if (stable < 0) { 8344 throw new IllegalStateException("stableCount < 0: " + stable); 8345 } 8346 8347 if (unstable > 0) { 8348 conn.numUnstableIncs += unstable; 8349 } 8350 unstable = conn.unstableCount + unstable; 8351 if (unstable < 0) { 8352 throw new IllegalStateException("unstableCount < 0: " + unstable); 8353 } 8354 8355 if ((stable+unstable) <= 0) { 8356 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8357 + stable + " unstable=" + unstable); 8358 } 8359 conn.stableCount = stable; 8360 conn.unstableCount = unstable; 8361 return !conn.dead; 8362 } 8363 } 8364 8365 public void unstableProviderDied(IBinder connection) { 8366 ContentProviderConnection conn; 8367 try { 8368 conn = (ContentProviderConnection)connection; 8369 } catch (ClassCastException e) { 8370 String msg ="refContentProvider: " + connection 8371 + " not a ContentProviderConnection"; 8372 Slog.w(TAG, msg); 8373 throw new IllegalArgumentException(msg); 8374 } 8375 if (conn == null) { 8376 throw new NullPointerException("connection is null"); 8377 } 8378 8379 // Safely retrieve the content provider associated with the connection. 8380 IContentProvider provider; 8381 synchronized (this) { 8382 provider = conn.provider.provider; 8383 } 8384 8385 if (provider == null) { 8386 // Um, yeah, we're way ahead of you. 8387 return; 8388 } 8389 8390 // Make sure the caller is being honest with us. 8391 if (provider.asBinder().pingBinder()) { 8392 // Er, no, still looks good to us. 8393 synchronized (this) { 8394 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8395 + " says " + conn + " died, but we don't agree"); 8396 return; 8397 } 8398 } 8399 8400 // Well look at that! It's dead! 8401 synchronized (this) { 8402 if (conn.provider.provider != provider) { 8403 // But something changed... good enough. 8404 return; 8405 } 8406 8407 ProcessRecord proc = conn.provider.proc; 8408 if (proc == null || proc.thread == null) { 8409 // Seems like the process is already cleaned up. 8410 return; 8411 } 8412 8413 // As far as we're concerned, this is just like receiving a 8414 // death notification... just a bit prematurely. 8415 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8416 + ") early provider death"); 8417 final long ident = Binder.clearCallingIdentity(); 8418 try { 8419 appDiedLocked(proc, proc.pid, proc.thread); 8420 } finally { 8421 Binder.restoreCallingIdentity(ident); 8422 } 8423 } 8424 } 8425 8426 @Override 8427 public void appNotRespondingViaProvider(IBinder connection) { 8428 enforceCallingPermission( 8429 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8430 8431 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8432 if (conn == null) { 8433 Slog.w(TAG, "ContentProviderConnection is null"); 8434 return; 8435 } 8436 8437 final ProcessRecord host = conn.provider.proc; 8438 if (host == null) { 8439 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8440 return; 8441 } 8442 8443 final long token = Binder.clearCallingIdentity(); 8444 try { 8445 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8446 } finally { 8447 Binder.restoreCallingIdentity(token); 8448 } 8449 } 8450 8451 public final void installSystemProviders() { 8452 List<ProviderInfo> providers; 8453 synchronized (this) { 8454 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8455 providers = generateApplicationProvidersLocked(app); 8456 if (providers != null) { 8457 for (int i=providers.size()-1; i>=0; i--) { 8458 ProviderInfo pi = (ProviderInfo)providers.get(i); 8459 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8460 Slog.w(TAG, "Not installing system proc provider " + pi.name 8461 + ": not system .apk"); 8462 providers.remove(i); 8463 } 8464 } 8465 } 8466 } 8467 if (providers != null) { 8468 mSystemThread.installSystemProviders(providers); 8469 } 8470 8471 mCoreSettingsObserver = new CoreSettingsObserver(this); 8472 8473 mUsageStatsService.monitorPackages(); 8474 } 8475 8476 /** 8477 * Allows app to retrieve the MIME type of a URI without having permission 8478 * to access its content provider. 8479 * 8480 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8481 * 8482 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8483 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8484 */ 8485 public String getProviderMimeType(Uri uri, int userId) { 8486 enforceNotIsolatedCaller("getProviderMimeType"); 8487 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8488 userId, false, true, "getProviderMimeType", null); 8489 final String name = uri.getAuthority(); 8490 final long ident = Binder.clearCallingIdentity(); 8491 ContentProviderHolder holder = null; 8492 8493 try { 8494 holder = getContentProviderExternalUnchecked(name, null, userId); 8495 if (holder != null) { 8496 return holder.provider.getType(uri); 8497 } 8498 } catch (RemoteException e) { 8499 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8500 return null; 8501 } finally { 8502 if (holder != null) { 8503 removeContentProviderExternalUnchecked(name, null, userId); 8504 } 8505 Binder.restoreCallingIdentity(ident); 8506 } 8507 8508 return null; 8509 } 8510 8511 // ========================================================= 8512 // GLOBAL MANAGEMENT 8513 // ========================================================= 8514 8515 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8516 boolean isolated) { 8517 String proc = customProcess != null ? customProcess : info.processName; 8518 BatteryStatsImpl.Uid.Proc ps = null; 8519 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8520 int uid = info.uid; 8521 if (isolated) { 8522 int userId = UserHandle.getUserId(uid); 8523 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8524 while (true) { 8525 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8526 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8527 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8528 } 8529 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8530 mNextIsolatedProcessUid++; 8531 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8532 // No process for this uid, use it. 8533 break; 8534 } 8535 stepsLeft--; 8536 if (stepsLeft <= 0) { 8537 return null; 8538 } 8539 } 8540 } 8541 return new ProcessRecord(stats, info, proc, uid); 8542 } 8543 8544 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8545 ProcessRecord app; 8546 if (!isolated) { 8547 app = getProcessRecordLocked(info.processName, info.uid, true); 8548 } else { 8549 app = null; 8550 } 8551 8552 if (app == null) { 8553 app = newProcessRecordLocked(info, null, isolated); 8554 mProcessNames.put(info.processName, app.uid, app); 8555 if (isolated) { 8556 mIsolatedProcesses.put(app.uid, app); 8557 } 8558 updateLruProcessLocked(app, false, null); 8559 updateOomAdjLocked(); 8560 } 8561 8562 // This package really, really can not be stopped. 8563 try { 8564 AppGlobals.getPackageManager().setPackageStoppedState( 8565 info.packageName, false, UserHandle.getUserId(app.uid)); 8566 } catch (RemoteException e) { 8567 } catch (IllegalArgumentException e) { 8568 Slog.w(TAG, "Failed trying to unstop package " 8569 + info.packageName + ": " + e); 8570 } 8571 8572 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8573 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8574 app.persistent = true; 8575 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8576 } 8577 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8578 mPersistentStartingProcesses.add(app); 8579 startProcessLocked(app, "added application", app.processName); 8580 } 8581 8582 return app; 8583 } 8584 8585 public void unhandledBack() { 8586 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8587 "unhandledBack()"); 8588 8589 synchronized(this) { 8590 final long origId = Binder.clearCallingIdentity(); 8591 try { 8592 getFocusedStack().unhandledBackLocked(); 8593 } finally { 8594 Binder.restoreCallingIdentity(origId); 8595 } 8596 } 8597 } 8598 8599 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8600 enforceNotIsolatedCaller("openContentUri"); 8601 final int userId = UserHandle.getCallingUserId(); 8602 String name = uri.getAuthority(); 8603 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8604 ParcelFileDescriptor pfd = null; 8605 if (cph != null) { 8606 // We record the binder invoker's uid in thread-local storage before 8607 // going to the content provider to open the file. Later, in the code 8608 // that handles all permissions checks, we look for this uid and use 8609 // that rather than the Activity Manager's own uid. The effect is that 8610 // we do the check against the caller's permissions even though it looks 8611 // to the content provider like the Activity Manager itself is making 8612 // the request. 8613 sCallerIdentity.set(new Identity( 8614 Binder.getCallingPid(), Binder.getCallingUid())); 8615 try { 8616 pfd = cph.provider.openFile(null, uri, "r", null); 8617 } catch (FileNotFoundException e) { 8618 // do nothing; pfd will be returned null 8619 } finally { 8620 // Ensure that whatever happens, we clean up the identity state 8621 sCallerIdentity.remove(); 8622 } 8623 8624 // We've got the fd now, so we're done with the provider. 8625 removeContentProviderExternalUnchecked(name, null, userId); 8626 } else { 8627 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8628 } 8629 return pfd; 8630 } 8631 8632 // Actually is sleeping or shutting down or whatever else in the future 8633 // is an inactive state. 8634 public boolean isSleepingOrShuttingDown() { 8635 return mSleeping || mShuttingDown; 8636 } 8637 8638 public boolean isSleeping() { 8639 return mSleeping; 8640 } 8641 8642 void goingToSleep() { 8643 synchronized(this) { 8644 mWentToSleep = true; 8645 updateEventDispatchingLocked(); 8646 goToSleepIfNeededLocked(); 8647 } 8648 } 8649 8650 void finishRunningVoiceLocked() { 8651 if (mRunningVoice) { 8652 mRunningVoice = false; 8653 goToSleepIfNeededLocked(); 8654 } 8655 } 8656 8657 void goToSleepIfNeededLocked() { 8658 if (mWentToSleep && !mRunningVoice) { 8659 if (!mSleeping) { 8660 mSleeping = true; 8661 mStackSupervisor.goingToSleepLocked(); 8662 8663 // Initialize the wake times of all processes. 8664 checkExcessivePowerUsageLocked(false); 8665 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8666 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8667 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8668 } 8669 } 8670 } 8671 8672 @Override 8673 public boolean shutdown(int timeout) { 8674 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8675 != PackageManager.PERMISSION_GRANTED) { 8676 throw new SecurityException("Requires permission " 8677 + android.Manifest.permission.SHUTDOWN); 8678 } 8679 8680 boolean timedout = false; 8681 8682 synchronized(this) { 8683 mShuttingDown = true; 8684 updateEventDispatchingLocked(); 8685 timedout = mStackSupervisor.shutdownLocked(timeout); 8686 } 8687 8688 mAppOpsService.shutdown(); 8689 mUsageStatsService.shutdown(); 8690 mBatteryStatsService.shutdown(); 8691 synchronized (this) { 8692 mProcessStats.shutdownLocked(); 8693 } 8694 8695 return timedout; 8696 } 8697 8698 public final void activitySlept(IBinder token) { 8699 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8700 8701 final long origId = Binder.clearCallingIdentity(); 8702 8703 synchronized (this) { 8704 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8705 if (r != null) { 8706 mStackSupervisor.activitySleptLocked(r); 8707 } 8708 } 8709 8710 Binder.restoreCallingIdentity(origId); 8711 } 8712 8713 void logLockScreen(String msg) { 8714 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8715 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8716 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8717 mStackSupervisor.mDismissKeyguardOnNextActivity); 8718 } 8719 8720 private void comeOutOfSleepIfNeededLocked() { 8721 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8722 if (mSleeping) { 8723 mSleeping = false; 8724 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8725 } 8726 } 8727 } 8728 8729 void wakingUp() { 8730 synchronized(this) { 8731 mWentToSleep = false; 8732 updateEventDispatchingLocked(); 8733 comeOutOfSleepIfNeededLocked(); 8734 } 8735 } 8736 8737 void startRunningVoiceLocked() { 8738 if (!mRunningVoice) { 8739 mRunningVoice = true; 8740 comeOutOfSleepIfNeededLocked(); 8741 } 8742 } 8743 8744 private void updateEventDispatchingLocked() { 8745 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8746 } 8747 8748 public void setLockScreenShown(boolean shown) { 8749 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8750 != PackageManager.PERMISSION_GRANTED) { 8751 throw new SecurityException("Requires permission " 8752 + android.Manifest.permission.DEVICE_POWER); 8753 } 8754 8755 synchronized(this) { 8756 long ident = Binder.clearCallingIdentity(); 8757 try { 8758 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8759 mLockScreenShown = shown; 8760 comeOutOfSleepIfNeededLocked(); 8761 } finally { 8762 Binder.restoreCallingIdentity(ident); 8763 } 8764 } 8765 } 8766 8767 public void stopAppSwitches() { 8768 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8769 != PackageManager.PERMISSION_GRANTED) { 8770 throw new SecurityException("Requires permission " 8771 + android.Manifest.permission.STOP_APP_SWITCHES); 8772 } 8773 8774 synchronized(this) { 8775 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8776 + APP_SWITCH_DELAY_TIME; 8777 mDidAppSwitch = false; 8778 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8779 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8780 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8781 } 8782 } 8783 8784 public void resumeAppSwitches() { 8785 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8786 != PackageManager.PERMISSION_GRANTED) { 8787 throw new SecurityException("Requires permission " 8788 + android.Manifest.permission.STOP_APP_SWITCHES); 8789 } 8790 8791 synchronized(this) { 8792 // Note that we don't execute any pending app switches... we will 8793 // let those wait until either the timeout, or the next start 8794 // activity request. 8795 mAppSwitchesAllowedTime = 0; 8796 } 8797 } 8798 8799 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8800 String name) { 8801 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8802 return true; 8803 } 8804 8805 final int perm = checkComponentPermission( 8806 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8807 callingUid, -1, true); 8808 if (perm == PackageManager.PERMISSION_GRANTED) { 8809 return true; 8810 } 8811 8812 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8813 return false; 8814 } 8815 8816 public void setDebugApp(String packageName, boolean waitForDebugger, 8817 boolean persistent) { 8818 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8819 "setDebugApp()"); 8820 8821 long ident = Binder.clearCallingIdentity(); 8822 try { 8823 // Note that this is not really thread safe if there are multiple 8824 // callers into it at the same time, but that's not a situation we 8825 // care about. 8826 if (persistent) { 8827 final ContentResolver resolver = mContext.getContentResolver(); 8828 Settings.Global.putString( 8829 resolver, Settings.Global.DEBUG_APP, 8830 packageName); 8831 Settings.Global.putInt( 8832 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8833 waitForDebugger ? 1 : 0); 8834 } 8835 8836 synchronized (this) { 8837 if (!persistent) { 8838 mOrigDebugApp = mDebugApp; 8839 mOrigWaitForDebugger = mWaitForDebugger; 8840 } 8841 mDebugApp = packageName; 8842 mWaitForDebugger = waitForDebugger; 8843 mDebugTransient = !persistent; 8844 if (packageName != null) { 8845 forceStopPackageLocked(packageName, -1, false, false, true, true, 8846 false, UserHandle.USER_ALL, "set debug app"); 8847 } 8848 } 8849 } finally { 8850 Binder.restoreCallingIdentity(ident); 8851 } 8852 } 8853 8854 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8855 synchronized (this) { 8856 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8857 if (!isDebuggable) { 8858 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8859 throw new SecurityException("Process not debuggable: " + app.packageName); 8860 } 8861 } 8862 8863 mOpenGlTraceApp = processName; 8864 } 8865 } 8866 8867 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8868 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8869 synchronized (this) { 8870 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8871 if (!isDebuggable) { 8872 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8873 throw new SecurityException("Process not debuggable: " + app.packageName); 8874 } 8875 } 8876 mProfileApp = processName; 8877 mProfileFile = profileFile; 8878 if (mProfileFd != null) { 8879 try { 8880 mProfileFd.close(); 8881 } catch (IOException e) { 8882 } 8883 mProfileFd = null; 8884 } 8885 mProfileFd = profileFd; 8886 mProfileType = 0; 8887 mAutoStopProfiler = autoStopProfiler; 8888 } 8889 } 8890 8891 @Override 8892 public void setAlwaysFinish(boolean enabled) { 8893 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8894 "setAlwaysFinish()"); 8895 8896 Settings.Global.putInt( 8897 mContext.getContentResolver(), 8898 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8899 8900 synchronized (this) { 8901 mAlwaysFinishActivities = enabled; 8902 } 8903 } 8904 8905 @Override 8906 public void setActivityController(IActivityController controller) { 8907 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8908 "setActivityController()"); 8909 synchronized (this) { 8910 mController = controller; 8911 Watchdog.getInstance().setActivityController(controller); 8912 } 8913 } 8914 8915 @Override 8916 public void setUserIsMonkey(boolean userIsMonkey) { 8917 synchronized (this) { 8918 synchronized (mPidsSelfLocked) { 8919 final int callingPid = Binder.getCallingPid(); 8920 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8921 if (precessRecord == null) { 8922 throw new SecurityException("Unknown process: " + callingPid); 8923 } 8924 if (precessRecord.instrumentationUiAutomationConnection == null) { 8925 throw new SecurityException("Only an instrumentation process " 8926 + "with a UiAutomation can call setUserIsMonkey"); 8927 } 8928 } 8929 mUserIsMonkey = userIsMonkey; 8930 } 8931 } 8932 8933 @Override 8934 public boolean isUserAMonkey() { 8935 synchronized (this) { 8936 // If there is a controller also implies the user is a monkey. 8937 return (mUserIsMonkey || mController != null); 8938 } 8939 } 8940 8941 public void requestBugReport() { 8942 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8943 SystemProperties.set("ctl.start", "bugreport"); 8944 } 8945 8946 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8947 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8948 } 8949 8950 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8951 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8952 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8953 } 8954 return KEY_DISPATCHING_TIMEOUT; 8955 } 8956 8957 @Override 8958 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8959 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8960 != PackageManager.PERMISSION_GRANTED) { 8961 throw new SecurityException("Requires permission " 8962 + android.Manifest.permission.FILTER_EVENTS); 8963 } 8964 ProcessRecord proc; 8965 long timeout; 8966 synchronized (this) { 8967 synchronized (mPidsSelfLocked) { 8968 proc = mPidsSelfLocked.get(pid); 8969 } 8970 timeout = getInputDispatchingTimeoutLocked(proc); 8971 } 8972 8973 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8974 return -1; 8975 } 8976 8977 return timeout; 8978 } 8979 8980 /** 8981 * Handle input dispatching timeouts. 8982 * Returns whether input dispatching should be aborted or not. 8983 */ 8984 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8985 final ActivityRecord activity, final ActivityRecord parent, 8986 final boolean aboveSystem, String reason) { 8987 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8988 != PackageManager.PERMISSION_GRANTED) { 8989 throw new SecurityException("Requires permission " 8990 + android.Manifest.permission.FILTER_EVENTS); 8991 } 8992 8993 final String annotation; 8994 if (reason == null) { 8995 annotation = "Input dispatching timed out"; 8996 } else { 8997 annotation = "Input dispatching timed out (" + reason + ")"; 8998 } 8999 9000 if (proc != null) { 9001 synchronized (this) { 9002 if (proc.debugging) { 9003 return false; 9004 } 9005 9006 if (mDidDexOpt) { 9007 // Give more time since we were dexopting. 9008 mDidDexOpt = false; 9009 return false; 9010 } 9011 9012 if (proc.instrumentationClass != null) { 9013 Bundle info = new Bundle(); 9014 info.putString("shortMsg", "keyDispatchingTimedOut"); 9015 info.putString("longMsg", annotation); 9016 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 9017 return true; 9018 } 9019 } 9020 mHandler.post(new Runnable() { 9021 @Override 9022 public void run() { 9023 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9024 } 9025 }); 9026 } 9027 9028 return true; 9029 } 9030 9031 public Bundle getAssistContextExtras(int requestType) { 9032 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9033 "getAssistContextExtras()"); 9034 PendingAssistExtras pae; 9035 Bundle extras = new Bundle(); 9036 synchronized (this) { 9037 ActivityRecord activity = getFocusedStack().mResumedActivity; 9038 if (activity == null) { 9039 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9040 return null; 9041 } 9042 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9043 if (activity.app == null || activity.app.thread == null) { 9044 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9045 return extras; 9046 } 9047 if (activity.app.pid == Binder.getCallingPid()) { 9048 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9049 return extras; 9050 } 9051 pae = new PendingAssistExtras(activity); 9052 try { 9053 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9054 requestType); 9055 mPendingAssistExtras.add(pae); 9056 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9057 } catch (RemoteException e) { 9058 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9059 return extras; 9060 } 9061 } 9062 synchronized (pae) { 9063 while (!pae.haveResult) { 9064 try { 9065 pae.wait(); 9066 } catch (InterruptedException e) { 9067 } 9068 } 9069 if (pae.result != null) { 9070 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9071 } 9072 } 9073 synchronized (this) { 9074 mPendingAssistExtras.remove(pae); 9075 mHandler.removeCallbacks(pae); 9076 } 9077 return extras; 9078 } 9079 9080 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9081 PendingAssistExtras pae = (PendingAssistExtras)token; 9082 synchronized (pae) { 9083 pae.result = extras; 9084 pae.haveResult = true; 9085 pae.notifyAll(); 9086 } 9087 } 9088 9089 public void registerProcessObserver(IProcessObserver observer) { 9090 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9091 "registerProcessObserver()"); 9092 synchronized (this) { 9093 mProcessObservers.register(observer); 9094 } 9095 } 9096 9097 @Override 9098 public void unregisterProcessObserver(IProcessObserver observer) { 9099 synchronized (this) { 9100 mProcessObservers.unregister(observer); 9101 } 9102 } 9103 9104 @Override 9105 public boolean convertFromTranslucent(IBinder token) { 9106 final long origId = Binder.clearCallingIdentity(); 9107 try { 9108 synchronized (this) { 9109 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9110 if (r == null) { 9111 return false; 9112 } 9113 if (r.changeWindowTranslucency(true)) { 9114 mWindowManager.setAppFullscreen(token, true); 9115 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9116 return true; 9117 } 9118 return false; 9119 } 9120 } finally { 9121 Binder.restoreCallingIdentity(origId); 9122 } 9123 } 9124 9125 @Override 9126 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9127 final long origId = Binder.clearCallingIdentity(); 9128 try { 9129 synchronized (this) { 9130 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9131 if (r == null) { 9132 return false; 9133 } 9134 if (r.changeWindowTranslucency(false)) { 9135 r.task.stack.convertToTranslucent(r, options); 9136 mWindowManager.setAppFullscreen(token, false); 9137 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9138 return true; 9139 } 9140 return false; 9141 } 9142 } finally { 9143 Binder.restoreCallingIdentity(origId); 9144 } 9145 } 9146 9147 @Override 9148 public ActivityOptions getActivityOptions(IBinder token) { 9149 final long origId = Binder.clearCallingIdentity(); 9150 try { 9151 synchronized (this) { 9152 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9153 if (r != null) { 9154 final ActivityOptions activityOptions = r.pendingOptions; 9155 r.pendingOptions = null; 9156 return activityOptions; 9157 } 9158 return null; 9159 } 9160 } finally { 9161 Binder.restoreCallingIdentity(origId); 9162 } 9163 } 9164 9165 @Override 9166 public void setImmersive(IBinder token, boolean immersive) { 9167 synchronized(this) { 9168 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9169 if (r == null) { 9170 throw new IllegalArgumentException(); 9171 } 9172 r.immersive = immersive; 9173 9174 // update associated state if we're frontmost 9175 if (r == mFocusedActivity) { 9176 if (DEBUG_IMMERSIVE) { 9177 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9178 } 9179 applyUpdateLockStateLocked(r); 9180 } 9181 } 9182 } 9183 9184 @Override 9185 public boolean isImmersive(IBinder token) { 9186 synchronized (this) { 9187 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9188 if (r == null) { 9189 throw new IllegalArgumentException(); 9190 } 9191 return r.immersive; 9192 } 9193 } 9194 9195 public boolean isTopActivityImmersive() { 9196 enforceNotIsolatedCaller("startActivity"); 9197 synchronized (this) { 9198 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9199 return (r != null) ? r.immersive : false; 9200 } 9201 } 9202 9203 public final void enterSafeMode() { 9204 synchronized(this) { 9205 // It only makes sense to do this before the system is ready 9206 // and started launching other packages. 9207 if (!mSystemReady) { 9208 try { 9209 AppGlobals.getPackageManager().enterSafeMode(); 9210 } catch (RemoteException e) { 9211 } 9212 } 9213 9214 mSafeMode = true; 9215 } 9216 } 9217 9218 public final void showSafeModeOverlay() { 9219 View v = LayoutInflater.from(mContext).inflate( 9220 com.android.internal.R.layout.safe_mode, null); 9221 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9222 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9223 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9224 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9225 lp.gravity = Gravity.BOTTOM | Gravity.START; 9226 lp.format = v.getBackground().getOpacity(); 9227 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9228 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9229 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9230 ((WindowManager)mContext.getSystemService( 9231 Context.WINDOW_SERVICE)).addView(v, lp); 9232 } 9233 9234 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9235 if (!(sender instanceof PendingIntentRecord)) { 9236 return; 9237 } 9238 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9239 synchronized (stats) { 9240 if (mBatteryStatsService.isOnBattery()) { 9241 mBatteryStatsService.enforceCallingPermission(); 9242 PendingIntentRecord rec = (PendingIntentRecord)sender; 9243 int MY_UID = Binder.getCallingUid(); 9244 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9245 BatteryStatsImpl.Uid.Pkg pkg = 9246 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9247 sourcePkg != null ? sourcePkg : rec.key.packageName); 9248 pkg.incWakeupsLocked(); 9249 } 9250 } 9251 } 9252 9253 public boolean killPids(int[] pids, String pReason, boolean secure) { 9254 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9255 throw new SecurityException("killPids only available to the system"); 9256 } 9257 String reason = (pReason == null) ? "Unknown" : pReason; 9258 // XXX Note: don't acquire main activity lock here, because the window 9259 // manager calls in with its locks held. 9260 9261 boolean killed = false; 9262 synchronized (mPidsSelfLocked) { 9263 int[] types = new int[pids.length]; 9264 int worstType = 0; 9265 for (int i=0; i<pids.length; i++) { 9266 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9267 if (proc != null) { 9268 int type = proc.setAdj; 9269 types[i] = type; 9270 if (type > worstType) { 9271 worstType = type; 9272 } 9273 } 9274 } 9275 9276 // If the worst oom_adj is somewhere in the cached proc LRU range, 9277 // then constrain it so we will kill all cached procs. 9278 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9279 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9280 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9281 } 9282 9283 // If this is not a secure call, don't let it kill processes that 9284 // are important. 9285 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9286 worstType = ProcessList.SERVICE_ADJ; 9287 } 9288 9289 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9290 for (int i=0; i<pids.length; i++) { 9291 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9292 if (proc == null) { 9293 continue; 9294 } 9295 int adj = proc.setAdj; 9296 if (adj >= worstType && !proc.killedByAm) { 9297 killUnneededProcessLocked(proc, reason); 9298 killed = true; 9299 } 9300 } 9301 } 9302 return killed; 9303 } 9304 9305 @Override 9306 public void killUid(int uid, String reason) { 9307 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9308 throw new SecurityException("killUid only available to the system"); 9309 } 9310 synchronized (this) { 9311 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9312 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9313 reason != null ? reason : "kill uid"); 9314 } 9315 } 9316 9317 @Override 9318 public boolean killProcessesBelowForeground(String reason) { 9319 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9320 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9321 } 9322 9323 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9324 } 9325 9326 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9327 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9328 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9329 } 9330 9331 boolean killed = false; 9332 synchronized (mPidsSelfLocked) { 9333 final int size = mPidsSelfLocked.size(); 9334 for (int i = 0; i < size; i++) { 9335 final int pid = mPidsSelfLocked.keyAt(i); 9336 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9337 if (proc == null) continue; 9338 9339 final int adj = proc.setAdj; 9340 if (adj > belowAdj && !proc.killedByAm) { 9341 killUnneededProcessLocked(proc, reason); 9342 killed = true; 9343 } 9344 } 9345 } 9346 return killed; 9347 } 9348 9349 @Override 9350 public void hang(final IBinder who, boolean allowRestart) { 9351 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9352 != PackageManager.PERMISSION_GRANTED) { 9353 throw new SecurityException("Requires permission " 9354 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9355 } 9356 9357 final IBinder.DeathRecipient death = new DeathRecipient() { 9358 @Override 9359 public void binderDied() { 9360 synchronized (this) { 9361 notifyAll(); 9362 } 9363 } 9364 }; 9365 9366 try { 9367 who.linkToDeath(death, 0); 9368 } catch (RemoteException e) { 9369 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9370 return; 9371 } 9372 9373 synchronized (this) { 9374 Watchdog.getInstance().setAllowRestart(allowRestart); 9375 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9376 synchronized (death) { 9377 while (who.isBinderAlive()) { 9378 try { 9379 death.wait(); 9380 } catch (InterruptedException e) { 9381 } 9382 } 9383 } 9384 Watchdog.getInstance().setAllowRestart(true); 9385 } 9386 } 9387 9388 @Override 9389 public void restart() { 9390 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9391 != PackageManager.PERMISSION_GRANTED) { 9392 throw new SecurityException("Requires permission " 9393 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9394 } 9395 9396 Log.i(TAG, "Sending shutdown broadcast..."); 9397 9398 BroadcastReceiver br = new BroadcastReceiver() { 9399 @Override public void onReceive(Context context, Intent intent) { 9400 // Now the broadcast is done, finish up the low-level shutdown. 9401 Log.i(TAG, "Shutting down activity manager..."); 9402 shutdown(10000); 9403 Log.i(TAG, "Shutdown complete, restarting!"); 9404 Process.killProcess(Process.myPid()); 9405 System.exit(10); 9406 } 9407 }; 9408 9409 // First send the high-level shut down broadcast. 9410 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9411 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9412 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9413 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9414 mContext.sendOrderedBroadcastAsUser(intent, 9415 UserHandle.ALL, null, br, mHandler, 0, null, null); 9416 */ 9417 br.onReceive(mContext, intent); 9418 } 9419 9420 private long getLowRamTimeSinceIdle(long now) { 9421 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9422 } 9423 9424 @Override 9425 public void performIdleMaintenance() { 9426 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9427 != PackageManager.PERMISSION_GRANTED) { 9428 throw new SecurityException("Requires permission " 9429 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9430 } 9431 9432 synchronized (this) { 9433 final long now = SystemClock.uptimeMillis(); 9434 final long timeSinceLastIdle = now - mLastIdleTime; 9435 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9436 mLastIdleTime = now; 9437 mLowRamTimeSinceLastIdle = 0; 9438 if (mLowRamStartTime != 0) { 9439 mLowRamStartTime = now; 9440 } 9441 9442 StringBuilder sb = new StringBuilder(128); 9443 sb.append("Idle maintenance over "); 9444 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9445 sb.append(" low RAM for "); 9446 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9447 Slog.i(TAG, sb.toString()); 9448 9449 // If at least 1/3 of our time since the last idle period has been spent 9450 // with RAM low, then we want to kill processes. 9451 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9452 9453 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9454 ProcessRecord proc = mLruProcesses.get(i); 9455 if (proc.notCachedSinceIdle) { 9456 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9457 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9458 if (doKilling && proc.initialIdlePss != 0 9459 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9460 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9461 + " from " + proc.initialIdlePss + ")"); 9462 } 9463 } 9464 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9465 proc.notCachedSinceIdle = true; 9466 proc.initialIdlePss = 0; 9467 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9468 isSleeping(), now); 9469 } 9470 } 9471 9472 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9473 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9474 } 9475 } 9476 9477 private void retrieveSettings() { 9478 final ContentResolver resolver = mContext.getContentResolver(); 9479 String debugApp = Settings.Global.getString( 9480 resolver, Settings.Global.DEBUG_APP); 9481 boolean waitForDebugger = Settings.Global.getInt( 9482 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9483 boolean alwaysFinishActivities = Settings.Global.getInt( 9484 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9485 boolean forceRtl = Settings.Global.getInt( 9486 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9487 // Transfer any global setting for forcing RTL layout, into a System Property 9488 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9489 9490 Configuration configuration = new Configuration(); 9491 Settings.System.getConfiguration(resolver, configuration); 9492 if (forceRtl) { 9493 // This will take care of setting the correct layout direction flags 9494 configuration.setLayoutDirection(configuration.locale); 9495 } 9496 9497 synchronized (this) { 9498 mDebugApp = mOrigDebugApp = debugApp; 9499 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9500 mAlwaysFinishActivities = alwaysFinishActivities; 9501 // This happens before any activities are started, so we can 9502 // change mConfiguration in-place. 9503 updateConfigurationLocked(configuration, null, false, true); 9504 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9505 } 9506 } 9507 9508 public boolean testIsSystemReady() { 9509 // no need to synchronize(this) just to read & return the value 9510 return mSystemReady; 9511 } 9512 9513 private static File getCalledPreBootReceiversFile() { 9514 File dataDir = Environment.getDataDirectory(); 9515 File systemDir = new File(dataDir, "system"); 9516 File fname = new File(systemDir, "called_pre_boots.dat"); 9517 return fname; 9518 } 9519 9520 static final int LAST_DONE_VERSION = 10000; 9521 9522 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9523 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9524 File file = getCalledPreBootReceiversFile(); 9525 FileInputStream fis = null; 9526 try { 9527 fis = new FileInputStream(file); 9528 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9529 int fvers = dis.readInt(); 9530 if (fvers == LAST_DONE_VERSION) { 9531 String vers = dis.readUTF(); 9532 String codename = dis.readUTF(); 9533 String build = dis.readUTF(); 9534 if (android.os.Build.VERSION.RELEASE.equals(vers) 9535 && android.os.Build.VERSION.CODENAME.equals(codename) 9536 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9537 int num = dis.readInt(); 9538 while (num > 0) { 9539 num--; 9540 String pkg = dis.readUTF(); 9541 String cls = dis.readUTF(); 9542 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9543 } 9544 } 9545 } 9546 } catch (FileNotFoundException e) { 9547 } catch (IOException e) { 9548 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9549 } finally { 9550 if (fis != null) { 9551 try { 9552 fis.close(); 9553 } catch (IOException e) { 9554 } 9555 } 9556 } 9557 return lastDoneReceivers; 9558 } 9559 9560 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9561 File file = getCalledPreBootReceiversFile(); 9562 FileOutputStream fos = null; 9563 DataOutputStream dos = null; 9564 try { 9565 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9566 fos = new FileOutputStream(file); 9567 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9568 dos.writeInt(LAST_DONE_VERSION); 9569 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9570 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9571 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9572 dos.writeInt(list.size()); 9573 for (int i=0; i<list.size(); i++) { 9574 dos.writeUTF(list.get(i).getPackageName()); 9575 dos.writeUTF(list.get(i).getClassName()); 9576 } 9577 } catch (IOException e) { 9578 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9579 file.delete(); 9580 } finally { 9581 FileUtils.sync(fos); 9582 if (dos != null) { 9583 try { 9584 dos.close(); 9585 } catch (IOException e) { 9586 // TODO Auto-generated catch block 9587 e.printStackTrace(); 9588 } 9589 } 9590 } 9591 } 9592 9593 public void systemReady(final Runnable goingCallback) { 9594 synchronized(this) { 9595 if (mSystemReady) { 9596 if (goingCallback != null) goingCallback.run(); 9597 return; 9598 } 9599 9600 // Check to see if there are any update receivers to run. 9601 if (!mDidUpdate) { 9602 if (mWaitingUpdate) { 9603 return; 9604 } 9605 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9606 List<ResolveInfo> ris = null; 9607 try { 9608 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9609 intent, null, 0, 0); 9610 } catch (RemoteException e) { 9611 } 9612 if (ris != null) { 9613 for (int i=ris.size()-1; i>=0; i--) { 9614 if ((ris.get(i).activityInfo.applicationInfo.flags 9615 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9616 ris.remove(i); 9617 } 9618 } 9619 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9620 9621 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9622 9623 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9624 for (int i=0; i<ris.size(); i++) { 9625 ActivityInfo ai = ris.get(i).activityInfo; 9626 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9627 if (lastDoneReceivers.contains(comp)) { 9628 // We already did the pre boot receiver for this app with the current 9629 // platform version, so don't do it again... 9630 ris.remove(i); 9631 i--; 9632 // ...however, do keep it as one that has been done, so we don't 9633 // forget about it when rewriting the file of last done receivers. 9634 doneReceivers.add(comp); 9635 } 9636 } 9637 9638 final int[] users = getUsersLocked(); 9639 for (int i=0; i<ris.size(); i++) { 9640 ActivityInfo ai = ris.get(i).activityInfo; 9641 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9642 doneReceivers.add(comp); 9643 intent.setComponent(comp); 9644 for (int j=0; j<users.length; j++) { 9645 IIntentReceiver finisher = null; 9646 if (i == ris.size()-1 && j == users.length-1) { 9647 finisher = new IIntentReceiver.Stub() { 9648 public void performReceive(Intent intent, int resultCode, 9649 String data, Bundle extras, boolean ordered, 9650 boolean sticky, int sendingUser) { 9651 // The raw IIntentReceiver interface is called 9652 // with the AM lock held, so redispatch to 9653 // execute our code without the lock. 9654 mHandler.post(new Runnable() { 9655 public void run() { 9656 synchronized (ActivityManagerService.this) { 9657 mDidUpdate = true; 9658 } 9659 writeLastDonePreBootReceivers(doneReceivers); 9660 showBootMessage(mContext.getText( 9661 R.string.android_upgrading_complete), 9662 false); 9663 systemReady(goingCallback); 9664 } 9665 }); 9666 } 9667 }; 9668 } 9669 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9670 + " for user " + users[j]); 9671 broadcastIntentLocked(null, null, intent, null, finisher, 9672 0, null, null, null, AppOpsManager.OP_NONE, 9673 true, false, MY_PID, Process.SYSTEM_UID, 9674 users[j]); 9675 if (finisher != null) { 9676 mWaitingUpdate = true; 9677 } 9678 } 9679 } 9680 } 9681 if (mWaitingUpdate) { 9682 return; 9683 } 9684 mDidUpdate = true; 9685 } 9686 9687 mAppOpsService.systemReady(); 9688 mUsageStatsService.systemReady(); 9689 mSystemReady = true; 9690 } 9691 9692 ArrayList<ProcessRecord> procsToKill = null; 9693 synchronized(mPidsSelfLocked) { 9694 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9695 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9696 if (!isAllowedWhileBooting(proc.info)){ 9697 if (procsToKill == null) { 9698 procsToKill = new ArrayList<ProcessRecord>(); 9699 } 9700 procsToKill.add(proc); 9701 } 9702 } 9703 } 9704 9705 synchronized(this) { 9706 if (procsToKill != null) { 9707 for (int i=procsToKill.size()-1; i>=0; i--) { 9708 ProcessRecord proc = procsToKill.get(i); 9709 Slog.i(TAG, "Removing system update proc: " + proc); 9710 removeProcessLocked(proc, true, false, "system update done"); 9711 } 9712 } 9713 9714 // Now that we have cleaned up any update processes, we 9715 // are ready to start launching real processes and know that 9716 // we won't trample on them any more. 9717 mProcessesReady = true; 9718 } 9719 9720 Slog.i(TAG, "System now ready"); 9721 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9722 SystemClock.uptimeMillis()); 9723 9724 synchronized(this) { 9725 // Make sure we have no pre-ready processes sitting around. 9726 9727 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9728 ResolveInfo ri = mContext.getPackageManager() 9729 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9730 STOCK_PM_FLAGS); 9731 CharSequence errorMsg = null; 9732 if (ri != null) { 9733 ActivityInfo ai = ri.activityInfo; 9734 ApplicationInfo app = ai.applicationInfo; 9735 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9736 mTopAction = Intent.ACTION_FACTORY_TEST; 9737 mTopData = null; 9738 mTopComponent = new ComponentName(app.packageName, 9739 ai.name); 9740 } else { 9741 errorMsg = mContext.getResources().getText( 9742 com.android.internal.R.string.factorytest_not_system); 9743 } 9744 } else { 9745 errorMsg = mContext.getResources().getText( 9746 com.android.internal.R.string.factorytest_no_action); 9747 } 9748 if (errorMsg != null) { 9749 mTopAction = null; 9750 mTopData = null; 9751 mTopComponent = null; 9752 Message msg = Message.obtain(); 9753 msg.what = SHOW_FACTORY_ERROR_MSG; 9754 msg.getData().putCharSequence("msg", errorMsg); 9755 mHandler.sendMessage(msg); 9756 } 9757 } 9758 } 9759 9760 retrieveSettings(); 9761 9762 synchronized (this) { 9763 readGrantedUriPermissionsLocked(); 9764 } 9765 9766 if (goingCallback != null) goingCallback.run(); 9767 9768 mSystemServiceManager.startUser(mCurrentUserId); 9769 9770 synchronized (this) { 9771 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9772 try { 9773 List apps = AppGlobals.getPackageManager(). 9774 getPersistentApplications(STOCK_PM_FLAGS); 9775 if (apps != null) { 9776 int N = apps.size(); 9777 int i; 9778 for (i=0; i<N; i++) { 9779 ApplicationInfo info 9780 = (ApplicationInfo)apps.get(i); 9781 if (info != null && 9782 !info.packageName.equals("android")) { 9783 addAppLocked(info, false); 9784 } 9785 } 9786 } 9787 } catch (RemoteException ex) { 9788 // pm is in same process, this will never happen. 9789 } 9790 } 9791 9792 // Start up initial activity. 9793 mBooting = true; 9794 9795 try { 9796 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9797 Message msg = Message.obtain(); 9798 msg.what = SHOW_UID_ERROR_MSG; 9799 mHandler.sendMessage(msg); 9800 } 9801 } catch (RemoteException e) { 9802 } 9803 9804 long ident = Binder.clearCallingIdentity(); 9805 try { 9806 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9807 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9808 | Intent.FLAG_RECEIVER_FOREGROUND); 9809 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9810 broadcastIntentLocked(null, null, intent, 9811 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9812 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9813 intent = new Intent(Intent.ACTION_USER_STARTING); 9814 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9815 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9816 broadcastIntentLocked(null, null, intent, 9817 null, new IIntentReceiver.Stub() { 9818 @Override 9819 public void performReceive(Intent intent, int resultCode, String data, 9820 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9821 throws RemoteException { 9822 } 9823 }, 0, null, null, 9824 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9825 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9826 } catch (Throwable t) { 9827 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 9828 } finally { 9829 Binder.restoreCallingIdentity(ident); 9830 } 9831 mStackSupervisor.resumeTopActivitiesLocked(); 9832 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9833 } 9834 } 9835 9836 private boolean makeAppCrashingLocked(ProcessRecord app, 9837 String shortMsg, String longMsg, String stackTrace) { 9838 app.crashing = true; 9839 app.crashingReport = generateProcessError(app, 9840 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9841 startAppProblemLocked(app); 9842 app.stopFreezingAllLocked(); 9843 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9844 } 9845 9846 private void makeAppNotRespondingLocked(ProcessRecord app, 9847 String activity, String shortMsg, String longMsg) { 9848 app.notResponding = true; 9849 app.notRespondingReport = generateProcessError(app, 9850 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9851 activity, shortMsg, longMsg, null); 9852 startAppProblemLocked(app); 9853 app.stopFreezingAllLocked(); 9854 } 9855 9856 /** 9857 * Generate a process error record, suitable for attachment to a ProcessRecord. 9858 * 9859 * @param app The ProcessRecord in which the error occurred. 9860 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9861 * ActivityManager.AppErrorStateInfo 9862 * @param activity The activity associated with the crash, if known. 9863 * @param shortMsg Short message describing the crash. 9864 * @param longMsg Long message describing the crash. 9865 * @param stackTrace Full crash stack trace, may be null. 9866 * 9867 * @return Returns a fully-formed AppErrorStateInfo record. 9868 */ 9869 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9870 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9871 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9872 9873 report.condition = condition; 9874 report.processName = app.processName; 9875 report.pid = app.pid; 9876 report.uid = app.info.uid; 9877 report.tag = activity; 9878 report.shortMsg = shortMsg; 9879 report.longMsg = longMsg; 9880 report.stackTrace = stackTrace; 9881 9882 return report; 9883 } 9884 9885 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9886 synchronized (this) { 9887 app.crashing = false; 9888 app.crashingReport = null; 9889 app.notResponding = false; 9890 app.notRespondingReport = null; 9891 if (app.anrDialog == fromDialog) { 9892 app.anrDialog = null; 9893 } 9894 if (app.waitDialog == fromDialog) { 9895 app.waitDialog = null; 9896 } 9897 if (app.pid > 0 && app.pid != MY_PID) { 9898 handleAppCrashLocked(app, null, null, null); 9899 killUnneededProcessLocked(app, "user request after error"); 9900 } 9901 } 9902 } 9903 9904 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9905 String stackTrace) { 9906 long now = SystemClock.uptimeMillis(); 9907 9908 Long crashTime; 9909 if (!app.isolated) { 9910 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9911 } else { 9912 crashTime = null; 9913 } 9914 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9915 // This process loses! 9916 Slog.w(TAG, "Process " + app.info.processName 9917 + " has crashed too many times: killing!"); 9918 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9919 app.userId, app.info.processName, app.uid); 9920 mStackSupervisor.handleAppCrashLocked(app); 9921 if (!app.persistent) { 9922 // We don't want to start this process again until the user 9923 // explicitly does so... but for persistent process, we really 9924 // need to keep it running. If a persistent process is actually 9925 // repeatedly crashing, then badness for everyone. 9926 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9927 app.info.processName); 9928 if (!app.isolated) { 9929 // XXX We don't have a way to mark isolated processes 9930 // as bad, since they don't have a peristent identity. 9931 mBadProcesses.put(app.info.processName, app.uid, 9932 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9933 mProcessCrashTimes.remove(app.info.processName, app.uid); 9934 } 9935 app.bad = true; 9936 app.removed = true; 9937 // Don't let services in this process be restarted and potentially 9938 // annoy the user repeatedly. Unless it is persistent, since those 9939 // processes run critical code. 9940 removeProcessLocked(app, false, false, "crash"); 9941 mStackSupervisor.resumeTopActivitiesLocked(); 9942 return false; 9943 } 9944 mStackSupervisor.resumeTopActivitiesLocked(); 9945 } else { 9946 mStackSupervisor.finishTopRunningActivityLocked(app); 9947 } 9948 9949 // Bump up the crash count of any services currently running in the proc. 9950 for (int i=app.services.size()-1; i>=0; i--) { 9951 // Any services running in the application need to be placed 9952 // back in the pending list. 9953 ServiceRecord sr = app.services.valueAt(i); 9954 sr.crashCount++; 9955 } 9956 9957 // If the crashing process is what we consider to be the "home process" and it has been 9958 // replaced by a third-party app, clear the package preferred activities from packages 9959 // with a home activity running in the process to prevent a repeatedly crashing app 9960 // from blocking the user to manually clear the list. 9961 final ArrayList<ActivityRecord> activities = app.activities; 9962 if (app == mHomeProcess && activities.size() > 0 9963 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9964 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9965 final ActivityRecord r = activities.get(activityNdx); 9966 if (r.isHomeActivity()) { 9967 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9968 try { 9969 ActivityThread.getPackageManager() 9970 .clearPackagePreferredActivities(r.packageName); 9971 } catch (RemoteException c) { 9972 // pm is in same process, this will never happen. 9973 } 9974 } 9975 } 9976 } 9977 9978 if (!app.isolated) { 9979 // XXX Can't keep track of crash times for isolated processes, 9980 // because they don't have a perisistent identity. 9981 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9982 } 9983 9984 return true; 9985 } 9986 9987 void startAppProblemLocked(ProcessRecord app) { 9988 if (app.userId == mCurrentUserId) { 9989 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9990 mContext, app.info.packageName, app.info.flags); 9991 } else { 9992 // If this app is not running under the current user, then we 9993 // can't give it a report button because that would require 9994 // launching the report UI under a different user. 9995 app.errorReportReceiver = null; 9996 } 9997 skipCurrentReceiverLocked(app); 9998 } 9999 10000 void skipCurrentReceiverLocked(ProcessRecord app) { 10001 for (BroadcastQueue queue : mBroadcastQueues) { 10002 queue.skipCurrentReceiverLocked(app); 10003 } 10004 } 10005 10006 /** 10007 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 10008 * The application process will exit immediately after this call returns. 10009 * @param app object of the crashing app, null for the system server 10010 * @param crashInfo describing the exception 10011 */ 10012 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 10013 ProcessRecord r = findAppProcess(app, "Crash"); 10014 final String processName = app == null ? "system_server" 10015 : (r == null ? "unknown" : r.processName); 10016 10017 handleApplicationCrashInner("crash", r, processName, crashInfo); 10018 } 10019 10020 /* Native crash reporting uses this inner version because it needs to be somewhat 10021 * decoupled from the AM-managed cleanup lifecycle 10022 */ 10023 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 10024 ApplicationErrorReport.CrashInfo crashInfo) { 10025 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10026 UserHandle.getUserId(Binder.getCallingUid()), processName, 10027 r == null ? -1 : r.info.flags, 10028 crashInfo.exceptionClassName, 10029 crashInfo.exceptionMessage, 10030 crashInfo.throwFileName, 10031 crashInfo.throwLineNumber); 10032 10033 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10034 10035 crashApplication(r, crashInfo); 10036 } 10037 10038 public void handleApplicationStrictModeViolation( 10039 IBinder app, 10040 int violationMask, 10041 StrictMode.ViolationInfo info) { 10042 ProcessRecord r = findAppProcess(app, "StrictMode"); 10043 if (r == null) { 10044 return; 10045 } 10046 10047 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10048 Integer stackFingerprint = info.hashCode(); 10049 boolean logIt = true; 10050 synchronized (mAlreadyLoggedViolatedStacks) { 10051 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10052 logIt = false; 10053 // TODO: sub-sample into EventLog for these, with 10054 // the info.durationMillis? Then we'd get 10055 // the relative pain numbers, without logging all 10056 // the stack traces repeatedly. We'd want to do 10057 // likewise in the client code, which also does 10058 // dup suppression, before the Binder call. 10059 } else { 10060 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10061 mAlreadyLoggedViolatedStacks.clear(); 10062 } 10063 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10064 } 10065 } 10066 if (logIt) { 10067 logStrictModeViolationToDropBox(r, info); 10068 } 10069 } 10070 10071 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10072 AppErrorResult result = new AppErrorResult(); 10073 synchronized (this) { 10074 final long origId = Binder.clearCallingIdentity(); 10075 10076 Message msg = Message.obtain(); 10077 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10078 HashMap<String, Object> data = new HashMap<String, Object>(); 10079 data.put("result", result); 10080 data.put("app", r); 10081 data.put("violationMask", violationMask); 10082 data.put("info", info); 10083 msg.obj = data; 10084 mHandler.sendMessage(msg); 10085 10086 Binder.restoreCallingIdentity(origId); 10087 } 10088 int res = result.get(); 10089 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10090 } 10091 } 10092 10093 // Depending on the policy in effect, there could be a bunch of 10094 // these in quick succession so we try to batch these together to 10095 // minimize disk writes, number of dropbox entries, and maximize 10096 // compression, by having more fewer, larger records. 10097 private void logStrictModeViolationToDropBox( 10098 ProcessRecord process, 10099 StrictMode.ViolationInfo info) { 10100 if (info == null) { 10101 return; 10102 } 10103 final boolean isSystemApp = process == null || 10104 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10105 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10106 final String processName = process == null ? "unknown" : process.processName; 10107 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10108 final DropBoxManager dbox = (DropBoxManager) 10109 mContext.getSystemService(Context.DROPBOX_SERVICE); 10110 10111 // Exit early if the dropbox isn't configured to accept this report type. 10112 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10113 10114 boolean bufferWasEmpty; 10115 boolean needsFlush; 10116 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10117 synchronized (sb) { 10118 bufferWasEmpty = sb.length() == 0; 10119 appendDropBoxProcessHeaders(process, processName, sb); 10120 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10121 sb.append("System-App: ").append(isSystemApp).append("\n"); 10122 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10123 if (info.violationNumThisLoop != 0) { 10124 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10125 } 10126 if (info.numAnimationsRunning != 0) { 10127 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10128 } 10129 if (info.broadcastIntentAction != null) { 10130 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10131 } 10132 if (info.durationMillis != -1) { 10133 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10134 } 10135 if (info.numInstances != -1) { 10136 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10137 } 10138 if (info.tags != null) { 10139 for (String tag : info.tags) { 10140 sb.append("Span-Tag: ").append(tag).append("\n"); 10141 } 10142 } 10143 sb.append("\n"); 10144 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10145 sb.append(info.crashInfo.stackTrace); 10146 } 10147 sb.append("\n"); 10148 10149 // Only buffer up to ~64k. Various logging bits truncate 10150 // things at 128k. 10151 needsFlush = (sb.length() > 64 * 1024); 10152 } 10153 10154 // Flush immediately if the buffer's grown too large, or this 10155 // is a non-system app. Non-system apps are isolated with a 10156 // different tag & policy and not batched. 10157 // 10158 // Batching is useful during internal testing with 10159 // StrictMode settings turned up high. Without batching, 10160 // thousands of separate files could be created on boot. 10161 if (!isSystemApp || needsFlush) { 10162 new Thread("Error dump: " + dropboxTag) { 10163 @Override 10164 public void run() { 10165 String report; 10166 synchronized (sb) { 10167 report = sb.toString(); 10168 sb.delete(0, sb.length()); 10169 sb.trimToSize(); 10170 } 10171 if (report.length() != 0) { 10172 dbox.addText(dropboxTag, report); 10173 } 10174 } 10175 }.start(); 10176 return; 10177 } 10178 10179 // System app batching: 10180 if (!bufferWasEmpty) { 10181 // An existing dropbox-writing thread is outstanding, so 10182 // we don't need to start it up. The existing thread will 10183 // catch the buffer appends we just did. 10184 return; 10185 } 10186 10187 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10188 // (After this point, we shouldn't access AMS internal data structures.) 10189 new Thread("Error dump: " + dropboxTag) { 10190 @Override 10191 public void run() { 10192 // 5 second sleep to let stacks arrive and be batched together 10193 try { 10194 Thread.sleep(5000); // 5 seconds 10195 } catch (InterruptedException e) {} 10196 10197 String errorReport; 10198 synchronized (mStrictModeBuffer) { 10199 errorReport = mStrictModeBuffer.toString(); 10200 if (errorReport.length() == 0) { 10201 return; 10202 } 10203 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10204 mStrictModeBuffer.trimToSize(); 10205 } 10206 dbox.addText(dropboxTag, errorReport); 10207 } 10208 }.start(); 10209 } 10210 10211 /** 10212 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10213 * @param app object of the crashing app, null for the system server 10214 * @param tag reported by the caller 10215 * @param crashInfo describing the context of the error 10216 * @return true if the process should exit immediately (WTF is fatal) 10217 */ 10218 public boolean handleApplicationWtf(IBinder app, String tag, 10219 ApplicationErrorReport.CrashInfo crashInfo) { 10220 ProcessRecord r = findAppProcess(app, "WTF"); 10221 final String processName = app == null ? "system_server" 10222 : (r == null ? "unknown" : r.processName); 10223 10224 EventLog.writeEvent(EventLogTags.AM_WTF, 10225 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10226 processName, 10227 r == null ? -1 : r.info.flags, 10228 tag, crashInfo.exceptionMessage); 10229 10230 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10231 10232 if (r != null && r.pid != Process.myPid() && 10233 Settings.Global.getInt(mContext.getContentResolver(), 10234 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10235 crashApplication(r, crashInfo); 10236 return true; 10237 } else { 10238 return false; 10239 } 10240 } 10241 10242 /** 10243 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10244 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10245 */ 10246 private ProcessRecord findAppProcess(IBinder app, String reason) { 10247 if (app == null) { 10248 return null; 10249 } 10250 10251 synchronized (this) { 10252 final int NP = mProcessNames.getMap().size(); 10253 for (int ip=0; ip<NP; ip++) { 10254 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10255 final int NA = apps.size(); 10256 for (int ia=0; ia<NA; ia++) { 10257 ProcessRecord p = apps.valueAt(ia); 10258 if (p.thread != null && p.thread.asBinder() == app) { 10259 return p; 10260 } 10261 } 10262 } 10263 10264 Slog.w(TAG, "Can't find mystery application for " + reason 10265 + " from pid=" + Binder.getCallingPid() 10266 + " uid=" + Binder.getCallingUid() + ": " + app); 10267 return null; 10268 } 10269 } 10270 10271 /** 10272 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10273 * to append various headers to the dropbox log text. 10274 */ 10275 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10276 StringBuilder sb) { 10277 // Watchdog thread ends up invoking this function (with 10278 // a null ProcessRecord) to add the stack file to dropbox. 10279 // Do not acquire a lock on this (am) in such cases, as it 10280 // could cause a potential deadlock, if and when watchdog 10281 // is invoked due to unavailability of lock on am and it 10282 // would prevent watchdog from killing system_server. 10283 if (process == null) { 10284 sb.append("Process: ").append(processName).append("\n"); 10285 return; 10286 } 10287 // Note: ProcessRecord 'process' is guarded by the service 10288 // instance. (notably process.pkgList, which could otherwise change 10289 // concurrently during execution of this method) 10290 synchronized (this) { 10291 sb.append("Process: ").append(processName).append("\n"); 10292 int flags = process.info.flags; 10293 IPackageManager pm = AppGlobals.getPackageManager(); 10294 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10295 for (int ip=0; ip<process.pkgList.size(); ip++) { 10296 String pkg = process.pkgList.keyAt(ip); 10297 sb.append("Package: ").append(pkg); 10298 try { 10299 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10300 if (pi != null) { 10301 sb.append(" v").append(pi.versionCode); 10302 if (pi.versionName != null) { 10303 sb.append(" (").append(pi.versionName).append(")"); 10304 } 10305 } 10306 } catch (RemoteException e) { 10307 Slog.e(TAG, "Error getting package info: " + pkg, e); 10308 } 10309 sb.append("\n"); 10310 } 10311 } 10312 } 10313 10314 private static String processClass(ProcessRecord process) { 10315 if (process == null || process.pid == MY_PID) { 10316 return "system_server"; 10317 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10318 return "system_app"; 10319 } else { 10320 return "data_app"; 10321 } 10322 } 10323 10324 /** 10325 * Write a description of an error (crash, WTF, ANR) to the drop box. 10326 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10327 * @param process which caused the error, null means the system server 10328 * @param activity which triggered the error, null if unknown 10329 * @param parent activity related to the error, null if unknown 10330 * @param subject line related to the error, null if absent 10331 * @param report in long form describing the error, null if absent 10332 * @param logFile to include in the report, null if none 10333 * @param crashInfo giving an application stack trace, null if absent 10334 */ 10335 public void addErrorToDropBox(String eventType, 10336 ProcessRecord process, String processName, ActivityRecord activity, 10337 ActivityRecord parent, String subject, 10338 final String report, final File logFile, 10339 final ApplicationErrorReport.CrashInfo crashInfo) { 10340 // NOTE -- this must never acquire the ActivityManagerService lock, 10341 // otherwise the watchdog may be prevented from resetting the system. 10342 10343 final String dropboxTag = processClass(process) + "_" + eventType; 10344 final DropBoxManager dbox = (DropBoxManager) 10345 mContext.getSystemService(Context.DROPBOX_SERVICE); 10346 10347 // Exit early if the dropbox isn't configured to accept this report type. 10348 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10349 10350 final StringBuilder sb = new StringBuilder(1024); 10351 appendDropBoxProcessHeaders(process, processName, sb); 10352 if (activity != null) { 10353 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10354 } 10355 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10356 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10357 } 10358 if (parent != null && parent != activity) { 10359 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10360 } 10361 if (subject != null) { 10362 sb.append("Subject: ").append(subject).append("\n"); 10363 } 10364 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10365 if (Debug.isDebuggerConnected()) { 10366 sb.append("Debugger: Connected\n"); 10367 } 10368 sb.append("\n"); 10369 10370 // Do the rest in a worker thread to avoid blocking the caller on I/O 10371 // (After this point, we shouldn't access AMS internal data structures.) 10372 Thread worker = new Thread("Error dump: " + dropboxTag) { 10373 @Override 10374 public void run() { 10375 if (report != null) { 10376 sb.append(report); 10377 } 10378 if (logFile != null) { 10379 try { 10380 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10381 "\n\n[[TRUNCATED]]")); 10382 } catch (IOException e) { 10383 Slog.e(TAG, "Error reading " + logFile, e); 10384 } 10385 } 10386 if (crashInfo != null && crashInfo.stackTrace != null) { 10387 sb.append(crashInfo.stackTrace); 10388 } 10389 10390 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10391 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10392 if (lines > 0) { 10393 sb.append("\n"); 10394 10395 // Merge several logcat streams, and take the last N lines 10396 InputStreamReader input = null; 10397 try { 10398 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10399 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10400 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10401 10402 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10403 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10404 input = new InputStreamReader(logcat.getInputStream()); 10405 10406 int num; 10407 char[] buf = new char[8192]; 10408 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10409 } catch (IOException e) { 10410 Slog.e(TAG, "Error running logcat", e); 10411 } finally { 10412 if (input != null) try { input.close(); } catch (IOException e) {} 10413 } 10414 } 10415 10416 dbox.addText(dropboxTag, sb.toString()); 10417 } 10418 }; 10419 10420 if (process == null) { 10421 // If process is null, we are being called from some internal code 10422 // and may be about to die -- run this synchronously. 10423 worker.run(); 10424 } else { 10425 worker.start(); 10426 } 10427 } 10428 10429 /** 10430 * Bring up the "unexpected error" dialog box for a crashing app. 10431 * Deal with edge cases (intercepts from instrumented applications, 10432 * ActivityController, error intent receivers, that sort of thing). 10433 * @param r the application crashing 10434 * @param crashInfo describing the failure 10435 */ 10436 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10437 long timeMillis = System.currentTimeMillis(); 10438 String shortMsg = crashInfo.exceptionClassName; 10439 String longMsg = crashInfo.exceptionMessage; 10440 String stackTrace = crashInfo.stackTrace; 10441 if (shortMsg != null && longMsg != null) { 10442 longMsg = shortMsg + ": " + longMsg; 10443 } else if (shortMsg != null) { 10444 longMsg = shortMsg; 10445 } 10446 10447 AppErrorResult result = new AppErrorResult(); 10448 synchronized (this) { 10449 if (mController != null) { 10450 try { 10451 String name = r != null ? r.processName : null; 10452 int pid = r != null ? r.pid : Binder.getCallingPid(); 10453 if (!mController.appCrashed(name, pid, 10454 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10455 Slog.w(TAG, "Force-killing crashed app " + name 10456 + " at watcher's request"); 10457 Process.killProcess(pid); 10458 return; 10459 } 10460 } catch (RemoteException e) { 10461 mController = null; 10462 Watchdog.getInstance().setActivityController(null); 10463 } 10464 } 10465 10466 final long origId = Binder.clearCallingIdentity(); 10467 10468 // If this process is running instrumentation, finish it. 10469 if (r != null && r.instrumentationClass != null) { 10470 Slog.w(TAG, "Error in app " + r.processName 10471 + " running instrumentation " + r.instrumentationClass + ":"); 10472 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10473 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10474 Bundle info = new Bundle(); 10475 info.putString("shortMsg", shortMsg); 10476 info.putString("longMsg", longMsg); 10477 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10478 Binder.restoreCallingIdentity(origId); 10479 return; 10480 } 10481 10482 // If we can't identify the process or it's already exceeded its crash quota, 10483 // quit right away without showing a crash dialog. 10484 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10485 Binder.restoreCallingIdentity(origId); 10486 return; 10487 } 10488 10489 Message msg = Message.obtain(); 10490 msg.what = SHOW_ERROR_MSG; 10491 HashMap data = new HashMap(); 10492 data.put("result", result); 10493 data.put("app", r); 10494 msg.obj = data; 10495 mHandler.sendMessage(msg); 10496 10497 Binder.restoreCallingIdentity(origId); 10498 } 10499 10500 int res = result.get(); 10501 10502 Intent appErrorIntent = null; 10503 synchronized (this) { 10504 if (r != null && !r.isolated) { 10505 // XXX Can't keep track of crash time for isolated processes, 10506 // since they don't have a persistent identity. 10507 mProcessCrashTimes.put(r.info.processName, r.uid, 10508 SystemClock.uptimeMillis()); 10509 } 10510 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10511 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10512 } 10513 } 10514 10515 if (appErrorIntent != null) { 10516 try { 10517 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10518 } catch (ActivityNotFoundException e) { 10519 Slog.w(TAG, "bug report receiver dissappeared", e); 10520 } 10521 } 10522 } 10523 10524 Intent createAppErrorIntentLocked(ProcessRecord r, 10525 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10526 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10527 if (report == null) { 10528 return null; 10529 } 10530 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10531 result.setComponent(r.errorReportReceiver); 10532 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10533 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10534 return result; 10535 } 10536 10537 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10538 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10539 if (r.errorReportReceiver == null) { 10540 return null; 10541 } 10542 10543 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10544 return null; 10545 } 10546 10547 ApplicationErrorReport report = new ApplicationErrorReport(); 10548 report.packageName = r.info.packageName; 10549 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10550 report.processName = r.processName; 10551 report.time = timeMillis; 10552 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10553 10554 if (r.crashing || r.forceCrashReport) { 10555 report.type = ApplicationErrorReport.TYPE_CRASH; 10556 report.crashInfo = crashInfo; 10557 } else if (r.notResponding) { 10558 report.type = ApplicationErrorReport.TYPE_ANR; 10559 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10560 10561 report.anrInfo.activity = r.notRespondingReport.tag; 10562 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10563 report.anrInfo.info = r.notRespondingReport.longMsg; 10564 } 10565 10566 return report; 10567 } 10568 10569 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10570 enforceNotIsolatedCaller("getProcessesInErrorState"); 10571 // assume our apps are happy - lazy create the list 10572 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10573 10574 final boolean allUsers = ActivityManager.checkUidPermission( 10575 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10576 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10577 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10578 10579 synchronized (this) { 10580 10581 // iterate across all processes 10582 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10583 ProcessRecord app = mLruProcesses.get(i); 10584 if (!allUsers && app.userId != userId) { 10585 continue; 10586 } 10587 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10588 // This one's in trouble, so we'll generate a report for it 10589 // crashes are higher priority (in case there's a crash *and* an anr) 10590 ActivityManager.ProcessErrorStateInfo report = null; 10591 if (app.crashing) { 10592 report = app.crashingReport; 10593 } else if (app.notResponding) { 10594 report = app.notRespondingReport; 10595 } 10596 10597 if (report != null) { 10598 if (errList == null) { 10599 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10600 } 10601 errList.add(report); 10602 } else { 10603 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10604 " crashing = " + app.crashing + 10605 " notResponding = " + app.notResponding); 10606 } 10607 } 10608 } 10609 } 10610 10611 return errList; 10612 } 10613 10614 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10615 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10616 if (currApp != null) { 10617 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10618 } 10619 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10620 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10621 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10622 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10623 if (currApp != null) { 10624 currApp.lru = 0; 10625 } 10626 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10627 } else if (adj >= ProcessList.SERVICE_ADJ) { 10628 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10629 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10630 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10631 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10632 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10633 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10634 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10635 } else { 10636 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10637 } 10638 } 10639 10640 private void fillInProcMemInfo(ProcessRecord app, 10641 ActivityManager.RunningAppProcessInfo outInfo) { 10642 outInfo.pid = app.pid; 10643 outInfo.uid = app.info.uid; 10644 if (mHeavyWeightProcess == app) { 10645 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10646 } 10647 if (app.persistent) { 10648 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10649 } 10650 if (app.activities.size() > 0) { 10651 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10652 } 10653 outInfo.lastTrimLevel = app.trimMemoryLevel; 10654 int adj = app.curAdj; 10655 outInfo.importance = oomAdjToImportance(adj, outInfo); 10656 outInfo.importanceReasonCode = app.adjTypeCode; 10657 outInfo.processState = app.curProcState; 10658 } 10659 10660 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10661 enforceNotIsolatedCaller("getRunningAppProcesses"); 10662 // Lazy instantiation of list 10663 List<ActivityManager.RunningAppProcessInfo> runList = null; 10664 final boolean allUsers = ActivityManager.checkUidPermission( 10665 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10666 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10667 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10668 synchronized (this) { 10669 // Iterate across all processes 10670 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10671 ProcessRecord app = mLruProcesses.get(i); 10672 if (!allUsers && app.userId != userId) { 10673 continue; 10674 } 10675 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10676 // Generate process state info for running application 10677 ActivityManager.RunningAppProcessInfo currApp = 10678 new ActivityManager.RunningAppProcessInfo(app.processName, 10679 app.pid, app.getPackageList()); 10680 fillInProcMemInfo(app, currApp); 10681 if (app.adjSource instanceof ProcessRecord) { 10682 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10683 currApp.importanceReasonImportance = oomAdjToImportance( 10684 app.adjSourceOom, null); 10685 } else if (app.adjSource instanceof ActivityRecord) { 10686 ActivityRecord r = (ActivityRecord)app.adjSource; 10687 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10688 } 10689 if (app.adjTarget instanceof ComponentName) { 10690 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10691 } 10692 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10693 // + " lru=" + currApp.lru); 10694 if (runList == null) { 10695 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10696 } 10697 runList.add(currApp); 10698 } 10699 } 10700 } 10701 return runList; 10702 } 10703 10704 public List<ApplicationInfo> getRunningExternalApplications() { 10705 enforceNotIsolatedCaller("getRunningExternalApplications"); 10706 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10707 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10708 if (runningApps != null && runningApps.size() > 0) { 10709 Set<String> extList = new HashSet<String>(); 10710 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10711 if (app.pkgList != null) { 10712 for (String pkg : app.pkgList) { 10713 extList.add(pkg); 10714 } 10715 } 10716 } 10717 IPackageManager pm = AppGlobals.getPackageManager(); 10718 for (String pkg : extList) { 10719 try { 10720 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10721 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10722 retList.add(info); 10723 } 10724 } catch (RemoteException e) { 10725 } 10726 } 10727 } 10728 return retList; 10729 } 10730 10731 @Override 10732 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10733 enforceNotIsolatedCaller("getMyMemoryState"); 10734 synchronized (this) { 10735 ProcessRecord proc; 10736 synchronized (mPidsSelfLocked) { 10737 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10738 } 10739 fillInProcMemInfo(proc, outInfo); 10740 } 10741 } 10742 10743 @Override 10744 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10745 if (checkCallingPermission(android.Manifest.permission.DUMP) 10746 != PackageManager.PERMISSION_GRANTED) { 10747 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10748 + Binder.getCallingPid() 10749 + ", uid=" + Binder.getCallingUid() 10750 + " without permission " 10751 + android.Manifest.permission.DUMP); 10752 return; 10753 } 10754 10755 boolean dumpAll = false; 10756 boolean dumpClient = false; 10757 String dumpPackage = null; 10758 10759 int opti = 0; 10760 while (opti < args.length) { 10761 String opt = args[opti]; 10762 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10763 break; 10764 } 10765 opti++; 10766 if ("-a".equals(opt)) { 10767 dumpAll = true; 10768 } else if ("-c".equals(opt)) { 10769 dumpClient = true; 10770 } else if ("-h".equals(opt)) { 10771 pw.println("Activity manager dump options:"); 10772 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10773 pw.println(" cmd may be one of:"); 10774 pw.println(" a[ctivities]: activity stack state"); 10775 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10776 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10777 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10778 pw.println(" o[om]: out of memory management"); 10779 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10780 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10781 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10782 pw.println(" service [COMP_SPEC]: service client-side state"); 10783 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10784 pw.println(" all: dump all activities"); 10785 pw.println(" top: dump the top activity"); 10786 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10787 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10788 pw.println(" a partial substring in a component name, a"); 10789 pw.println(" hex object identifier."); 10790 pw.println(" -a: include all available server state."); 10791 pw.println(" -c: include client state."); 10792 return; 10793 } else { 10794 pw.println("Unknown argument: " + opt + "; use -h for help"); 10795 } 10796 } 10797 10798 long origId = Binder.clearCallingIdentity(); 10799 boolean more = false; 10800 // Is the caller requesting to dump a particular piece of data? 10801 if (opti < args.length) { 10802 String cmd = args[opti]; 10803 opti++; 10804 if ("activities".equals(cmd) || "a".equals(cmd)) { 10805 synchronized (this) { 10806 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10807 } 10808 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10809 String[] newArgs; 10810 String name; 10811 if (opti >= args.length) { 10812 name = null; 10813 newArgs = EMPTY_STRING_ARRAY; 10814 } else { 10815 name = args[opti]; 10816 opti++; 10817 newArgs = new String[args.length - opti]; 10818 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10819 args.length - opti); 10820 } 10821 synchronized (this) { 10822 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10823 } 10824 } else if ("intents".equals(cmd) || "i".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 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10839 } 10840 } else if ("processes".equals(cmd) || "p".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 dumpProcessesLocked(fd, pw, args, opti, true, name); 10855 } 10856 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10857 synchronized (this) { 10858 dumpOomLocked(fd, pw, args, opti, true); 10859 } 10860 } else if ("provider".equals(cmd)) { 10861 String[] newArgs; 10862 String name; 10863 if (opti >= args.length) { 10864 name = null; 10865 newArgs = EMPTY_STRING_ARRAY; 10866 } else { 10867 name = args[opti]; 10868 opti++; 10869 newArgs = new String[args.length - opti]; 10870 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10871 } 10872 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10873 pw.println("No providers match: " + name); 10874 pw.println("Use -h for help."); 10875 } 10876 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10877 synchronized (this) { 10878 dumpProvidersLocked(fd, pw, args, opti, true, null); 10879 } 10880 } else if ("service".equals(cmd)) { 10881 String[] newArgs; 10882 String name; 10883 if (opti >= args.length) { 10884 name = null; 10885 newArgs = EMPTY_STRING_ARRAY; 10886 } else { 10887 name = args[opti]; 10888 opti++; 10889 newArgs = new String[args.length - opti]; 10890 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10891 args.length - opti); 10892 } 10893 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10894 pw.println("No services match: " + name); 10895 pw.println("Use -h for help."); 10896 } 10897 } else if ("package".equals(cmd)) { 10898 String[] newArgs; 10899 if (opti >= args.length) { 10900 pw.println("package: no package name specified"); 10901 pw.println("Use -h for help."); 10902 } else { 10903 dumpPackage = 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 args = newArgs; 10909 opti = 0; 10910 more = true; 10911 } 10912 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10913 synchronized (this) { 10914 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10915 } 10916 } else { 10917 // Dumping a single activity? 10918 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10919 pw.println("Bad activity command, or no activities match: " + cmd); 10920 pw.println("Use -h for help."); 10921 } 10922 } 10923 if (!more) { 10924 Binder.restoreCallingIdentity(origId); 10925 return; 10926 } 10927 } 10928 10929 // No piece of data specified, dump everything. 10930 synchronized (this) { 10931 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10932 pw.println(); 10933 if (dumpAll) { 10934 pw.println("-------------------------------------------------------------------------------"); 10935 } 10936 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10937 pw.println(); 10938 if (dumpAll) { 10939 pw.println("-------------------------------------------------------------------------------"); 10940 } 10941 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10942 pw.println(); 10943 if (dumpAll) { 10944 pw.println("-------------------------------------------------------------------------------"); 10945 } 10946 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10947 pw.println(); 10948 if (dumpAll) { 10949 pw.println("-------------------------------------------------------------------------------"); 10950 } 10951 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10952 pw.println(); 10953 if (dumpAll) { 10954 pw.println("-------------------------------------------------------------------------------"); 10955 } 10956 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10957 } 10958 Binder.restoreCallingIdentity(origId); 10959 } 10960 10961 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10962 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10963 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10964 10965 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10966 dumpPackage); 10967 boolean needSep = printedAnything; 10968 10969 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10970 dumpPackage, needSep, " mFocusedActivity: "); 10971 if (printed) { 10972 printedAnything = true; 10973 needSep = false; 10974 } 10975 10976 if (dumpPackage == null) { 10977 if (needSep) { 10978 pw.println(); 10979 } 10980 needSep = true; 10981 printedAnything = true; 10982 mStackSupervisor.dump(pw, " "); 10983 } 10984 10985 if (mRecentTasks.size() > 0) { 10986 boolean printedHeader = false; 10987 10988 final int N = mRecentTasks.size(); 10989 for (int i=0; i<N; i++) { 10990 TaskRecord tr = mRecentTasks.get(i); 10991 if (dumpPackage != null) { 10992 if (tr.realActivity == null || 10993 !dumpPackage.equals(tr.realActivity)) { 10994 continue; 10995 } 10996 } 10997 if (!printedHeader) { 10998 if (needSep) { 10999 pw.println(); 11000 } 11001 pw.println(" Recent tasks:"); 11002 printedHeader = true; 11003 printedAnything = true; 11004 } 11005 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 11006 pw.println(tr); 11007 if (dumpAll) { 11008 mRecentTasks.get(i).dump(pw, " "); 11009 } 11010 } 11011 } 11012 11013 if (!printedAnything) { 11014 pw.println(" (nothing)"); 11015 } 11016 } 11017 11018 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11019 int opti, boolean dumpAll, String dumpPackage) { 11020 boolean needSep = false; 11021 boolean printedAnything = false; 11022 int numPers = 0; 11023 11024 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11025 11026 if (dumpAll) { 11027 final int NP = mProcessNames.getMap().size(); 11028 for (int ip=0; ip<NP; ip++) { 11029 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11030 final int NA = procs.size(); 11031 for (int ia=0; ia<NA; ia++) { 11032 ProcessRecord r = procs.valueAt(ia); 11033 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11034 continue; 11035 } 11036 if (!needSep) { 11037 pw.println(" All known processes:"); 11038 needSep = true; 11039 printedAnything = true; 11040 } 11041 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11042 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11043 pw.print(" "); pw.println(r); 11044 r.dump(pw, " "); 11045 if (r.persistent) { 11046 numPers++; 11047 } 11048 } 11049 } 11050 } 11051 11052 if (mIsolatedProcesses.size() > 0) { 11053 boolean printed = false; 11054 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11055 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11056 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11057 continue; 11058 } 11059 if (!printed) { 11060 if (needSep) { 11061 pw.println(); 11062 } 11063 pw.println(" Isolated process list (sorted by uid):"); 11064 printedAnything = true; 11065 printed = true; 11066 needSep = true; 11067 } 11068 pw.println(String.format("%sIsolated #%2d: %s", 11069 " ", i, r.toString())); 11070 } 11071 } 11072 11073 if (mLruProcesses.size() > 0) { 11074 if (needSep) { 11075 pw.println(); 11076 } 11077 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11078 pw.print(" total, non-act at "); 11079 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11080 pw.print(", non-svc at "); 11081 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11082 pw.println("):"); 11083 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11084 needSep = true; 11085 printedAnything = true; 11086 } 11087 11088 if (dumpAll || dumpPackage != null) { 11089 synchronized (mPidsSelfLocked) { 11090 boolean printed = false; 11091 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11092 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11093 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11094 continue; 11095 } 11096 if (!printed) { 11097 if (needSep) pw.println(); 11098 needSep = true; 11099 pw.println(" PID mappings:"); 11100 printed = true; 11101 printedAnything = true; 11102 } 11103 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11104 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11105 } 11106 } 11107 } 11108 11109 if (mForegroundProcesses.size() > 0) { 11110 synchronized (mPidsSelfLocked) { 11111 boolean printed = false; 11112 for (int i=0; i<mForegroundProcesses.size(); i++) { 11113 ProcessRecord r = mPidsSelfLocked.get( 11114 mForegroundProcesses.valueAt(i).pid); 11115 if (dumpPackage != null && (r == null 11116 || !r.pkgList.containsKey(dumpPackage))) { 11117 continue; 11118 } 11119 if (!printed) { 11120 if (needSep) pw.println(); 11121 needSep = true; 11122 pw.println(" Foreground Processes:"); 11123 printed = true; 11124 printedAnything = true; 11125 } 11126 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11127 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11128 } 11129 } 11130 } 11131 11132 if (mPersistentStartingProcesses.size() > 0) { 11133 if (needSep) pw.println(); 11134 needSep = true; 11135 printedAnything = true; 11136 pw.println(" Persisent processes that are starting:"); 11137 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11138 "Starting Norm", "Restarting PERS", dumpPackage); 11139 } 11140 11141 if (mRemovedProcesses.size() > 0) { 11142 if (needSep) pw.println(); 11143 needSep = true; 11144 printedAnything = true; 11145 pw.println(" Processes that are being removed:"); 11146 dumpProcessList(pw, this, mRemovedProcesses, " ", 11147 "Removed Norm", "Removed PERS", dumpPackage); 11148 } 11149 11150 if (mProcessesOnHold.size() > 0) { 11151 if (needSep) pw.println(); 11152 needSep = true; 11153 printedAnything = true; 11154 pw.println(" Processes that are on old until the system is ready:"); 11155 dumpProcessList(pw, this, mProcessesOnHold, " ", 11156 "OnHold Norm", "OnHold PERS", dumpPackage); 11157 } 11158 11159 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11160 11161 if (mProcessCrashTimes.getMap().size() > 0) { 11162 boolean printed = false; 11163 long now = SystemClock.uptimeMillis(); 11164 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11165 final int NP = pmap.size(); 11166 for (int ip=0; ip<NP; ip++) { 11167 String pname = pmap.keyAt(ip); 11168 SparseArray<Long> uids = pmap.valueAt(ip); 11169 final int N = uids.size(); 11170 for (int i=0; i<N; i++) { 11171 int puid = uids.keyAt(i); 11172 ProcessRecord r = mProcessNames.get(pname, puid); 11173 if (dumpPackage != null && (r == null 11174 || !r.pkgList.containsKey(dumpPackage))) { 11175 continue; 11176 } 11177 if (!printed) { 11178 if (needSep) pw.println(); 11179 needSep = true; 11180 pw.println(" Time since processes crashed:"); 11181 printed = true; 11182 printedAnything = true; 11183 } 11184 pw.print(" Process "); pw.print(pname); 11185 pw.print(" uid "); pw.print(puid); 11186 pw.print(": last crashed "); 11187 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11188 pw.println(" ago"); 11189 } 11190 } 11191 } 11192 11193 if (mBadProcesses.getMap().size() > 0) { 11194 boolean printed = false; 11195 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11196 final int NP = pmap.size(); 11197 for (int ip=0; ip<NP; ip++) { 11198 String pname = pmap.keyAt(ip); 11199 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11200 final int N = uids.size(); 11201 for (int i=0; i<N; i++) { 11202 int puid = uids.keyAt(i); 11203 ProcessRecord r = mProcessNames.get(pname, puid); 11204 if (dumpPackage != null && (r == null 11205 || !r.pkgList.containsKey(dumpPackage))) { 11206 continue; 11207 } 11208 if (!printed) { 11209 if (needSep) pw.println(); 11210 needSep = true; 11211 pw.println(" Bad processes:"); 11212 printedAnything = true; 11213 } 11214 BadProcessInfo info = uids.valueAt(i); 11215 pw.print(" Bad process "); pw.print(pname); 11216 pw.print(" uid "); pw.print(puid); 11217 pw.print(": crashed at time "); pw.println(info.time); 11218 if (info.shortMsg != null) { 11219 pw.print(" Short msg: "); pw.println(info.shortMsg); 11220 } 11221 if (info.longMsg != null) { 11222 pw.print(" Long msg: "); pw.println(info.longMsg); 11223 } 11224 if (info.stack != null) { 11225 pw.println(" Stack:"); 11226 int lastPos = 0; 11227 for (int pos=0; pos<info.stack.length(); pos++) { 11228 if (info.stack.charAt(pos) == '\n') { 11229 pw.print(" "); 11230 pw.write(info.stack, lastPos, pos-lastPos); 11231 pw.println(); 11232 lastPos = pos+1; 11233 } 11234 } 11235 if (lastPos < info.stack.length()) { 11236 pw.print(" "); 11237 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11238 pw.println(); 11239 } 11240 } 11241 } 11242 } 11243 } 11244 11245 if (dumpPackage == null) { 11246 pw.println(); 11247 needSep = false; 11248 pw.println(" mStartedUsers:"); 11249 for (int i=0; i<mStartedUsers.size(); i++) { 11250 UserStartedState uss = mStartedUsers.valueAt(i); 11251 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11252 pw.print(": "); uss.dump("", pw); 11253 } 11254 pw.print(" mStartedUserArray: ["); 11255 for (int i=0; i<mStartedUserArray.length; i++) { 11256 if (i > 0) pw.print(", "); 11257 pw.print(mStartedUserArray[i]); 11258 } 11259 pw.println("]"); 11260 pw.print(" mUserLru: ["); 11261 for (int i=0; i<mUserLru.size(); i++) { 11262 if (i > 0) pw.print(", "); 11263 pw.print(mUserLru.get(i)); 11264 } 11265 pw.println("]"); 11266 if (dumpAll) { 11267 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11268 } 11269 } 11270 if (mHomeProcess != null && (dumpPackage == null 11271 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11272 if (needSep) { 11273 pw.println(); 11274 needSep = false; 11275 } 11276 pw.println(" mHomeProcess: " + mHomeProcess); 11277 } 11278 if (mPreviousProcess != null && (dumpPackage == null 11279 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11280 if (needSep) { 11281 pw.println(); 11282 needSep = false; 11283 } 11284 pw.println(" mPreviousProcess: " + mPreviousProcess); 11285 } 11286 if (dumpAll) { 11287 StringBuilder sb = new StringBuilder(128); 11288 sb.append(" mPreviousProcessVisibleTime: "); 11289 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11290 pw.println(sb); 11291 } 11292 if (mHeavyWeightProcess != null && (dumpPackage == null 11293 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11294 if (needSep) { 11295 pw.println(); 11296 needSep = false; 11297 } 11298 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11299 } 11300 if (dumpPackage == null) { 11301 pw.println(" mConfiguration: " + mConfiguration); 11302 } 11303 if (dumpAll) { 11304 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11305 if (mCompatModePackages.getPackages().size() > 0) { 11306 boolean printed = false; 11307 for (Map.Entry<String, Integer> entry 11308 : mCompatModePackages.getPackages().entrySet()) { 11309 String pkg = entry.getKey(); 11310 int mode = entry.getValue(); 11311 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11312 continue; 11313 } 11314 if (!printed) { 11315 pw.println(" mScreenCompatPackages:"); 11316 printed = true; 11317 } 11318 pw.print(" "); pw.print(pkg); pw.print(": "); 11319 pw.print(mode); pw.println(); 11320 } 11321 } 11322 } 11323 if (dumpPackage == null) { 11324 if (mSleeping || mWentToSleep || mLockScreenShown) { 11325 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11326 + " mLockScreenShown " + mLockScreenShown); 11327 } 11328 if (mShuttingDown || mRunningVoice) { 11329 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11330 } 11331 } 11332 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11333 || mOrigWaitForDebugger) { 11334 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11335 || dumpPackage.equals(mOrigDebugApp)) { 11336 if (needSep) { 11337 pw.println(); 11338 needSep = false; 11339 } 11340 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11341 + " mDebugTransient=" + mDebugTransient 11342 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11343 } 11344 } 11345 if (mOpenGlTraceApp != null) { 11346 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11347 if (needSep) { 11348 pw.println(); 11349 needSep = false; 11350 } 11351 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11352 } 11353 } 11354 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11355 || mProfileFd != null) { 11356 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11357 if (needSep) { 11358 pw.println(); 11359 needSep = false; 11360 } 11361 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11362 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11363 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11364 + mAutoStopProfiler); 11365 } 11366 } 11367 if (dumpPackage == null) { 11368 if (mAlwaysFinishActivities || mController != null) { 11369 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11370 + " mController=" + mController); 11371 } 11372 if (dumpAll) { 11373 pw.println(" Total persistent processes: " + numPers); 11374 pw.println(" mProcessesReady=" + mProcessesReady 11375 + " mSystemReady=" + mSystemReady); 11376 pw.println(" mBooting=" + mBooting 11377 + " mBooted=" + mBooted 11378 + " mFactoryTest=" + mFactoryTest); 11379 pw.print(" mLastPowerCheckRealtime="); 11380 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11381 pw.println(""); 11382 pw.print(" mLastPowerCheckUptime="); 11383 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11384 pw.println(""); 11385 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11386 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11387 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11388 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11389 + " (" + mLruProcesses.size() + " total)" 11390 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11391 + " mNumServiceProcs=" + mNumServiceProcs 11392 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11393 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11394 + " mLastMemoryLevel" + mLastMemoryLevel 11395 + " mLastNumProcesses" + mLastNumProcesses); 11396 long now = SystemClock.uptimeMillis(); 11397 pw.print(" mLastIdleTime="); 11398 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11399 pw.print(" mLowRamSinceLastIdle="); 11400 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11401 pw.println(); 11402 } 11403 } 11404 11405 if (!printedAnything) { 11406 pw.println(" (nothing)"); 11407 } 11408 } 11409 11410 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11411 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11412 if (mProcessesToGc.size() > 0) { 11413 boolean printed = false; 11414 long now = SystemClock.uptimeMillis(); 11415 for (int i=0; i<mProcessesToGc.size(); i++) { 11416 ProcessRecord proc = mProcessesToGc.get(i); 11417 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11418 continue; 11419 } 11420 if (!printed) { 11421 if (needSep) pw.println(); 11422 needSep = true; 11423 pw.println(" Processes that are waiting to GC:"); 11424 printed = true; 11425 } 11426 pw.print(" Process "); pw.println(proc); 11427 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11428 pw.print(", last gced="); 11429 pw.print(now-proc.lastRequestedGc); 11430 pw.print(" ms ago, last lowMem="); 11431 pw.print(now-proc.lastLowMemory); 11432 pw.println(" ms ago"); 11433 11434 } 11435 } 11436 return needSep; 11437 } 11438 11439 void printOomLevel(PrintWriter pw, String name, int adj) { 11440 pw.print(" "); 11441 if (adj >= 0) { 11442 pw.print(' '); 11443 if (adj < 10) pw.print(' '); 11444 } else { 11445 if (adj > -10) pw.print(' '); 11446 } 11447 pw.print(adj); 11448 pw.print(": "); 11449 pw.print(name); 11450 pw.print(" ("); 11451 pw.print(mProcessList.getMemLevel(adj)/1024); 11452 pw.println(" kB)"); 11453 } 11454 11455 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11456 int opti, boolean dumpAll) { 11457 boolean needSep = false; 11458 11459 if (mLruProcesses.size() > 0) { 11460 if (needSep) pw.println(); 11461 needSep = true; 11462 pw.println(" OOM levels:"); 11463 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11464 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11465 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11466 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11467 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11468 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11469 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11470 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11471 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11472 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11473 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11474 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11475 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11476 11477 if (needSep) pw.println(); 11478 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11479 pw.print(" total, non-act at "); 11480 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11481 pw.print(", non-svc at "); 11482 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11483 pw.println("):"); 11484 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11485 needSep = true; 11486 } 11487 11488 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11489 11490 pw.println(); 11491 pw.println(" mHomeProcess: " + mHomeProcess); 11492 pw.println(" mPreviousProcess: " + mPreviousProcess); 11493 if (mHeavyWeightProcess != null) { 11494 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11495 } 11496 11497 return true; 11498 } 11499 11500 /** 11501 * There are three ways to call this: 11502 * - no provider specified: dump all the providers 11503 * - a flattened component name that matched an existing provider was specified as the 11504 * first arg: dump that one provider 11505 * - the first arg isn't the flattened component name of an existing provider: 11506 * dump all providers whose component contains the first arg as a substring 11507 */ 11508 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11509 int opti, boolean dumpAll) { 11510 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11511 } 11512 11513 static class ItemMatcher { 11514 ArrayList<ComponentName> components; 11515 ArrayList<String> strings; 11516 ArrayList<Integer> objects; 11517 boolean all; 11518 11519 ItemMatcher() { 11520 all = true; 11521 } 11522 11523 void build(String name) { 11524 ComponentName componentName = ComponentName.unflattenFromString(name); 11525 if (componentName != null) { 11526 if (components == null) { 11527 components = new ArrayList<ComponentName>(); 11528 } 11529 components.add(componentName); 11530 all = false; 11531 } else { 11532 int objectId = 0; 11533 // Not a '/' separated full component name; maybe an object ID? 11534 try { 11535 objectId = Integer.parseInt(name, 16); 11536 if (objects == null) { 11537 objects = new ArrayList<Integer>(); 11538 } 11539 objects.add(objectId); 11540 all = false; 11541 } catch (RuntimeException e) { 11542 // Not an integer; just do string match. 11543 if (strings == null) { 11544 strings = new ArrayList<String>(); 11545 } 11546 strings.add(name); 11547 all = false; 11548 } 11549 } 11550 } 11551 11552 int build(String[] args, int opti) { 11553 for (; opti<args.length; opti++) { 11554 String name = args[opti]; 11555 if ("--".equals(name)) { 11556 return opti+1; 11557 } 11558 build(name); 11559 } 11560 return opti; 11561 } 11562 11563 boolean match(Object object, ComponentName comp) { 11564 if (all) { 11565 return true; 11566 } 11567 if (components != null) { 11568 for (int i=0; i<components.size(); i++) { 11569 if (components.get(i).equals(comp)) { 11570 return true; 11571 } 11572 } 11573 } 11574 if (objects != null) { 11575 for (int i=0; i<objects.size(); i++) { 11576 if (System.identityHashCode(object) == objects.get(i)) { 11577 return true; 11578 } 11579 } 11580 } 11581 if (strings != null) { 11582 String flat = comp.flattenToString(); 11583 for (int i=0; i<strings.size(); i++) { 11584 if (flat.contains(strings.get(i))) { 11585 return true; 11586 } 11587 } 11588 } 11589 return false; 11590 } 11591 } 11592 11593 /** 11594 * There are three things that cmd can be: 11595 * - a flattened component name that matches an existing activity 11596 * - the cmd arg isn't the flattened component name of an existing activity: 11597 * dump all activity whose component contains the cmd as a substring 11598 * - A hex number of the ActivityRecord object instance. 11599 */ 11600 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11601 int opti, boolean dumpAll) { 11602 ArrayList<ActivityRecord> activities; 11603 11604 synchronized (this) { 11605 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11606 } 11607 11608 if (activities.size() <= 0) { 11609 return false; 11610 } 11611 11612 String[] newArgs = new String[args.length - opti]; 11613 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11614 11615 TaskRecord lastTask = null; 11616 boolean needSep = false; 11617 for (int i=activities.size()-1; i>=0; i--) { 11618 ActivityRecord r = activities.get(i); 11619 if (needSep) { 11620 pw.println(); 11621 } 11622 needSep = true; 11623 synchronized (this) { 11624 if (lastTask != r.task) { 11625 lastTask = r.task; 11626 pw.print("TASK "); pw.print(lastTask.affinity); 11627 pw.print(" id="); pw.println(lastTask.taskId); 11628 if (dumpAll) { 11629 lastTask.dump(pw, " "); 11630 } 11631 } 11632 } 11633 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11634 } 11635 return true; 11636 } 11637 11638 /** 11639 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11640 * there is a thread associated with the activity. 11641 */ 11642 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11643 final ActivityRecord r, String[] args, boolean dumpAll) { 11644 String innerPrefix = prefix + " "; 11645 synchronized (this) { 11646 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11647 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11648 pw.print(" pid="); 11649 if (r.app != null) pw.println(r.app.pid); 11650 else pw.println("(not running)"); 11651 if (dumpAll) { 11652 r.dump(pw, innerPrefix); 11653 } 11654 } 11655 if (r.app != null && r.app.thread != null) { 11656 // flush anything that is already in the PrintWriter since the thread is going 11657 // to write to the file descriptor directly 11658 pw.flush(); 11659 try { 11660 TransferPipe tp = new TransferPipe(); 11661 try { 11662 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11663 r.appToken, innerPrefix, args); 11664 tp.go(fd); 11665 } finally { 11666 tp.kill(); 11667 } 11668 } catch (IOException e) { 11669 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11670 } catch (RemoteException e) { 11671 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11672 } 11673 } 11674 } 11675 11676 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11677 int opti, boolean dumpAll, String dumpPackage) { 11678 boolean needSep = false; 11679 boolean onlyHistory = false; 11680 boolean printedAnything = false; 11681 11682 if ("history".equals(dumpPackage)) { 11683 if (opti < args.length && "-s".equals(args[opti])) { 11684 dumpAll = false; 11685 } 11686 onlyHistory = true; 11687 dumpPackage = null; 11688 } 11689 11690 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11691 if (!onlyHistory && dumpAll) { 11692 if (mRegisteredReceivers.size() > 0) { 11693 boolean printed = false; 11694 Iterator it = mRegisteredReceivers.values().iterator(); 11695 while (it.hasNext()) { 11696 ReceiverList r = (ReceiverList)it.next(); 11697 if (dumpPackage != null && (r.app == null || 11698 !dumpPackage.equals(r.app.info.packageName))) { 11699 continue; 11700 } 11701 if (!printed) { 11702 pw.println(" Registered Receivers:"); 11703 needSep = true; 11704 printed = true; 11705 printedAnything = true; 11706 } 11707 pw.print(" * "); pw.println(r); 11708 r.dump(pw, " "); 11709 } 11710 } 11711 11712 if (mReceiverResolver.dump(pw, needSep ? 11713 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11714 " ", dumpPackage, false)) { 11715 needSep = true; 11716 printedAnything = true; 11717 } 11718 } 11719 11720 for (BroadcastQueue q : mBroadcastQueues) { 11721 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11722 printedAnything |= needSep; 11723 } 11724 11725 needSep = true; 11726 11727 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11728 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11729 if (needSep) { 11730 pw.println(); 11731 } 11732 needSep = true; 11733 printedAnything = true; 11734 pw.print(" Sticky broadcasts for user "); 11735 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11736 StringBuilder sb = new StringBuilder(128); 11737 for (Map.Entry<String, ArrayList<Intent>> ent 11738 : mStickyBroadcasts.valueAt(user).entrySet()) { 11739 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11740 if (dumpAll) { 11741 pw.println(":"); 11742 ArrayList<Intent> intents = ent.getValue(); 11743 final int N = intents.size(); 11744 for (int i=0; i<N; i++) { 11745 sb.setLength(0); 11746 sb.append(" Intent: "); 11747 intents.get(i).toShortString(sb, false, true, false, false); 11748 pw.println(sb.toString()); 11749 Bundle bundle = intents.get(i).getExtras(); 11750 if (bundle != null) { 11751 pw.print(" "); 11752 pw.println(bundle.toString()); 11753 } 11754 } 11755 } else { 11756 pw.println(""); 11757 } 11758 } 11759 } 11760 } 11761 11762 if (!onlyHistory && dumpAll) { 11763 pw.println(); 11764 for (BroadcastQueue queue : mBroadcastQueues) { 11765 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11766 + queue.mBroadcastsScheduled); 11767 } 11768 pw.println(" mHandler:"); 11769 mHandler.dump(new PrintWriterPrinter(pw), " "); 11770 needSep = true; 11771 printedAnything = true; 11772 } 11773 11774 if (!printedAnything) { 11775 pw.println(" (nothing)"); 11776 } 11777 } 11778 11779 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11780 int opti, boolean dumpAll, String dumpPackage) { 11781 boolean needSep; 11782 boolean printedAnything = false; 11783 11784 ItemMatcher matcher = new ItemMatcher(); 11785 matcher.build(args, opti); 11786 11787 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11788 11789 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11790 printedAnything |= needSep; 11791 11792 if (mLaunchingProviders.size() > 0) { 11793 boolean printed = false; 11794 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11795 ContentProviderRecord r = mLaunchingProviders.get(i); 11796 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11797 continue; 11798 } 11799 if (!printed) { 11800 if (needSep) pw.println(); 11801 needSep = true; 11802 pw.println(" Launching content providers:"); 11803 printed = true; 11804 printedAnything = true; 11805 } 11806 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11807 pw.println(r); 11808 } 11809 } 11810 11811 if (mGrantedUriPermissions.size() > 0) { 11812 boolean printed = false; 11813 int dumpUid = -2; 11814 if (dumpPackage != null) { 11815 try { 11816 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11817 } catch (NameNotFoundException e) { 11818 dumpUid = -1; 11819 } 11820 } 11821 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11822 int uid = mGrantedUriPermissions.keyAt(i); 11823 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11824 continue; 11825 } 11826 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11827 if (!printed) { 11828 if (needSep) pw.println(); 11829 needSep = true; 11830 pw.println(" Granted Uri Permissions:"); 11831 printed = true; 11832 printedAnything = true; 11833 } 11834 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11835 for (UriPermission perm : perms.values()) { 11836 pw.print(" "); pw.println(perm); 11837 if (dumpAll) { 11838 perm.dump(pw, " "); 11839 } 11840 } 11841 } 11842 } 11843 11844 if (!printedAnything) { 11845 pw.println(" (nothing)"); 11846 } 11847 } 11848 11849 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11850 int opti, boolean dumpAll, String dumpPackage) { 11851 boolean printed = false; 11852 11853 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11854 11855 if (mIntentSenderRecords.size() > 0) { 11856 Iterator<WeakReference<PendingIntentRecord>> it 11857 = mIntentSenderRecords.values().iterator(); 11858 while (it.hasNext()) { 11859 WeakReference<PendingIntentRecord> ref = it.next(); 11860 PendingIntentRecord rec = ref != null ? ref.get(): null; 11861 if (dumpPackage != null && (rec == null 11862 || !dumpPackage.equals(rec.key.packageName))) { 11863 continue; 11864 } 11865 printed = true; 11866 if (rec != null) { 11867 pw.print(" * "); pw.println(rec); 11868 if (dumpAll) { 11869 rec.dump(pw, " "); 11870 } 11871 } else { 11872 pw.print(" * "); pw.println(ref); 11873 } 11874 } 11875 } 11876 11877 if (!printed) { 11878 pw.println(" (nothing)"); 11879 } 11880 } 11881 11882 private static final int dumpProcessList(PrintWriter pw, 11883 ActivityManagerService service, List list, 11884 String prefix, String normalLabel, String persistentLabel, 11885 String dumpPackage) { 11886 int numPers = 0; 11887 final int N = list.size()-1; 11888 for (int i=N; i>=0; i--) { 11889 ProcessRecord r = (ProcessRecord)list.get(i); 11890 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11891 continue; 11892 } 11893 pw.println(String.format("%s%s #%2d: %s", 11894 prefix, (r.persistent ? persistentLabel : normalLabel), 11895 i, r.toString())); 11896 if (r.persistent) { 11897 numPers++; 11898 } 11899 } 11900 return numPers; 11901 } 11902 11903 private static final boolean dumpProcessOomList(PrintWriter pw, 11904 ActivityManagerService service, List<ProcessRecord> origList, 11905 String prefix, String normalLabel, String persistentLabel, 11906 boolean inclDetails, String dumpPackage) { 11907 11908 ArrayList<Pair<ProcessRecord, Integer>> list 11909 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11910 for (int i=0; i<origList.size(); i++) { 11911 ProcessRecord r = origList.get(i); 11912 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11913 continue; 11914 } 11915 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11916 } 11917 11918 if (list.size() <= 0) { 11919 return false; 11920 } 11921 11922 Comparator<Pair<ProcessRecord, Integer>> comparator 11923 = new Comparator<Pair<ProcessRecord, Integer>>() { 11924 @Override 11925 public int compare(Pair<ProcessRecord, Integer> object1, 11926 Pair<ProcessRecord, Integer> object2) { 11927 if (object1.first.setAdj != object2.first.setAdj) { 11928 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11929 } 11930 if (object1.second.intValue() != object2.second.intValue()) { 11931 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11932 } 11933 return 0; 11934 } 11935 }; 11936 11937 Collections.sort(list, comparator); 11938 11939 final long curRealtime = SystemClock.elapsedRealtime(); 11940 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11941 final long curUptime = SystemClock.uptimeMillis(); 11942 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11943 11944 for (int i=list.size()-1; i>=0; i--) { 11945 ProcessRecord r = list.get(i).first; 11946 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11947 char schedGroup; 11948 switch (r.setSchedGroup) { 11949 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11950 schedGroup = 'B'; 11951 break; 11952 case Process.THREAD_GROUP_DEFAULT: 11953 schedGroup = 'F'; 11954 break; 11955 default: 11956 schedGroup = '?'; 11957 break; 11958 } 11959 char foreground; 11960 if (r.foregroundActivities) { 11961 foreground = 'A'; 11962 } else if (r.foregroundServices) { 11963 foreground = 'S'; 11964 } else { 11965 foreground = ' '; 11966 } 11967 String procState = ProcessList.makeProcStateString(r.curProcState); 11968 pw.print(prefix); 11969 pw.print(r.persistent ? persistentLabel : normalLabel); 11970 pw.print(" #"); 11971 int num = (origList.size()-1)-list.get(i).second; 11972 if (num < 10) pw.print(' '); 11973 pw.print(num); 11974 pw.print(": "); 11975 pw.print(oomAdj); 11976 pw.print(' '); 11977 pw.print(schedGroup); 11978 pw.print('/'); 11979 pw.print(foreground); 11980 pw.print('/'); 11981 pw.print(procState); 11982 pw.print(" trm:"); 11983 if (r.trimMemoryLevel < 10) pw.print(' '); 11984 pw.print(r.trimMemoryLevel); 11985 pw.print(' '); 11986 pw.print(r.toShortString()); 11987 pw.print(" ("); 11988 pw.print(r.adjType); 11989 pw.println(')'); 11990 if (r.adjSource != null || r.adjTarget != null) { 11991 pw.print(prefix); 11992 pw.print(" "); 11993 if (r.adjTarget instanceof ComponentName) { 11994 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11995 } else if (r.adjTarget != null) { 11996 pw.print(r.adjTarget.toString()); 11997 } else { 11998 pw.print("{null}"); 11999 } 12000 pw.print("<="); 12001 if (r.adjSource instanceof ProcessRecord) { 12002 pw.print("Proc{"); 12003 pw.print(((ProcessRecord)r.adjSource).toShortString()); 12004 pw.println("}"); 12005 } else if (r.adjSource != null) { 12006 pw.println(r.adjSource.toString()); 12007 } else { 12008 pw.println("{null}"); 12009 } 12010 } 12011 if (inclDetails) { 12012 pw.print(prefix); 12013 pw.print(" "); 12014 pw.print("oom: max="); pw.print(r.maxAdj); 12015 pw.print(" curRaw="); pw.print(r.curRawAdj); 12016 pw.print(" setRaw="); pw.print(r.setRawAdj); 12017 pw.print(" cur="); pw.print(r.curAdj); 12018 pw.print(" set="); pw.println(r.setAdj); 12019 pw.print(prefix); 12020 pw.print(" "); 12021 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 12022 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 12023 pw.print(" lastPss="); pw.print(r.lastPss); 12024 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12025 pw.print(prefix); 12026 pw.print(" "); 12027 pw.print("keeping="); pw.print(r.keeping); 12028 pw.print(" cached="); pw.print(r.cached); 12029 pw.print(" empty="); pw.print(r.empty); 12030 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12031 12032 if (!r.keeping) { 12033 if (r.lastWakeTime != 0) { 12034 long wtime; 12035 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12036 synchronized (stats) { 12037 wtime = stats.getProcessWakeTime(r.info.uid, 12038 r.pid, curRealtime); 12039 } 12040 long timeUsed = wtime - r.lastWakeTime; 12041 pw.print(prefix); 12042 pw.print(" "); 12043 pw.print("keep awake over "); 12044 TimeUtils.formatDuration(realtimeSince, pw); 12045 pw.print(" used "); 12046 TimeUtils.formatDuration(timeUsed, pw); 12047 pw.print(" ("); 12048 pw.print((timeUsed*100)/realtimeSince); 12049 pw.println("%)"); 12050 } 12051 if (r.lastCpuTime != 0) { 12052 long timeUsed = r.curCpuTime - r.lastCpuTime; 12053 pw.print(prefix); 12054 pw.print(" "); 12055 pw.print("run cpu over "); 12056 TimeUtils.formatDuration(uptimeSince, pw); 12057 pw.print(" used "); 12058 TimeUtils.formatDuration(timeUsed, pw); 12059 pw.print(" ("); 12060 pw.print((timeUsed*100)/uptimeSince); 12061 pw.println("%)"); 12062 } 12063 } 12064 } 12065 } 12066 return true; 12067 } 12068 12069 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12070 ArrayList<ProcessRecord> procs; 12071 synchronized (this) { 12072 if (args != null && args.length > start 12073 && args[start].charAt(0) != '-') { 12074 procs = new ArrayList<ProcessRecord>(); 12075 int pid = -1; 12076 try { 12077 pid = Integer.parseInt(args[start]); 12078 } catch (NumberFormatException e) { 12079 } 12080 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12081 ProcessRecord proc = mLruProcesses.get(i); 12082 if (proc.pid == pid) { 12083 procs.add(proc); 12084 } else if (proc.processName.equals(args[start])) { 12085 procs.add(proc); 12086 } 12087 } 12088 if (procs.size() <= 0) { 12089 return null; 12090 } 12091 } else { 12092 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12093 } 12094 } 12095 return procs; 12096 } 12097 12098 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12099 PrintWriter pw, String[] args) { 12100 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12101 if (procs == null) { 12102 pw.println("No process found for: " + args[0]); 12103 return; 12104 } 12105 12106 long uptime = SystemClock.uptimeMillis(); 12107 long realtime = SystemClock.elapsedRealtime(); 12108 pw.println("Applications Graphics Acceleration Info:"); 12109 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12110 12111 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12112 ProcessRecord r = procs.get(i); 12113 if (r.thread != null) { 12114 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12115 pw.flush(); 12116 try { 12117 TransferPipe tp = new TransferPipe(); 12118 try { 12119 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12120 tp.go(fd); 12121 } finally { 12122 tp.kill(); 12123 } 12124 } catch (IOException e) { 12125 pw.println("Failure while dumping the app: " + r); 12126 pw.flush(); 12127 } catch (RemoteException e) { 12128 pw.println("Got a RemoteException while dumping the app " + r); 12129 pw.flush(); 12130 } 12131 } 12132 } 12133 } 12134 12135 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12136 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12137 if (procs == null) { 12138 pw.println("No process found for: " + args[0]); 12139 return; 12140 } 12141 12142 pw.println("Applications Database Info:"); 12143 12144 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12145 ProcessRecord r = procs.get(i); 12146 if (r.thread != null) { 12147 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12148 pw.flush(); 12149 try { 12150 TransferPipe tp = new TransferPipe(); 12151 try { 12152 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12153 tp.go(fd); 12154 } finally { 12155 tp.kill(); 12156 } 12157 } catch (IOException e) { 12158 pw.println("Failure while dumping the app: " + r); 12159 pw.flush(); 12160 } catch (RemoteException e) { 12161 pw.println("Got a RemoteException while dumping the app " + r); 12162 pw.flush(); 12163 } 12164 } 12165 } 12166 } 12167 12168 final static class MemItem { 12169 final boolean isProc; 12170 final String label; 12171 final String shortLabel; 12172 final long pss; 12173 final int id; 12174 final boolean hasActivities; 12175 ArrayList<MemItem> subitems; 12176 12177 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12178 boolean _hasActivities) { 12179 isProc = true; 12180 label = _label; 12181 shortLabel = _shortLabel; 12182 pss = _pss; 12183 id = _id; 12184 hasActivities = _hasActivities; 12185 } 12186 12187 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12188 isProc = false; 12189 label = _label; 12190 shortLabel = _shortLabel; 12191 pss = _pss; 12192 id = _id; 12193 hasActivities = false; 12194 } 12195 } 12196 12197 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12198 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12199 if (sort && !isCompact) { 12200 Collections.sort(items, new Comparator<MemItem>() { 12201 @Override 12202 public int compare(MemItem lhs, MemItem rhs) { 12203 if (lhs.pss < rhs.pss) { 12204 return 1; 12205 } else if (lhs.pss > rhs.pss) { 12206 return -1; 12207 } 12208 return 0; 12209 } 12210 }); 12211 } 12212 12213 for (int i=0; i<items.size(); i++) { 12214 MemItem mi = items.get(i); 12215 if (!isCompact) { 12216 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12217 } else if (mi.isProc) { 12218 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12219 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12220 pw.println(mi.hasActivities ? ",a" : ",e"); 12221 } else { 12222 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12223 pw.println(mi.pss); 12224 } 12225 if (mi.subitems != null) { 12226 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12227 true, isCompact); 12228 } 12229 } 12230 } 12231 12232 // These are in KB. 12233 static final long[] DUMP_MEM_BUCKETS = new long[] { 12234 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12235 120*1024, 160*1024, 200*1024, 12236 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12237 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12238 }; 12239 12240 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12241 boolean stackLike) { 12242 int start = label.lastIndexOf('.'); 12243 if (start >= 0) start++; 12244 else start = 0; 12245 int end = label.length(); 12246 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12247 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12248 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12249 out.append(bucket); 12250 out.append(stackLike ? "MB." : "MB "); 12251 out.append(label, start, end); 12252 return; 12253 } 12254 } 12255 out.append(memKB/1024); 12256 out.append(stackLike ? "MB." : "MB "); 12257 out.append(label, start, end); 12258 } 12259 12260 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12261 ProcessList.NATIVE_ADJ, 12262 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12263 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12264 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12265 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12266 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12267 }; 12268 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12269 "Native", 12270 "System", "Persistent", "Foreground", 12271 "Visible", "Perceptible", 12272 "Heavy Weight", "Backup", 12273 "A Services", "Home", 12274 "Previous", "B Services", "Cached" 12275 }; 12276 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12277 "native", 12278 "sys", "pers", "fore", 12279 "vis", "percept", 12280 "heavy", "backup", 12281 "servicea", "home", 12282 "prev", "serviceb", "cached" 12283 }; 12284 12285 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12286 long realtime, boolean isCheckinRequest, boolean isCompact) { 12287 if (isCheckinRequest || isCompact) { 12288 // short checkin version 12289 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12290 } else { 12291 pw.println("Applications Memory Usage (kB):"); 12292 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12293 } 12294 } 12295 12296 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12297 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12298 boolean dumpDetails = false; 12299 boolean dumpFullDetails = false; 12300 boolean dumpDalvik = false; 12301 boolean oomOnly = false; 12302 boolean isCompact = false; 12303 boolean localOnly = false; 12304 12305 int opti = 0; 12306 while (opti < args.length) { 12307 String opt = args[opti]; 12308 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12309 break; 12310 } 12311 opti++; 12312 if ("-a".equals(opt)) { 12313 dumpDetails = true; 12314 dumpFullDetails = true; 12315 dumpDalvik = true; 12316 } else if ("-d".equals(opt)) { 12317 dumpDalvik = true; 12318 } else if ("-c".equals(opt)) { 12319 isCompact = true; 12320 } else if ("--oom".equals(opt)) { 12321 oomOnly = true; 12322 } else if ("--local".equals(opt)) { 12323 localOnly = true; 12324 } else if ("-h".equals(opt)) { 12325 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12326 pw.println(" -a: include all available information for each process."); 12327 pw.println(" -d: include dalvik details when dumping process details."); 12328 pw.println(" -c: dump in a compact machine-parseable representation."); 12329 pw.println(" --oom: only show processes organized by oom adj."); 12330 pw.println(" --local: only collect details locally, don't call process."); 12331 pw.println("If [process] is specified it can be the name or "); 12332 pw.println("pid of a specific process to dump."); 12333 return; 12334 } else { 12335 pw.println("Unknown argument: " + opt + "; use -h for help"); 12336 } 12337 } 12338 12339 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12340 long uptime = SystemClock.uptimeMillis(); 12341 long realtime = SystemClock.elapsedRealtime(); 12342 final long[] tmpLong = new long[1]; 12343 12344 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12345 if (procs == null) { 12346 // No Java processes. Maybe they want to print a native process. 12347 if (args != null && args.length > opti 12348 && args[opti].charAt(0) != '-') { 12349 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12350 = new ArrayList<ProcessCpuTracker.Stats>(); 12351 updateCpuStatsNow(); 12352 int findPid = -1; 12353 try { 12354 findPid = Integer.parseInt(args[opti]); 12355 } catch (NumberFormatException e) { 12356 } 12357 synchronized (mProcessCpuThread) { 12358 final int N = mProcessCpuTracker.countStats(); 12359 for (int i=0; i<N; i++) { 12360 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12361 if (st.pid == findPid || (st.baseName != null 12362 && st.baseName.equals(args[opti]))) { 12363 nativeProcs.add(st); 12364 } 12365 } 12366 } 12367 if (nativeProcs.size() > 0) { 12368 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12369 isCompact); 12370 Debug.MemoryInfo mi = null; 12371 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12372 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12373 final int pid = r.pid; 12374 if (!isCheckinRequest && dumpDetails) { 12375 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12376 } 12377 if (mi == null) { 12378 mi = new Debug.MemoryInfo(); 12379 } 12380 if (dumpDetails || (!brief && !oomOnly)) { 12381 Debug.getMemoryInfo(pid, mi); 12382 } else { 12383 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12384 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12385 } 12386 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12387 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12388 if (isCheckinRequest) { 12389 pw.println(); 12390 } 12391 } 12392 return; 12393 } 12394 } 12395 pw.println("No process found for: " + args[opti]); 12396 return; 12397 } 12398 12399 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12400 dumpDetails = true; 12401 } 12402 12403 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12404 12405 String[] innerArgs = new String[args.length-opti]; 12406 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12407 12408 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12409 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12410 long nativePss=0, dalvikPss=0, otherPss=0; 12411 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12412 12413 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12414 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12415 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12416 12417 long totalPss = 0; 12418 long cachedPss = 0; 12419 12420 Debug.MemoryInfo mi = null; 12421 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12422 final ProcessRecord r = procs.get(i); 12423 final IApplicationThread thread; 12424 final int pid; 12425 final int oomAdj; 12426 final boolean hasActivities; 12427 synchronized (this) { 12428 thread = r.thread; 12429 pid = r.pid; 12430 oomAdj = r.getSetAdjWithServices(); 12431 hasActivities = r.activities.size() > 0; 12432 } 12433 if (thread != null) { 12434 if (!isCheckinRequest && dumpDetails) { 12435 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12436 } 12437 if (mi == null) { 12438 mi = new Debug.MemoryInfo(); 12439 } 12440 if (dumpDetails || (!brief && !oomOnly)) { 12441 Debug.getMemoryInfo(pid, mi); 12442 } else { 12443 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12444 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12445 } 12446 if (dumpDetails) { 12447 if (localOnly) { 12448 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12449 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12450 if (isCheckinRequest) { 12451 pw.println(); 12452 } 12453 } else { 12454 try { 12455 pw.flush(); 12456 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12457 dumpDalvik, innerArgs); 12458 } catch (RemoteException e) { 12459 if (!isCheckinRequest) { 12460 pw.println("Got RemoteException!"); 12461 pw.flush(); 12462 } 12463 } 12464 } 12465 } 12466 12467 final long myTotalPss = mi.getTotalPss(); 12468 final long myTotalUss = mi.getTotalUss(); 12469 12470 synchronized (this) { 12471 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12472 // Record this for posterity if the process has been stable. 12473 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12474 } 12475 } 12476 12477 if (!isCheckinRequest && mi != null) { 12478 totalPss += myTotalPss; 12479 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12480 (hasActivities ? " / activities)" : ")"), 12481 r.processName, myTotalPss, pid, hasActivities); 12482 procMems.add(pssItem); 12483 procMemsMap.put(pid, pssItem); 12484 12485 nativePss += mi.nativePss; 12486 dalvikPss += mi.dalvikPss; 12487 otherPss += mi.otherPss; 12488 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12489 long mem = mi.getOtherPss(j); 12490 miscPss[j] += mem; 12491 otherPss -= mem; 12492 } 12493 12494 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12495 cachedPss += myTotalPss; 12496 } 12497 12498 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12499 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12500 || oomIndex == (oomPss.length-1)) { 12501 oomPss[oomIndex] += myTotalPss; 12502 if (oomProcs[oomIndex] == null) { 12503 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12504 } 12505 oomProcs[oomIndex].add(pssItem); 12506 break; 12507 } 12508 } 12509 } 12510 } 12511 } 12512 12513 if (!isCheckinRequest && procs.size() > 1) { 12514 // If we are showing aggregations, also look for native processes to 12515 // include so that our aggregations are more accurate. 12516 updateCpuStatsNow(); 12517 synchronized (mProcessCpuThread) { 12518 final int N = mProcessCpuTracker.countStats(); 12519 for (int i=0; i<N; i++) { 12520 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12521 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12522 if (mi == null) { 12523 mi = new Debug.MemoryInfo(); 12524 } 12525 if (!brief && !oomOnly) { 12526 Debug.getMemoryInfo(st.pid, mi); 12527 } else { 12528 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12529 mi.nativePrivateDirty = (int)tmpLong[0]; 12530 } 12531 12532 final long myTotalPss = mi.getTotalPss(); 12533 totalPss += myTotalPss; 12534 12535 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12536 st.name, myTotalPss, st.pid, false); 12537 procMems.add(pssItem); 12538 12539 nativePss += mi.nativePss; 12540 dalvikPss += mi.dalvikPss; 12541 otherPss += mi.otherPss; 12542 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12543 long mem = mi.getOtherPss(j); 12544 miscPss[j] += mem; 12545 otherPss -= mem; 12546 } 12547 oomPss[0] += myTotalPss; 12548 if (oomProcs[0] == null) { 12549 oomProcs[0] = new ArrayList<MemItem>(); 12550 } 12551 oomProcs[0].add(pssItem); 12552 } 12553 } 12554 } 12555 12556 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12557 12558 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12559 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12560 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12561 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12562 String label = Debug.MemoryInfo.getOtherLabel(j); 12563 catMems.add(new MemItem(label, label, miscPss[j], j)); 12564 } 12565 12566 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12567 for (int j=0; j<oomPss.length; j++) { 12568 if (oomPss[j] != 0) { 12569 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12570 : DUMP_MEM_OOM_LABEL[j]; 12571 MemItem item = new MemItem(label, label, oomPss[j], 12572 DUMP_MEM_OOM_ADJ[j]); 12573 item.subitems = oomProcs[j]; 12574 oomMems.add(item); 12575 } 12576 } 12577 12578 if (!brief && !oomOnly && !isCompact) { 12579 pw.println(); 12580 pw.println("Total PSS by process:"); 12581 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12582 pw.println(); 12583 } 12584 if (!isCompact) { 12585 pw.println("Total PSS by OOM adjustment:"); 12586 } 12587 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12588 if (!brief && !oomOnly) { 12589 PrintWriter out = categoryPw != null ? categoryPw : pw; 12590 if (!isCompact) { 12591 out.println(); 12592 out.println("Total PSS by category:"); 12593 } 12594 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12595 } 12596 if (!isCompact) { 12597 pw.println(); 12598 } 12599 MemInfoReader memInfo = new MemInfoReader(); 12600 memInfo.readMemInfo(); 12601 if (!brief) { 12602 if (!isCompact) { 12603 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12604 pw.print(" kB (status "); 12605 switch (mLastMemoryLevel) { 12606 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12607 pw.println("normal)"); 12608 break; 12609 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12610 pw.println("moderate)"); 12611 break; 12612 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12613 pw.println("low)"); 12614 break; 12615 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12616 pw.println("critical)"); 12617 break; 12618 default: 12619 pw.print(mLastMemoryLevel); 12620 pw.println(")"); 12621 break; 12622 } 12623 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12624 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12625 pw.print(cachedPss); pw.print(" cached pss + "); 12626 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12627 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12628 } else { 12629 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12630 pw.print(cachedPss + memInfo.getCachedSizeKb() 12631 + memInfo.getFreeSizeKb()); pw.print(","); 12632 pw.println(totalPss - cachedPss); 12633 } 12634 } 12635 if (!isCompact) { 12636 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12637 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12638 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12639 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12640 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12641 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12642 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12643 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12644 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12645 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12646 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12647 } 12648 if (!brief) { 12649 if (memInfo.getZramTotalSizeKb() != 0) { 12650 if (!isCompact) { 12651 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12652 pw.print(" kB physical used for "); 12653 pw.print(memInfo.getSwapTotalSizeKb() 12654 - memInfo.getSwapFreeSizeKb()); 12655 pw.print(" kB in swap ("); 12656 pw.print(memInfo.getSwapTotalSizeKb()); 12657 pw.println(" kB total swap)"); 12658 } else { 12659 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12660 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12661 pw.println(memInfo.getSwapFreeSizeKb()); 12662 } 12663 } 12664 final int[] SINGLE_LONG_FORMAT = new int[] { 12665 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12666 }; 12667 long[] longOut = new long[1]; 12668 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12669 SINGLE_LONG_FORMAT, null, longOut, null); 12670 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12671 longOut[0] = 0; 12672 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12673 SINGLE_LONG_FORMAT, null, longOut, null); 12674 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12675 longOut[0] = 0; 12676 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12677 SINGLE_LONG_FORMAT, null, longOut, null); 12678 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12679 longOut[0] = 0; 12680 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12681 SINGLE_LONG_FORMAT, null, longOut, null); 12682 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12683 if (!isCompact) { 12684 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12685 pw.print(" KSM: "); pw.print(sharing); 12686 pw.print(" kB saved from shared "); 12687 pw.print(shared); pw.println(" kB"); 12688 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12689 pw.print(voltile); pw.println(" kB volatile"); 12690 } 12691 pw.print(" Tuning: "); 12692 pw.print(ActivityManager.staticGetMemoryClass()); 12693 pw.print(" (large "); 12694 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12695 pw.print("), oom "); 12696 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12697 pw.print(" kB"); 12698 pw.print(", restore limit "); 12699 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12700 pw.print(" kB"); 12701 if (ActivityManager.isLowRamDeviceStatic()) { 12702 pw.print(" (low-ram)"); 12703 } 12704 if (ActivityManager.isHighEndGfx()) { 12705 pw.print(" (high-end-gfx)"); 12706 } 12707 pw.println(); 12708 } else { 12709 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12710 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12711 pw.println(voltile); 12712 pw.print("tuning,"); 12713 pw.print(ActivityManager.staticGetMemoryClass()); 12714 pw.print(','); 12715 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12716 pw.print(','); 12717 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12718 if (ActivityManager.isLowRamDeviceStatic()) { 12719 pw.print(",low-ram"); 12720 } 12721 if (ActivityManager.isHighEndGfx()) { 12722 pw.print(",high-end-gfx"); 12723 } 12724 pw.println(); 12725 } 12726 } 12727 } 12728 } 12729 12730 /** 12731 * Searches array of arguments for the specified string 12732 * @param args array of argument strings 12733 * @param value value to search for 12734 * @return true if the value is contained in the array 12735 */ 12736 private static boolean scanArgs(String[] args, String value) { 12737 if (args != null) { 12738 for (String arg : args) { 12739 if (value.equals(arg)) { 12740 return true; 12741 } 12742 } 12743 } 12744 return false; 12745 } 12746 12747 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12748 ContentProviderRecord cpr, boolean always) { 12749 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12750 12751 if (!inLaunching || always) { 12752 synchronized (cpr) { 12753 cpr.launchingApp = null; 12754 cpr.notifyAll(); 12755 } 12756 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12757 String names[] = cpr.info.authority.split(";"); 12758 for (int j = 0; j < names.length; j++) { 12759 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12760 } 12761 } 12762 12763 for (int i=0; i<cpr.connections.size(); i++) { 12764 ContentProviderConnection conn = cpr.connections.get(i); 12765 if (conn.waiting) { 12766 // If this connection is waiting for the provider, then we don't 12767 // need to mess with its process unless we are always removing 12768 // or for some reason the provider is not currently launching. 12769 if (inLaunching && !always) { 12770 continue; 12771 } 12772 } 12773 ProcessRecord capp = conn.client; 12774 conn.dead = true; 12775 if (conn.stableCount > 0) { 12776 if (!capp.persistent && capp.thread != null 12777 && capp.pid != 0 12778 && capp.pid != MY_PID) { 12779 killUnneededProcessLocked(capp, "depends on provider " 12780 + cpr.name.flattenToShortString() 12781 + " in dying proc " + (proc != null ? proc.processName : "??")); 12782 } 12783 } else if (capp.thread != null && conn.provider.provider != null) { 12784 try { 12785 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12786 } catch (RemoteException e) { 12787 } 12788 // In the protocol here, we don't expect the client to correctly 12789 // clean up this connection, we'll just remove it. 12790 cpr.connections.remove(i); 12791 conn.client.conProviders.remove(conn); 12792 } 12793 } 12794 12795 if (inLaunching && always) { 12796 mLaunchingProviders.remove(cpr); 12797 } 12798 return inLaunching; 12799 } 12800 12801 /** 12802 * Main code for cleaning up a process when it has gone away. This is 12803 * called both as a result of the process dying, or directly when stopping 12804 * a process when running in single process mode. 12805 */ 12806 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12807 boolean restarting, boolean allowRestart, int index) { 12808 if (index >= 0) { 12809 removeLruProcessLocked(app); 12810 ProcessList.remove(app.pid); 12811 } 12812 12813 mProcessesToGc.remove(app); 12814 mPendingPssProcesses.remove(app); 12815 12816 // Dismiss any open dialogs. 12817 if (app.crashDialog != null && !app.forceCrashReport) { 12818 app.crashDialog.dismiss(); 12819 app.crashDialog = null; 12820 } 12821 if (app.anrDialog != null) { 12822 app.anrDialog.dismiss(); 12823 app.anrDialog = null; 12824 } 12825 if (app.waitDialog != null) { 12826 app.waitDialog.dismiss(); 12827 app.waitDialog = null; 12828 } 12829 12830 app.crashing = false; 12831 app.notResponding = false; 12832 12833 app.resetPackageList(mProcessStats); 12834 app.unlinkDeathRecipient(); 12835 app.makeInactive(mProcessStats); 12836 app.forcingToForeground = null; 12837 updateProcessForegroundLocked(app, false, false); 12838 app.foregroundActivities = false; 12839 app.hasShownUi = false; 12840 app.treatLikeActivity = false; 12841 app.hasAboveClient = false; 12842 app.hasClientActivities = false; 12843 12844 mServices.killServicesLocked(app, allowRestart); 12845 12846 boolean restart = false; 12847 12848 // Remove published content providers. 12849 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12850 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12851 final boolean always = app.bad || !allowRestart; 12852 if (removeDyingProviderLocked(app, cpr, always) || always) { 12853 // We left the provider in the launching list, need to 12854 // restart it. 12855 restart = true; 12856 } 12857 12858 cpr.provider = null; 12859 cpr.proc = null; 12860 } 12861 app.pubProviders.clear(); 12862 12863 // Take care of any launching providers waiting for this process. 12864 if (checkAppInLaunchingProvidersLocked(app, false)) { 12865 restart = true; 12866 } 12867 12868 // Unregister from connected content providers. 12869 if (!app.conProviders.isEmpty()) { 12870 for (int i=0; i<app.conProviders.size(); i++) { 12871 ContentProviderConnection conn = app.conProviders.get(i); 12872 conn.provider.connections.remove(conn); 12873 } 12874 app.conProviders.clear(); 12875 } 12876 12877 // At this point there may be remaining entries in mLaunchingProviders 12878 // where we were the only one waiting, so they are no longer of use. 12879 // Look for these and clean up if found. 12880 // XXX Commented out for now. Trying to figure out a way to reproduce 12881 // the actual situation to identify what is actually going on. 12882 if (false) { 12883 for (int i=0; i<mLaunchingProviders.size(); i++) { 12884 ContentProviderRecord cpr = (ContentProviderRecord) 12885 mLaunchingProviders.get(i); 12886 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12887 synchronized (cpr) { 12888 cpr.launchingApp = null; 12889 cpr.notifyAll(); 12890 } 12891 } 12892 } 12893 } 12894 12895 skipCurrentReceiverLocked(app); 12896 12897 // Unregister any receivers. 12898 for (int i=app.receivers.size()-1; i>=0; i--) { 12899 removeReceiverLocked(app.receivers.valueAt(i)); 12900 } 12901 app.receivers.clear(); 12902 12903 // If the app is undergoing backup, tell the backup manager about it 12904 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12905 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12906 + mBackupTarget.appInfo + " died during backup"); 12907 try { 12908 IBackupManager bm = IBackupManager.Stub.asInterface( 12909 ServiceManager.getService(Context.BACKUP_SERVICE)); 12910 bm.agentDisconnected(app.info.packageName); 12911 } catch (RemoteException e) { 12912 // can't happen; backup manager is local 12913 } 12914 } 12915 12916 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12917 ProcessChangeItem item = mPendingProcessChanges.get(i); 12918 if (item.pid == app.pid) { 12919 mPendingProcessChanges.remove(i); 12920 mAvailProcessChanges.add(item); 12921 } 12922 } 12923 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12924 12925 // If the caller is restarting this app, then leave it in its 12926 // current lists and let the caller take care of it. 12927 if (restarting) { 12928 return; 12929 } 12930 12931 if (!app.persistent || app.isolated) { 12932 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12933 "Removing non-persistent process during cleanup: " + app); 12934 mProcessNames.remove(app.processName, app.uid); 12935 mIsolatedProcesses.remove(app.uid); 12936 if (mHeavyWeightProcess == app) { 12937 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12938 mHeavyWeightProcess.userId, 0)); 12939 mHeavyWeightProcess = null; 12940 } 12941 } else if (!app.removed) { 12942 // This app is persistent, so we need to keep its record around. 12943 // If it is not already on the pending app list, add it there 12944 // and start a new process for it. 12945 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12946 mPersistentStartingProcesses.add(app); 12947 restart = true; 12948 } 12949 } 12950 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12951 "Clean-up removing on hold: " + app); 12952 mProcessesOnHold.remove(app); 12953 12954 if (app == mHomeProcess) { 12955 mHomeProcess = null; 12956 } 12957 if (app == mPreviousProcess) { 12958 mPreviousProcess = null; 12959 } 12960 12961 if (restart && !app.isolated) { 12962 // We have components that still need to be running in the 12963 // process, so re-launch it. 12964 mProcessNames.put(app.processName, app.uid, app); 12965 startProcessLocked(app, "restart", app.processName); 12966 } else if (app.pid > 0 && app.pid != MY_PID) { 12967 // Goodbye! 12968 boolean removed; 12969 synchronized (mPidsSelfLocked) { 12970 mPidsSelfLocked.remove(app.pid); 12971 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12972 } 12973 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12974 app.processName, app.info.uid); 12975 if (app.isolated) { 12976 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12977 } 12978 app.setPid(0); 12979 } 12980 } 12981 12982 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12983 // Look through the content providers we are waiting to have launched, 12984 // and if any run in this process then either schedule a restart of 12985 // the process or kill the client waiting for it if this process has 12986 // gone bad. 12987 int NL = mLaunchingProviders.size(); 12988 boolean restart = false; 12989 for (int i=0; i<NL; i++) { 12990 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12991 if (cpr.launchingApp == app) { 12992 if (!alwaysBad && !app.bad) { 12993 restart = true; 12994 } else { 12995 removeDyingProviderLocked(app, cpr, true); 12996 // cpr should have been removed from mLaunchingProviders 12997 NL = mLaunchingProviders.size(); 12998 i--; 12999 } 13000 } 13001 } 13002 return restart; 13003 } 13004 13005 // ========================================================= 13006 // SERVICES 13007 // ========================================================= 13008 13009 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 13010 int flags) { 13011 enforceNotIsolatedCaller("getServices"); 13012 synchronized (this) { 13013 return mServices.getRunningServiceInfoLocked(maxNum, flags); 13014 } 13015 } 13016 13017 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 13018 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 13019 synchronized (this) { 13020 return mServices.getRunningServiceControlPanelLocked(name); 13021 } 13022 } 13023 13024 public ComponentName startService(IApplicationThread caller, Intent service, 13025 String resolvedType, int userId) { 13026 enforceNotIsolatedCaller("startService"); 13027 // Refuse possible leaked file descriptors 13028 if (service != null && service.hasFileDescriptors() == true) { 13029 throw new IllegalArgumentException("File descriptors passed in Intent"); 13030 } 13031 13032 if (DEBUG_SERVICE) 13033 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13034 synchronized(this) { 13035 final int callingPid = Binder.getCallingPid(); 13036 final int callingUid = Binder.getCallingUid(); 13037 final long origId = Binder.clearCallingIdentity(); 13038 ComponentName res = mServices.startServiceLocked(caller, service, 13039 resolvedType, callingPid, callingUid, userId); 13040 Binder.restoreCallingIdentity(origId); 13041 return res; 13042 } 13043 } 13044 13045 ComponentName startServiceInPackage(int uid, 13046 Intent service, String resolvedType, int userId) { 13047 synchronized(this) { 13048 if (DEBUG_SERVICE) 13049 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13050 final long origId = Binder.clearCallingIdentity(); 13051 ComponentName res = mServices.startServiceLocked(null, service, 13052 resolvedType, -1, uid, userId); 13053 Binder.restoreCallingIdentity(origId); 13054 return res; 13055 } 13056 } 13057 13058 public int stopService(IApplicationThread caller, Intent service, 13059 String resolvedType, int userId) { 13060 enforceNotIsolatedCaller("stopService"); 13061 // Refuse possible leaked file descriptors 13062 if (service != null && service.hasFileDescriptors() == true) { 13063 throw new IllegalArgumentException("File descriptors passed in Intent"); 13064 } 13065 13066 synchronized(this) { 13067 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13068 } 13069 } 13070 13071 public IBinder peekService(Intent service, String resolvedType) { 13072 enforceNotIsolatedCaller("peekService"); 13073 // Refuse possible leaked file descriptors 13074 if (service != null && service.hasFileDescriptors() == true) { 13075 throw new IllegalArgumentException("File descriptors passed in Intent"); 13076 } 13077 synchronized(this) { 13078 return mServices.peekServiceLocked(service, resolvedType); 13079 } 13080 } 13081 13082 public boolean stopServiceToken(ComponentName className, IBinder token, 13083 int startId) { 13084 synchronized(this) { 13085 return mServices.stopServiceTokenLocked(className, token, startId); 13086 } 13087 } 13088 13089 public void setServiceForeground(ComponentName className, IBinder token, 13090 int id, Notification notification, boolean removeNotification) { 13091 synchronized(this) { 13092 mServices.setServiceForegroundLocked(className, token, id, notification, 13093 removeNotification); 13094 } 13095 } 13096 13097 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13098 boolean requireFull, String name, String callerPackage) { 13099 final int callingUserId = UserHandle.getUserId(callingUid); 13100 if (callingUserId != userId) { 13101 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13102 if ((requireFull || checkComponentPermission( 13103 android.Manifest.permission.INTERACT_ACROSS_USERS, 13104 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 13105 && checkComponentPermission( 13106 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 13107 callingPid, callingUid, -1, true) 13108 != PackageManager.PERMISSION_GRANTED) { 13109 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13110 // In this case, they would like to just execute as their 13111 // owner user instead of failing. 13112 userId = callingUserId; 13113 } else { 13114 StringBuilder builder = new StringBuilder(128); 13115 builder.append("Permission Denial: "); 13116 builder.append(name); 13117 if (callerPackage != null) { 13118 builder.append(" from "); 13119 builder.append(callerPackage); 13120 } 13121 builder.append(" asks to run as user "); 13122 builder.append(userId); 13123 builder.append(" but is calling from user "); 13124 builder.append(UserHandle.getUserId(callingUid)); 13125 builder.append("; this requires "); 13126 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 13127 if (!requireFull) { 13128 builder.append(" or "); 13129 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13130 } 13131 String msg = builder.toString(); 13132 Slog.w(TAG, msg); 13133 throw new SecurityException(msg); 13134 } 13135 } 13136 } 13137 if (userId == UserHandle.USER_CURRENT 13138 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13139 // Note that we may be accessing this outside of a lock... 13140 // shouldn't be a big deal, if this is being called outside 13141 // of a locked context there is intrinsically a race with 13142 // the value the caller will receive and someone else changing it. 13143 userId = mCurrentUserId; 13144 } 13145 if (!allowAll && userId < 0) { 13146 throw new IllegalArgumentException( 13147 "Call does not support special user #" + userId); 13148 } 13149 } 13150 return userId; 13151 } 13152 13153 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13154 String className, int flags) { 13155 boolean result = false; 13156 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13157 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 13158 if (ActivityManager.checkUidPermission( 13159 android.Manifest.permission.INTERACT_ACROSS_USERS, 13160 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13161 ComponentName comp = new ComponentName(aInfo.packageName, className); 13162 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13163 + " requests FLAG_SINGLE_USER, but app does not hold " 13164 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13165 Slog.w(TAG, msg); 13166 throw new SecurityException(msg); 13167 } 13168 result = true; 13169 } 13170 } else if (componentProcessName == aInfo.packageName) { 13171 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13172 } else if ("system".equals(componentProcessName)) { 13173 result = true; 13174 } 13175 if (DEBUG_MU) { 13176 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13177 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13178 } 13179 return result; 13180 } 13181 13182 public int bindService(IApplicationThread caller, IBinder token, 13183 Intent service, String resolvedType, 13184 IServiceConnection connection, int flags, int userId) { 13185 enforceNotIsolatedCaller("bindService"); 13186 // Refuse possible leaked file descriptors 13187 if (service != null && service.hasFileDescriptors() == true) { 13188 throw new IllegalArgumentException("File descriptors passed in Intent"); 13189 } 13190 13191 synchronized(this) { 13192 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13193 connection, flags, userId); 13194 } 13195 } 13196 13197 public boolean unbindService(IServiceConnection connection) { 13198 synchronized (this) { 13199 return mServices.unbindServiceLocked(connection); 13200 } 13201 } 13202 13203 public void publishService(IBinder token, Intent intent, IBinder service) { 13204 // Refuse possible leaked file descriptors 13205 if (intent != null && intent.hasFileDescriptors() == true) { 13206 throw new IllegalArgumentException("File descriptors passed in Intent"); 13207 } 13208 13209 synchronized(this) { 13210 if (!(token instanceof ServiceRecord)) { 13211 throw new IllegalArgumentException("Invalid service token"); 13212 } 13213 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13214 } 13215 } 13216 13217 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13218 // Refuse possible leaked file descriptors 13219 if (intent != null && intent.hasFileDescriptors() == true) { 13220 throw new IllegalArgumentException("File descriptors passed in Intent"); 13221 } 13222 13223 synchronized(this) { 13224 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13225 } 13226 } 13227 13228 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13229 synchronized(this) { 13230 if (!(token instanceof ServiceRecord)) { 13231 throw new IllegalArgumentException("Invalid service token"); 13232 } 13233 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13234 } 13235 } 13236 13237 // ========================================================= 13238 // BACKUP AND RESTORE 13239 // ========================================================= 13240 13241 // Cause the target app to be launched if necessary and its backup agent 13242 // instantiated. The backup agent will invoke backupAgentCreated() on the 13243 // activity manager to announce its creation. 13244 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13245 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13246 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13247 13248 synchronized(this) { 13249 // !!! TODO: currently no check here that we're already bound 13250 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13251 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13252 synchronized (stats) { 13253 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13254 } 13255 13256 // Backup agent is now in use, its package can't be stopped. 13257 try { 13258 AppGlobals.getPackageManager().setPackageStoppedState( 13259 app.packageName, false, UserHandle.getUserId(app.uid)); 13260 } catch (RemoteException e) { 13261 } catch (IllegalArgumentException e) { 13262 Slog.w(TAG, "Failed trying to unstop package " 13263 + app.packageName + ": " + e); 13264 } 13265 13266 BackupRecord r = new BackupRecord(ss, app, backupMode); 13267 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13268 ? new ComponentName(app.packageName, app.backupAgentName) 13269 : new ComponentName("android", "FullBackupAgent"); 13270 // startProcessLocked() returns existing proc's record if it's already running 13271 ProcessRecord proc = startProcessLocked(app.processName, app, 13272 false, 0, "backup", hostingName, false, false, false); 13273 if (proc == null) { 13274 Slog.e(TAG, "Unable to start backup agent process " + r); 13275 return false; 13276 } 13277 13278 r.app = proc; 13279 mBackupTarget = r; 13280 mBackupAppName = app.packageName; 13281 13282 // Try not to kill the process during backup 13283 updateOomAdjLocked(proc); 13284 13285 // If the process is already attached, schedule the creation of the backup agent now. 13286 // If it is not yet live, this will be done when it attaches to the framework. 13287 if (proc.thread != null) { 13288 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13289 try { 13290 proc.thread.scheduleCreateBackupAgent(app, 13291 compatibilityInfoForPackageLocked(app), backupMode); 13292 } catch (RemoteException e) { 13293 // Will time out on the backup manager side 13294 } 13295 } else { 13296 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13297 } 13298 // Invariants: at this point, the target app process exists and the application 13299 // is either already running or in the process of coming up. mBackupTarget and 13300 // mBackupAppName describe the app, so that when it binds back to the AM we 13301 // know that it's scheduled for a backup-agent operation. 13302 } 13303 13304 return true; 13305 } 13306 13307 @Override 13308 public void clearPendingBackup() { 13309 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13310 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13311 13312 synchronized (this) { 13313 mBackupTarget = null; 13314 mBackupAppName = null; 13315 } 13316 } 13317 13318 // A backup agent has just come up 13319 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13320 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13321 + " = " + agent); 13322 13323 synchronized(this) { 13324 if (!agentPackageName.equals(mBackupAppName)) { 13325 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13326 return; 13327 } 13328 } 13329 13330 long oldIdent = Binder.clearCallingIdentity(); 13331 try { 13332 IBackupManager bm = IBackupManager.Stub.asInterface( 13333 ServiceManager.getService(Context.BACKUP_SERVICE)); 13334 bm.agentConnected(agentPackageName, agent); 13335 } catch (RemoteException e) { 13336 // can't happen; the backup manager service is local 13337 } catch (Exception e) { 13338 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13339 e.printStackTrace(); 13340 } finally { 13341 Binder.restoreCallingIdentity(oldIdent); 13342 } 13343 } 13344 13345 // done with this agent 13346 public void unbindBackupAgent(ApplicationInfo appInfo) { 13347 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13348 if (appInfo == null) { 13349 Slog.w(TAG, "unbind backup agent for null app"); 13350 return; 13351 } 13352 13353 synchronized(this) { 13354 try { 13355 if (mBackupAppName == null) { 13356 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13357 return; 13358 } 13359 13360 if (!mBackupAppName.equals(appInfo.packageName)) { 13361 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13362 return; 13363 } 13364 13365 // Not backing this app up any more; reset its OOM adjustment 13366 final ProcessRecord proc = mBackupTarget.app; 13367 updateOomAdjLocked(proc); 13368 13369 // If the app crashed during backup, 'thread' will be null here 13370 if (proc.thread != null) { 13371 try { 13372 proc.thread.scheduleDestroyBackupAgent(appInfo, 13373 compatibilityInfoForPackageLocked(appInfo)); 13374 } catch (Exception e) { 13375 Slog.e(TAG, "Exception when unbinding backup agent:"); 13376 e.printStackTrace(); 13377 } 13378 } 13379 } finally { 13380 mBackupTarget = null; 13381 mBackupAppName = null; 13382 } 13383 } 13384 } 13385 // ========================================================= 13386 // BROADCASTS 13387 // ========================================================= 13388 13389 private final List getStickiesLocked(String action, IntentFilter filter, 13390 List cur, int userId) { 13391 final ContentResolver resolver = mContext.getContentResolver(); 13392 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13393 if (stickies == null) { 13394 return cur; 13395 } 13396 final ArrayList<Intent> list = stickies.get(action); 13397 if (list == null) { 13398 return cur; 13399 } 13400 int N = list.size(); 13401 for (int i=0; i<N; i++) { 13402 Intent intent = list.get(i); 13403 if (filter.match(resolver, intent, true, TAG) >= 0) { 13404 if (cur == null) { 13405 cur = new ArrayList<Intent>(); 13406 } 13407 cur.add(intent); 13408 } 13409 } 13410 return cur; 13411 } 13412 13413 boolean isPendingBroadcastProcessLocked(int pid) { 13414 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13415 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13416 } 13417 13418 void skipPendingBroadcastLocked(int pid) { 13419 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13420 for (BroadcastQueue queue : mBroadcastQueues) { 13421 queue.skipPendingBroadcastLocked(pid); 13422 } 13423 } 13424 13425 // The app just attached; send any pending broadcasts that it should receive 13426 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13427 boolean didSomething = false; 13428 for (BroadcastQueue queue : mBroadcastQueues) { 13429 didSomething |= queue.sendPendingBroadcastsLocked(app); 13430 } 13431 return didSomething; 13432 } 13433 13434 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13435 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13436 enforceNotIsolatedCaller("registerReceiver"); 13437 int callingUid; 13438 int callingPid; 13439 synchronized(this) { 13440 ProcessRecord callerApp = null; 13441 if (caller != null) { 13442 callerApp = getRecordForAppLocked(caller); 13443 if (callerApp == null) { 13444 throw new SecurityException( 13445 "Unable to find app for caller " + caller 13446 + " (pid=" + Binder.getCallingPid() 13447 + ") when registering receiver " + receiver); 13448 } 13449 if (callerApp.info.uid != Process.SYSTEM_UID && 13450 !callerApp.pkgList.containsKey(callerPackage) && 13451 !"android".equals(callerPackage)) { 13452 throw new SecurityException("Given caller package " + callerPackage 13453 + " is not running in process " + callerApp); 13454 } 13455 callingUid = callerApp.info.uid; 13456 callingPid = callerApp.pid; 13457 } else { 13458 callerPackage = null; 13459 callingUid = Binder.getCallingUid(); 13460 callingPid = Binder.getCallingPid(); 13461 } 13462 13463 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13464 true, true, "registerReceiver", callerPackage); 13465 13466 List allSticky = null; 13467 13468 // Look for any matching sticky broadcasts... 13469 Iterator actions = filter.actionsIterator(); 13470 if (actions != null) { 13471 while (actions.hasNext()) { 13472 String action = (String)actions.next(); 13473 allSticky = getStickiesLocked(action, filter, allSticky, 13474 UserHandle.USER_ALL); 13475 allSticky = getStickiesLocked(action, filter, allSticky, 13476 UserHandle.getUserId(callingUid)); 13477 } 13478 } else { 13479 allSticky = getStickiesLocked(null, filter, allSticky, 13480 UserHandle.USER_ALL); 13481 allSticky = getStickiesLocked(null, filter, allSticky, 13482 UserHandle.getUserId(callingUid)); 13483 } 13484 13485 // The first sticky in the list is returned directly back to 13486 // the client. 13487 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13488 13489 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13490 + ": " + sticky); 13491 13492 if (receiver == null) { 13493 return sticky; 13494 } 13495 13496 ReceiverList rl 13497 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13498 if (rl == null) { 13499 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13500 userId, receiver); 13501 if (rl.app != null) { 13502 rl.app.receivers.add(rl); 13503 } else { 13504 try { 13505 receiver.asBinder().linkToDeath(rl, 0); 13506 } catch (RemoteException e) { 13507 return sticky; 13508 } 13509 rl.linkedToDeath = true; 13510 } 13511 mRegisteredReceivers.put(receiver.asBinder(), rl); 13512 } else if (rl.uid != callingUid) { 13513 throw new IllegalArgumentException( 13514 "Receiver requested to register for uid " + callingUid 13515 + " was previously registered for uid " + rl.uid); 13516 } else if (rl.pid != callingPid) { 13517 throw new IllegalArgumentException( 13518 "Receiver requested to register for pid " + callingPid 13519 + " was previously registered for pid " + rl.pid); 13520 } else if (rl.userId != userId) { 13521 throw new IllegalArgumentException( 13522 "Receiver requested to register for user " + userId 13523 + " was previously registered for user " + rl.userId); 13524 } 13525 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13526 permission, callingUid, userId); 13527 rl.add(bf); 13528 if (!bf.debugCheck()) { 13529 Slog.w(TAG, "==> For Dynamic broadast"); 13530 } 13531 mReceiverResolver.addFilter(bf); 13532 13533 // Enqueue broadcasts for all existing stickies that match 13534 // this filter. 13535 if (allSticky != null) { 13536 ArrayList receivers = new ArrayList(); 13537 receivers.add(bf); 13538 13539 int N = allSticky.size(); 13540 for (int i=0; i<N; i++) { 13541 Intent intent = (Intent)allSticky.get(i); 13542 BroadcastQueue queue = broadcastQueueForIntent(intent); 13543 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13544 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13545 null, null, false, true, true, -1); 13546 queue.enqueueParallelBroadcastLocked(r); 13547 queue.scheduleBroadcastsLocked(); 13548 } 13549 } 13550 13551 return sticky; 13552 } 13553 } 13554 13555 public void unregisterReceiver(IIntentReceiver receiver) { 13556 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13557 13558 final long origId = Binder.clearCallingIdentity(); 13559 try { 13560 boolean doTrim = false; 13561 13562 synchronized(this) { 13563 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13564 if (rl != null) { 13565 if (rl.curBroadcast != null) { 13566 BroadcastRecord r = rl.curBroadcast; 13567 final boolean doNext = finishReceiverLocked( 13568 receiver.asBinder(), r.resultCode, r.resultData, 13569 r.resultExtras, r.resultAbort); 13570 if (doNext) { 13571 doTrim = true; 13572 r.queue.processNextBroadcast(false); 13573 } 13574 } 13575 13576 if (rl.app != null) { 13577 rl.app.receivers.remove(rl); 13578 } 13579 removeReceiverLocked(rl); 13580 if (rl.linkedToDeath) { 13581 rl.linkedToDeath = false; 13582 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13583 } 13584 } 13585 } 13586 13587 // If we actually concluded any broadcasts, we might now be able 13588 // to trim the recipients' apps from our working set 13589 if (doTrim) { 13590 trimApplications(); 13591 return; 13592 } 13593 13594 } finally { 13595 Binder.restoreCallingIdentity(origId); 13596 } 13597 } 13598 13599 void removeReceiverLocked(ReceiverList rl) { 13600 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13601 int N = rl.size(); 13602 for (int i=0; i<N; i++) { 13603 mReceiverResolver.removeFilter(rl.get(i)); 13604 } 13605 } 13606 13607 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13608 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13609 ProcessRecord r = mLruProcesses.get(i); 13610 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13611 try { 13612 r.thread.dispatchPackageBroadcast(cmd, packages); 13613 } catch (RemoteException ex) { 13614 } 13615 } 13616 } 13617 } 13618 13619 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13620 int[] users) { 13621 List<ResolveInfo> receivers = null; 13622 try { 13623 HashSet<ComponentName> singleUserReceivers = null; 13624 boolean scannedFirstReceivers = false; 13625 for (int user : users) { 13626 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13627 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13628 if (user != 0 && newReceivers != null) { 13629 // If this is not the primary user, we need to check for 13630 // any receivers that should be filtered out. 13631 for (int i=0; i<newReceivers.size(); i++) { 13632 ResolveInfo ri = newReceivers.get(i); 13633 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13634 newReceivers.remove(i); 13635 i--; 13636 } 13637 } 13638 } 13639 if (newReceivers != null && newReceivers.size() == 0) { 13640 newReceivers = null; 13641 } 13642 if (receivers == null) { 13643 receivers = newReceivers; 13644 } else if (newReceivers != null) { 13645 // We need to concatenate the additional receivers 13646 // found with what we have do far. This would be easy, 13647 // but we also need to de-dup any receivers that are 13648 // singleUser. 13649 if (!scannedFirstReceivers) { 13650 // Collect any single user receivers we had already retrieved. 13651 scannedFirstReceivers = true; 13652 for (int i=0; i<receivers.size(); i++) { 13653 ResolveInfo ri = receivers.get(i); 13654 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13655 ComponentName cn = new ComponentName( 13656 ri.activityInfo.packageName, ri.activityInfo.name); 13657 if (singleUserReceivers == null) { 13658 singleUserReceivers = new HashSet<ComponentName>(); 13659 } 13660 singleUserReceivers.add(cn); 13661 } 13662 } 13663 } 13664 // Add the new results to the existing results, tracking 13665 // and de-dupping single user receivers. 13666 for (int i=0; i<newReceivers.size(); i++) { 13667 ResolveInfo ri = newReceivers.get(i); 13668 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13669 ComponentName cn = new ComponentName( 13670 ri.activityInfo.packageName, ri.activityInfo.name); 13671 if (singleUserReceivers == null) { 13672 singleUserReceivers = new HashSet<ComponentName>(); 13673 } 13674 if (!singleUserReceivers.contains(cn)) { 13675 singleUserReceivers.add(cn); 13676 receivers.add(ri); 13677 } 13678 } else { 13679 receivers.add(ri); 13680 } 13681 } 13682 } 13683 } 13684 } catch (RemoteException ex) { 13685 // pm is in same process, this will never happen. 13686 } 13687 return receivers; 13688 } 13689 13690 private final int broadcastIntentLocked(ProcessRecord callerApp, 13691 String callerPackage, Intent intent, String resolvedType, 13692 IIntentReceiver resultTo, int resultCode, String resultData, 13693 Bundle map, String requiredPermission, int appOp, 13694 boolean ordered, boolean sticky, int callingPid, int callingUid, 13695 int userId) { 13696 intent = new Intent(intent); 13697 13698 // By default broadcasts do not go to stopped apps. 13699 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13700 13701 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13702 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13703 + " ordered=" + ordered + " userid=" + userId); 13704 if ((resultTo != null) && !ordered) { 13705 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13706 } 13707 13708 userId = handleIncomingUser(callingPid, callingUid, userId, 13709 true, false, "broadcast", callerPackage); 13710 13711 // Make sure that the user who is receiving this broadcast is started. 13712 // If not, we will just skip it. 13713 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13714 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13715 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13716 Slog.w(TAG, "Skipping broadcast of " + intent 13717 + ": user " + userId + " is stopped"); 13718 return ActivityManager.BROADCAST_SUCCESS; 13719 } 13720 } 13721 13722 /* 13723 * Prevent non-system code (defined here to be non-persistent 13724 * processes) from sending protected broadcasts. 13725 */ 13726 int callingAppId = UserHandle.getAppId(callingUid); 13727 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13728 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13729 callingUid == 0) { 13730 // Always okay. 13731 } else if (callerApp == null || !callerApp.persistent) { 13732 try { 13733 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13734 intent.getAction())) { 13735 String msg = "Permission Denial: not allowed to send broadcast " 13736 + intent.getAction() + " from pid=" 13737 + callingPid + ", uid=" + callingUid; 13738 Slog.w(TAG, msg); 13739 throw new SecurityException(msg); 13740 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13741 // Special case for compatibility: we don't want apps to send this, 13742 // but historically it has not been protected and apps may be using it 13743 // to poke their own app widget. So, instead of making it protected, 13744 // just limit it to the caller. 13745 if (callerApp == null) { 13746 String msg = "Permission Denial: not allowed to send broadcast " 13747 + intent.getAction() + " from unknown caller."; 13748 Slog.w(TAG, msg); 13749 throw new SecurityException(msg); 13750 } else if (intent.getComponent() != null) { 13751 // They are good enough to send to an explicit component... verify 13752 // it is being sent to the calling app. 13753 if (!intent.getComponent().getPackageName().equals( 13754 callerApp.info.packageName)) { 13755 String msg = "Permission Denial: not allowed to send broadcast " 13756 + intent.getAction() + " to " 13757 + intent.getComponent().getPackageName() + " from " 13758 + callerApp.info.packageName; 13759 Slog.w(TAG, msg); 13760 throw new SecurityException(msg); 13761 } 13762 } else { 13763 // Limit broadcast to their own package. 13764 intent.setPackage(callerApp.info.packageName); 13765 } 13766 } 13767 } catch (RemoteException e) { 13768 Slog.w(TAG, "Remote exception", e); 13769 return ActivityManager.BROADCAST_SUCCESS; 13770 } 13771 } 13772 13773 // Handle special intents: if this broadcast is from the package 13774 // manager about a package being removed, we need to remove all of 13775 // its activities from the history stack. 13776 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13777 intent.getAction()); 13778 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13779 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13780 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13781 || uidRemoved) { 13782 if (checkComponentPermission( 13783 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13784 callingPid, callingUid, -1, true) 13785 == PackageManager.PERMISSION_GRANTED) { 13786 if (uidRemoved) { 13787 final Bundle intentExtras = intent.getExtras(); 13788 final int uid = intentExtras != null 13789 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13790 if (uid >= 0) { 13791 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13792 synchronized (bs) { 13793 bs.removeUidStatsLocked(uid); 13794 } 13795 mAppOpsService.uidRemoved(uid); 13796 } 13797 } else { 13798 // If resources are unavailable just force stop all 13799 // those packages and flush the attribute cache as well. 13800 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13801 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13802 if (list != null && (list.length > 0)) { 13803 for (String pkg : list) { 13804 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13805 "storage unmount"); 13806 } 13807 sendPackageBroadcastLocked( 13808 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13809 } 13810 } else { 13811 Uri data = intent.getData(); 13812 String ssp; 13813 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13814 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13815 intent.getAction()); 13816 boolean fullUninstall = removed && 13817 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13818 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13819 forceStopPackageLocked(ssp, UserHandle.getAppId( 13820 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13821 false, fullUninstall, userId, 13822 removed ? "pkg removed" : "pkg changed"); 13823 } 13824 if (removed) { 13825 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13826 new String[] {ssp}, userId); 13827 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13828 mAppOpsService.packageRemoved( 13829 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13830 13831 // Remove all permissions granted from/to this package 13832 removeUriPermissionsForPackageLocked(ssp, userId, true); 13833 } 13834 } 13835 } 13836 } 13837 } 13838 } else { 13839 String msg = "Permission Denial: " + intent.getAction() 13840 + " broadcast from " + callerPackage + " (pid=" + callingPid 13841 + ", uid=" + callingUid + ")" 13842 + " requires " 13843 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13844 Slog.w(TAG, msg); 13845 throw new SecurityException(msg); 13846 } 13847 13848 // Special case for adding a package: by default turn on compatibility 13849 // mode. 13850 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13851 Uri data = intent.getData(); 13852 String ssp; 13853 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13854 mCompatModePackages.handlePackageAddedLocked(ssp, 13855 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13856 } 13857 } 13858 13859 /* 13860 * If this is the time zone changed action, queue up a message that will reset the timezone 13861 * of all currently running processes. This message will get queued up before the broadcast 13862 * happens. 13863 */ 13864 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13865 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13866 } 13867 13868 /* 13869 * If the user set the time, let all running processes know. 13870 */ 13871 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13872 final int is24Hour = intent.getBooleanExtra( 13873 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13874 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13875 } 13876 13877 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13878 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13879 } 13880 13881 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13882 ProxyInfo proxy = intent.getParcelableExtra("proxy"); 13883 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13884 } 13885 13886 // Add to the sticky list if requested. 13887 if (sticky) { 13888 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13889 callingPid, callingUid) 13890 != PackageManager.PERMISSION_GRANTED) { 13891 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13892 + callingPid + ", uid=" + callingUid 13893 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13894 Slog.w(TAG, msg); 13895 throw new SecurityException(msg); 13896 } 13897 if (requiredPermission != null) { 13898 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13899 + " and enforce permission " + requiredPermission); 13900 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13901 } 13902 if (intent.getComponent() != null) { 13903 throw new SecurityException( 13904 "Sticky broadcasts can't target a specific component"); 13905 } 13906 // We use userId directly here, since the "all" target is maintained 13907 // as a separate set of sticky broadcasts. 13908 if (userId != UserHandle.USER_ALL) { 13909 // But first, if this is not a broadcast to all users, then 13910 // make sure it doesn't conflict with an existing broadcast to 13911 // all users. 13912 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13913 UserHandle.USER_ALL); 13914 if (stickies != null) { 13915 ArrayList<Intent> list = stickies.get(intent.getAction()); 13916 if (list != null) { 13917 int N = list.size(); 13918 int i; 13919 for (i=0; i<N; i++) { 13920 if (intent.filterEquals(list.get(i))) { 13921 throw new IllegalArgumentException( 13922 "Sticky broadcast " + intent + " for user " 13923 + userId + " conflicts with existing global broadcast"); 13924 } 13925 } 13926 } 13927 } 13928 } 13929 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13930 if (stickies == null) { 13931 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13932 mStickyBroadcasts.put(userId, stickies); 13933 } 13934 ArrayList<Intent> list = stickies.get(intent.getAction()); 13935 if (list == null) { 13936 list = new ArrayList<Intent>(); 13937 stickies.put(intent.getAction(), list); 13938 } 13939 int N = list.size(); 13940 int i; 13941 for (i=0; i<N; i++) { 13942 if (intent.filterEquals(list.get(i))) { 13943 // This sticky already exists, replace it. 13944 list.set(i, new Intent(intent)); 13945 break; 13946 } 13947 } 13948 if (i >= N) { 13949 list.add(new Intent(intent)); 13950 } 13951 } 13952 13953 int[] users; 13954 if (userId == UserHandle.USER_ALL) { 13955 // Caller wants broadcast to go to all started users. 13956 users = mStartedUserArray; 13957 } else { 13958 // Caller wants broadcast to go to one specific user. 13959 users = new int[] {userId}; 13960 } 13961 13962 // Figure out who all will receive this broadcast. 13963 List receivers = null; 13964 List<BroadcastFilter> registeredReceivers = null; 13965 // Need to resolve the intent to interested receivers... 13966 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13967 == 0) { 13968 receivers = collectReceiverComponents(intent, resolvedType, users); 13969 } 13970 if (intent.getComponent() == null) { 13971 registeredReceivers = mReceiverResolver.queryIntent(intent, 13972 resolvedType, false, userId); 13973 } 13974 13975 final boolean replacePending = 13976 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13977 13978 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13979 + " replacePending=" + replacePending); 13980 13981 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13982 if (!ordered && NR > 0) { 13983 // If we are not serializing this broadcast, then send the 13984 // registered receivers separately so they don't wait for the 13985 // components to be launched. 13986 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13987 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13988 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13989 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13990 ordered, sticky, false, userId); 13991 if (DEBUG_BROADCAST) Slog.v( 13992 TAG, "Enqueueing parallel broadcast " + r); 13993 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13994 if (!replaced) { 13995 queue.enqueueParallelBroadcastLocked(r); 13996 queue.scheduleBroadcastsLocked(); 13997 } 13998 registeredReceivers = null; 13999 NR = 0; 14000 } 14001 14002 // Merge into one list. 14003 int ir = 0; 14004 if (receivers != null) { 14005 // A special case for PACKAGE_ADDED: do not allow the package 14006 // being added to see this broadcast. This prevents them from 14007 // using this as a back door to get run as soon as they are 14008 // installed. Maybe in the future we want to have a special install 14009 // broadcast or such for apps, but we'd like to deliberately make 14010 // this decision. 14011 String skipPackages[] = null; 14012 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 14013 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 14014 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 14015 Uri data = intent.getData(); 14016 if (data != null) { 14017 String pkgName = data.getSchemeSpecificPart(); 14018 if (pkgName != null) { 14019 skipPackages = new String[] { pkgName }; 14020 } 14021 } 14022 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 14023 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14024 } 14025 if (skipPackages != null && (skipPackages.length > 0)) { 14026 for (String skipPackage : skipPackages) { 14027 if (skipPackage != null) { 14028 int NT = receivers.size(); 14029 for (int it=0; it<NT; it++) { 14030 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14031 if (curt.activityInfo.packageName.equals(skipPackage)) { 14032 receivers.remove(it); 14033 it--; 14034 NT--; 14035 } 14036 } 14037 } 14038 } 14039 } 14040 14041 int NT = receivers != null ? receivers.size() : 0; 14042 int it = 0; 14043 ResolveInfo curt = null; 14044 BroadcastFilter curr = null; 14045 while (it < NT && ir < NR) { 14046 if (curt == null) { 14047 curt = (ResolveInfo)receivers.get(it); 14048 } 14049 if (curr == null) { 14050 curr = registeredReceivers.get(ir); 14051 } 14052 if (curr.getPriority() >= curt.priority) { 14053 // Insert this broadcast record into the final list. 14054 receivers.add(it, curr); 14055 ir++; 14056 curr = null; 14057 it++; 14058 NT++; 14059 } else { 14060 // Skip to the next ResolveInfo in the final list. 14061 it++; 14062 curt = null; 14063 } 14064 } 14065 } 14066 while (ir < NR) { 14067 if (receivers == null) { 14068 receivers = new ArrayList(); 14069 } 14070 receivers.add(registeredReceivers.get(ir)); 14071 ir++; 14072 } 14073 14074 if ((receivers != null && receivers.size() > 0) 14075 || resultTo != null) { 14076 BroadcastQueue queue = broadcastQueueForIntent(intent); 14077 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14078 callerPackage, callingPid, callingUid, resolvedType, 14079 requiredPermission, appOp, receivers, resultTo, resultCode, 14080 resultData, map, ordered, sticky, false, userId); 14081 if (DEBUG_BROADCAST) Slog.v( 14082 TAG, "Enqueueing ordered broadcast " + r 14083 + ": prev had " + queue.mOrderedBroadcasts.size()); 14084 if (DEBUG_BROADCAST) { 14085 int seq = r.intent.getIntExtra("seq", -1); 14086 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14087 } 14088 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14089 if (!replaced) { 14090 queue.enqueueOrderedBroadcastLocked(r); 14091 queue.scheduleBroadcastsLocked(); 14092 } 14093 } 14094 14095 return ActivityManager.BROADCAST_SUCCESS; 14096 } 14097 14098 final Intent verifyBroadcastLocked(Intent intent) { 14099 // Refuse possible leaked file descriptors 14100 if (intent != null && intent.hasFileDescriptors() == true) { 14101 throw new IllegalArgumentException("File descriptors passed in Intent"); 14102 } 14103 14104 int flags = intent.getFlags(); 14105 14106 if (!mProcessesReady) { 14107 // if the caller really truly claims to know what they're doing, go 14108 // ahead and allow the broadcast without launching any receivers 14109 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14110 intent = new Intent(intent); 14111 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14112 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14113 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14114 + " before boot completion"); 14115 throw new IllegalStateException("Cannot broadcast before boot completed"); 14116 } 14117 } 14118 14119 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14120 throw new IllegalArgumentException( 14121 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14122 } 14123 14124 return intent; 14125 } 14126 14127 public final int broadcastIntent(IApplicationThread caller, 14128 Intent intent, String resolvedType, IIntentReceiver resultTo, 14129 int resultCode, String resultData, Bundle map, 14130 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14131 enforceNotIsolatedCaller("broadcastIntent"); 14132 synchronized(this) { 14133 intent = verifyBroadcastLocked(intent); 14134 14135 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14136 final int callingPid = Binder.getCallingPid(); 14137 final int callingUid = Binder.getCallingUid(); 14138 final long origId = Binder.clearCallingIdentity(); 14139 int res = broadcastIntentLocked(callerApp, 14140 callerApp != null ? callerApp.info.packageName : null, 14141 intent, resolvedType, resultTo, 14142 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14143 callingPid, callingUid, userId); 14144 Binder.restoreCallingIdentity(origId); 14145 return res; 14146 } 14147 } 14148 14149 int broadcastIntentInPackage(String packageName, int uid, 14150 Intent intent, String resolvedType, IIntentReceiver resultTo, 14151 int resultCode, String resultData, Bundle map, 14152 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14153 synchronized(this) { 14154 intent = verifyBroadcastLocked(intent); 14155 14156 final long origId = Binder.clearCallingIdentity(); 14157 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14158 resultTo, resultCode, resultData, map, requiredPermission, 14159 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14160 Binder.restoreCallingIdentity(origId); 14161 return res; 14162 } 14163 } 14164 14165 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14166 // Refuse possible leaked file descriptors 14167 if (intent != null && intent.hasFileDescriptors() == true) { 14168 throw new IllegalArgumentException("File descriptors passed in Intent"); 14169 } 14170 14171 userId = handleIncomingUser(Binder.getCallingPid(), 14172 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14173 14174 synchronized(this) { 14175 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14176 != PackageManager.PERMISSION_GRANTED) { 14177 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14178 + Binder.getCallingPid() 14179 + ", uid=" + Binder.getCallingUid() 14180 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14181 Slog.w(TAG, msg); 14182 throw new SecurityException(msg); 14183 } 14184 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14185 if (stickies != null) { 14186 ArrayList<Intent> list = stickies.get(intent.getAction()); 14187 if (list != null) { 14188 int N = list.size(); 14189 int i; 14190 for (i=0; i<N; i++) { 14191 if (intent.filterEquals(list.get(i))) { 14192 list.remove(i); 14193 break; 14194 } 14195 } 14196 if (list.size() <= 0) { 14197 stickies.remove(intent.getAction()); 14198 } 14199 } 14200 if (stickies.size() <= 0) { 14201 mStickyBroadcasts.remove(userId); 14202 } 14203 } 14204 } 14205 } 14206 14207 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14208 String resultData, Bundle resultExtras, boolean resultAbort) { 14209 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14210 if (r == null) { 14211 Slog.w(TAG, "finishReceiver called but not found on queue"); 14212 return false; 14213 } 14214 14215 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14216 } 14217 14218 void backgroundServicesFinishedLocked(int userId) { 14219 for (BroadcastQueue queue : mBroadcastQueues) { 14220 queue.backgroundServicesFinishedLocked(userId); 14221 } 14222 } 14223 14224 public void finishReceiver(IBinder who, int resultCode, String resultData, 14225 Bundle resultExtras, boolean resultAbort) { 14226 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14227 14228 // Refuse possible leaked file descriptors 14229 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14230 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14231 } 14232 14233 final long origId = Binder.clearCallingIdentity(); 14234 try { 14235 boolean doNext = false; 14236 BroadcastRecord r; 14237 14238 synchronized(this) { 14239 r = broadcastRecordForReceiverLocked(who); 14240 if (r != null) { 14241 doNext = r.queue.finishReceiverLocked(r, resultCode, 14242 resultData, resultExtras, resultAbort, true); 14243 } 14244 } 14245 14246 if (doNext) { 14247 r.queue.processNextBroadcast(false); 14248 } 14249 trimApplications(); 14250 } finally { 14251 Binder.restoreCallingIdentity(origId); 14252 } 14253 } 14254 14255 // ========================================================= 14256 // INSTRUMENTATION 14257 // ========================================================= 14258 14259 public boolean startInstrumentation(ComponentName className, 14260 String profileFile, int flags, Bundle arguments, 14261 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14262 int userId) { 14263 enforceNotIsolatedCaller("startInstrumentation"); 14264 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14265 userId, false, true, "startInstrumentation", null); 14266 // Refuse possible leaked file descriptors 14267 if (arguments != null && arguments.hasFileDescriptors()) { 14268 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14269 } 14270 14271 synchronized(this) { 14272 InstrumentationInfo ii = null; 14273 ApplicationInfo ai = null; 14274 try { 14275 ii = mContext.getPackageManager().getInstrumentationInfo( 14276 className, STOCK_PM_FLAGS); 14277 ai = AppGlobals.getPackageManager().getApplicationInfo( 14278 ii.targetPackage, STOCK_PM_FLAGS, userId); 14279 } catch (PackageManager.NameNotFoundException e) { 14280 } catch (RemoteException e) { 14281 } 14282 if (ii == null) { 14283 reportStartInstrumentationFailure(watcher, className, 14284 "Unable to find instrumentation info for: " + className); 14285 return false; 14286 } 14287 if (ai == null) { 14288 reportStartInstrumentationFailure(watcher, className, 14289 "Unable to find instrumentation target package: " + ii.targetPackage); 14290 return false; 14291 } 14292 14293 int match = mContext.getPackageManager().checkSignatures( 14294 ii.targetPackage, ii.packageName); 14295 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14296 String msg = "Permission Denial: starting instrumentation " 14297 + className + " from pid=" 14298 + Binder.getCallingPid() 14299 + ", uid=" + Binder.getCallingPid() 14300 + " not allowed because package " + ii.packageName 14301 + " does not have a signature matching the target " 14302 + ii.targetPackage; 14303 reportStartInstrumentationFailure(watcher, className, msg); 14304 throw new SecurityException(msg); 14305 } 14306 14307 final long origId = Binder.clearCallingIdentity(); 14308 // Instrumentation can kill and relaunch even persistent processes 14309 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14310 "start instr"); 14311 ProcessRecord app = addAppLocked(ai, false); 14312 app.instrumentationClass = className; 14313 app.instrumentationInfo = ai; 14314 app.instrumentationProfileFile = profileFile; 14315 app.instrumentationArguments = arguments; 14316 app.instrumentationWatcher = watcher; 14317 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14318 app.instrumentationResultClass = className; 14319 Binder.restoreCallingIdentity(origId); 14320 } 14321 14322 return true; 14323 } 14324 14325 /** 14326 * Report errors that occur while attempting to start Instrumentation. Always writes the 14327 * error to the logs, but if somebody is watching, send the report there too. This enables 14328 * the "am" command to report errors with more information. 14329 * 14330 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14331 * @param cn The component name of the instrumentation. 14332 * @param report The error report. 14333 */ 14334 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14335 ComponentName cn, String report) { 14336 Slog.w(TAG, report); 14337 try { 14338 if (watcher != null) { 14339 Bundle results = new Bundle(); 14340 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14341 results.putString("Error", report); 14342 watcher.instrumentationStatus(cn, -1, results); 14343 } 14344 } catch (RemoteException e) { 14345 Slog.w(TAG, e); 14346 } 14347 } 14348 14349 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14350 if (app.instrumentationWatcher != null) { 14351 try { 14352 // NOTE: IInstrumentationWatcher *must* be oneway here 14353 app.instrumentationWatcher.instrumentationFinished( 14354 app.instrumentationClass, 14355 resultCode, 14356 results); 14357 } catch (RemoteException e) { 14358 } 14359 } 14360 if (app.instrumentationUiAutomationConnection != null) { 14361 try { 14362 app.instrumentationUiAutomationConnection.shutdown(); 14363 } catch (RemoteException re) { 14364 /* ignore */ 14365 } 14366 // Only a UiAutomation can set this flag and now that 14367 // it is finished we make sure it is reset to its default. 14368 mUserIsMonkey = false; 14369 } 14370 app.instrumentationWatcher = null; 14371 app.instrumentationUiAutomationConnection = null; 14372 app.instrumentationClass = null; 14373 app.instrumentationInfo = null; 14374 app.instrumentationProfileFile = null; 14375 app.instrumentationArguments = null; 14376 14377 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14378 "finished inst"); 14379 } 14380 14381 public void finishInstrumentation(IApplicationThread target, 14382 int resultCode, Bundle results) { 14383 int userId = UserHandle.getCallingUserId(); 14384 // Refuse possible leaked file descriptors 14385 if (results != null && results.hasFileDescriptors()) { 14386 throw new IllegalArgumentException("File descriptors passed in Intent"); 14387 } 14388 14389 synchronized(this) { 14390 ProcessRecord app = getRecordForAppLocked(target); 14391 if (app == null) { 14392 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14393 return; 14394 } 14395 final long origId = Binder.clearCallingIdentity(); 14396 finishInstrumentationLocked(app, resultCode, results); 14397 Binder.restoreCallingIdentity(origId); 14398 } 14399 } 14400 14401 // ========================================================= 14402 // CONFIGURATION 14403 // ========================================================= 14404 14405 public ConfigurationInfo getDeviceConfigurationInfo() { 14406 ConfigurationInfo config = new ConfigurationInfo(); 14407 synchronized (this) { 14408 config.reqTouchScreen = mConfiguration.touchscreen; 14409 config.reqKeyboardType = mConfiguration.keyboard; 14410 config.reqNavigation = mConfiguration.navigation; 14411 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14412 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14413 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14414 } 14415 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14416 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14417 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14418 } 14419 config.reqGlEsVersion = GL_ES_VERSION; 14420 } 14421 return config; 14422 } 14423 14424 ActivityStack getFocusedStack() { 14425 return mStackSupervisor.getFocusedStack(); 14426 } 14427 14428 public Configuration getConfiguration() { 14429 Configuration ci; 14430 synchronized(this) { 14431 ci = new Configuration(mConfiguration); 14432 } 14433 return ci; 14434 } 14435 14436 public void updatePersistentConfiguration(Configuration values) { 14437 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14438 "updateConfiguration()"); 14439 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14440 "updateConfiguration()"); 14441 if (values == null) { 14442 throw new NullPointerException("Configuration must not be null"); 14443 } 14444 14445 synchronized(this) { 14446 final long origId = Binder.clearCallingIdentity(); 14447 updateConfigurationLocked(values, null, true, false); 14448 Binder.restoreCallingIdentity(origId); 14449 } 14450 } 14451 14452 public void updateConfiguration(Configuration values) { 14453 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14454 "updateConfiguration()"); 14455 14456 synchronized(this) { 14457 if (values == null && mWindowManager != null) { 14458 // sentinel: fetch the current configuration from the window manager 14459 values = mWindowManager.computeNewConfiguration(); 14460 } 14461 14462 if (mWindowManager != null) { 14463 mProcessList.applyDisplaySize(mWindowManager); 14464 } 14465 14466 final long origId = Binder.clearCallingIdentity(); 14467 if (values != null) { 14468 Settings.System.clearConfiguration(values); 14469 } 14470 updateConfigurationLocked(values, null, false, false); 14471 Binder.restoreCallingIdentity(origId); 14472 } 14473 } 14474 14475 /** 14476 * Do either or both things: (1) change the current configuration, and (2) 14477 * make sure the given activity is running with the (now) current 14478 * configuration. Returns true if the activity has been left running, or 14479 * false if <var>starting</var> is being destroyed to match the new 14480 * configuration. 14481 * @param persistent TODO 14482 */ 14483 boolean updateConfigurationLocked(Configuration values, 14484 ActivityRecord starting, boolean persistent, boolean initLocale) { 14485 int changes = 0; 14486 14487 if (values != null) { 14488 Configuration newConfig = new Configuration(mConfiguration); 14489 changes = newConfig.updateFrom(values); 14490 if (changes != 0) { 14491 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14492 Slog.i(TAG, "Updating configuration to: " + values); 14493 } 14494 14495 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14496 14497 if (values.locale != null && !initLocale) { 14498 saveLocaleLocked(values.locale, 14499 !values.locale.equals(mConfiguration.locale), 14500 values.userSetLocale); 14501 } 14502 14503 mConfigurationSeq++; 14504 if (mConfigurationSeq <= 0) { 14505 mConfigurationSeq = 1; 14506 } 14507 newConfig.seq = mConfigurationSeq; 14508 mConfiguration = newConfig; 14509 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14510 mUsageStatsService.noteStartConfig(newConfig); 14511 14512 final Configuration configCopy = new Configuration(mConfiguration); 14513 14514 // TODO: If our config changes, should we auto dismiss any currently 14515 // showing dialogs? 14516 mShowDialogs = shouldShowDialogs(newConfig); 14517 14518 AttributeCache ac = AttributeCache.instance(); 14519 if (ac != null) { 14520 ac.updateConfiguration(configCopy); 14521 } 14522 14523 // Make sure all resources in our process are updated 14524 // right now, so that anyone who is going to retrieve 14525 // resource values after we return will be sure to get 14526 // the new ones. This is especially important during 14527 // boot, where the first config change needs to guarantee 14528 // all resources have that config before following boot 14529 // code is executed. 14530 mSystemThread.applyConfigurationToResources(configCopy); 14531 14532 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14533 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14534 msg.obj = new Configuration(configCopy); 14535 mHandler.sendMessage(msg); 14536 } 14537 14538 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14539 ProcessRecord app = mLruProcesses.get(i); 14540 try { 14541 if (app.thread != null) { 14542 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14543 + app.processName + " new config " + mConfiguration); 14544 app.thread.scheduleConfigurationChanged(configCopy); 14545 } 14546 } catch (Exception e) { 14547 } 14548 } 14549 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14550 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14551 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14552 | Intent.FLAG_RECEIVER_FOREGROUND); 14553 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14554 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14555 Process.SYSTEM_UID, UserHandle.USER_ALL); 14556 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14557 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14558 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14559 broadcastIntentLocked(null, null, intent, 14560 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14561 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14562 } 14563 } 14564 } 14565 14566 boolean kept = true; 14567 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14568 // mainStack is null during startup. 14569 if (mainStack != null) { 14570 if (changes != 0 && starting == null) { 14571 // If the configuration changed, and the caller is not already 14572 // in the process of starting an activity, then find the top 14573 // activity to check if its configuration needs to change. 14574 starting = mainStack.topRunningActivityLocked(null); 14575 } 14576 14577 if (starting != null) { 14578 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14579 // And we need to make sure at this point that all other activities 14580 // are made visible with the correct configuration. 14581 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14582 } 14583 } 14584 14585 if (values != null && mWindowManager != null) { 14586 mWindowManager.setNewConfiguration(mConfiguration); 14587 } 14588 14589 return kept; 14590 } 14591 14592 /** 14593 * Decide based on the configuration whether we should shouw the ANR, 14594 * crash, etc dialogs. The idea is that if there is no affordnace to 14595 * press the on-screen buttons, we shouldn't show the dialog. 14596 * 14597 * A thought: SystemUI might also want to get told about this, the Power 14598 * dialog / global actions also might want different behaviors. 14599 */ 14600 private static final boolean shouldShowDialogs(Configuration config) { 14601 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14602 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14603 } 14604 14605 /** 14606 * Save the locale. You must be inside a synchronized (this) block. 14607 */ 14608 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14609 if(isDiff) { 14610 SystemProperties.set("user.language", l.getLanguage()); 14611 SystemProperties.set("user.region", l.getCountry()); 14612 } 14613 14614 if(isPersist) { 14615 SystemProperties.set("persist.sys.language", l.getLanguage()); 14616 SystemProperties.set("persist.sys.country", l.getCountry()); 14617 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14618 } 14619 } 14620 14621 @Override 14622 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14623 ActivityRecord srec = ActivityRecord.forToken(token); 14624 return srec != null && srec.task.affinity != null && 14625 srec.task.affinity.equals(destAffinity); 14626 } 14627 14628 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14629 Intent resultData) { 14630 14631 synchronized (this) { 14632 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14633 if (stack != null) { 14634 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14635 } 14636 return false; 14637 } 14638 } 14639 14640 public int getLaunchedFromUid(IBinder activityToken) { 14641 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14642 if (srec == null) { 14643 return -1; 14644 } 14645 return srec.launchedFromUid; 14646 } 14647 14648 public String getLaunchedFromPackage(IBinder activityToken) { 14649 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14650 if (srec == null) { 14651 return null; 14652 } 14653 return srec.launchedFromPackage; 14654 } 14655 14656 // ========================================================= 14657 // LIFETIME MANAGEMENT 14658 // ========================================================= 14659 14660 // Returns which broadcast queue the app is the current [or imminent] receiver 14661 // on, or 'null' if the app is not an active broadcast recipient. 14662 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14663 BroadcastRecord r = app.curReceiver; 14664 if (r != null) { 14665 return r.queue; 14666 } 14667 14668 // It's not the current receiver, but it might be starting up to become one 14669 synchronized (this) { 14670 for (BroadcastQueue queue : mBroadcastQueues) { 14671 r = queue.mPendingBroadcast; 14672 if (r != null && r.curApp == app) { 14673 // found it; report which queue it's in 14674 return queue; 14675 } 14676 } 14677 } 14678 14679 return null; 14680 } 14681 14682 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14683 boolean doingAll, long now) { 14684 if (mAdjSeq == app.adjSeq) { 14685 // This adjustment has already been computed. 14686 return app.curRawAdj; 14687 } 14688 14689 if (app.thread == null) { 14690 app.adjSeq = mAdjSeq; 14691 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14692 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14693 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14694 } 14695 14696 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14697 app.adjSource = null; 14698 app.adjTarget = null; 14699 app.empty = false; 14700 app.cached = false; 14701 14702 final int activitiesSize = app.activities.size(); 14703 14704 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14705 // The max adjustment doesn't allow this app to be anything 14706 // below foreground, so it is not worth doing work for it. 14707 app.adjType = "fixed"; 14708 app.adjSeq = mAdjSeq; 14709 app.curRawAdj = app.maxAdj; 14710 app.foregroundActivities = false; 14711 app.keeping = true; 14712 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14713 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14714 // System processes can do UI, and when they do we want to have 14715 // them trim their memory after the user leaves the UI. To 14716 // facilitate this, here we need to determine whether or not it 14717 // is currently showing UI. 14718 app.systemNoUi = true; 14719 if (app == TOP_APP) { 14720 app.systemNoUi = false; 14721 } else if (activitiesSize > 0) { 14722 for (int j = 0; j < activitiesSize; j++) { 14723 final ActivityRecord r = app.activities.get(j); 14724 if (r.visible) { 14725 app.systemNoUi = false; 14726 } 14727 } 14728 } 14729 if (!app.systemNoUi) { 14730 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14731 } 14732 return (app.curAdj=app.maxAdj); 14733 } 14734 14735 app.keeping = false; 14736 app.systemNoUi = false; 14737 14738 // Determine the importance of the process, starting with most 14739 // important to least, and assign an appropriate OOM adjustment. 14740 int adj; 14741 int schedGroup; 14742 int procState; 14743 boolean foregroundActivities = false; 14744 boolean interesting = false; 14745 BroadcastQueue queue; 14746 if (app == TOP_APP) { 14747 // The last app on the list is the foreground app. 14748 adj = ProcessList.FOREGROUND_APP_ADJ; 14749 schedGroup = Process.THREAD_GROUP_DEFAULT; 14750 app.adjType = "top-activity"; 14751 foregroundActivities = true; 14752 interesting = true; 14753 procState = ActivityManager.PROCESS_STATE_TOP; 14754 } else if (app.instrumentationClass != null) { 14755 // Don't want to kill running instrumentation. 14756 adj = ProcessList.FOREGROUND_APP_ADJ; 14757 schedGroup = Process.THREAD_GROUP_DEFAULT; 14758 app.adjType = "instrumentation"; 14759 interesting = true; 14760 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14761 } else if ((queue = isReceivingBroadcast(app)) != null) { 14762 // An app that is currently receiving a broadcast also 14763 // counts as being in the foreground for OOM killer purposes. 14764 // It's placed in a sched group based on the nature of the 14765 // broadcast as reflected by which queue it's active in. 14766 adj = ProcessList.FOREGROUND_APP_ADJ; 14767 schedGroup = (queue == mFgBroadcastQueue) 14768 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14769 app.adjType = "broadcast"; 14770 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14771 } else if (app.executingServices.size() > 0) { 14772 // An app that is currently executing a service callback also 14773 // counts as being in the foreground. 14774 adj = ProcessList.FOREGROUND_APP_ADJ; 14775 schedGroup = app.execServicesFg ? 14776 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14777 app.adjType = "exec-service"; 14778 procState = ActivityManager.PROCESS_STATE_SERVICE; 14779 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14780 } else { 14781 // As far as we know the process is empty. We may change our mind later. 14782 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14783 // At this point we don't actually know the adjustment. Use the cached adj 14784 // value that the caller wants us to. 14785 adj = cachedAdj; 14786 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14787 app.cached = true; 14788 app.empty = true; 14789 app.adjType = "cch-empty"; 14790 } 14791 14792 // Examine all activities if not already foreground. 14793 if (!foregroundActivities && activitiesSize > 0) { 14794 for (int j = 0; j < activitiesSize; j++) { 14795 final ActivityRecord r = app.activities.get(j); 14796 if (r.app != app) { 14797 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14798 + app + "?!?"); 14799 continue; 14800 } 14801 if (r.visible) { 14802 // App has a visible activity; only upgrade adjustment. 14803 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14804 adj = ProcessList.VISIBLE_APP_ADJ; 14805 app.adjType = "visible"; 14806 } 14807 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14808 procState = ActivityManager.PROCESS_STATE_TOP; 14809 } 14810 schedGroup = Process.THREAD_GROUP_DEFAULT; 14811 app.cached = false; 14812 app.empty = false; 14813 foregroundActivities = true; 14814 break; 14815 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14816 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14817 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14818 app.adjType = "pausing"; 14819 } 14820 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14821 procState = ActivityManager.PROCESS_STATE_TOP; 14822 } 14823 schedGroup = Process.THREAD_GROUP_DEFAULT; 14824 app.cached = false; 14825 app.empty = false; 14826 foregroundActivities = true; 14827 } else if (r.state == ActivityState.STOPPING) { 14828 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14829 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14830 app.adjType = "stopping"; 14831 } 14832 // For the process state, we will at this point consider the 14833 // process to be cached. It will be cached either as an activity 14834 // or empty depending on whether the activity is finishing. We do 14835 // this so that we can treat the process as cached for purposes of 14836 // memory trimming (determing current memory level, trim command to 14837 // send to process) since there can be an arbitrary number of stopping 14838 // processes and they should soon all go into the cached state. 14839 if (!r.finishing) { 14840 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14841 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14842 } 14843 } 14844 app.cached = false; 14845 app.empty = false; 14846 foregroundActivities = true; 14847 } else { 14848 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14849 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14850 app.adjType = "cch-act"; 14851 } 14852 } 14853 } 14854 } 14855 14856 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14857 if (app.foregroundServices) { 14858 // The user is aware of this app, so make it visible. 14859 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14860 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14861 app.cached = false; 14862 app.adjType = "fg-service"; 14863 schedGroup = Process.THREAD_GROUP_DEFAULT; 14864 } else if (app.forcingToForeground != null) { 14865 // The user is aware of this app, so make it visible. 14866 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14867 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14868 app.cached = false; 14869 app.adjType = "force-fg"; 14870 app.adjSource = app.forcingToForeground; 14871 schedGroup = Process.THREAD_GROUP_DEFAULT; 14872 } 14873 } 14874 14875 if (app.foregroundServices) { 14876 interesting = true; 14877 } 14878 14879 if (app == mHeavyWeightProcess) { 14880 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14881 // We don't want to kill the current heavy-weight process. 14882 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14883 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14884 app.cached = false; 14885 app.adjType = "heavy"; 14886 } 14887 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14888 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14889 } 14890 } 14891 14892 if (app == mHomeProcess) { 14893 if (adj > ProcessList.HOME_APP_ADJ) { 14894 // This process is hosting what we currently consider to be the 14895 // home app, so we don't want to let it go into the background. 14896 adj = ProcessList.HOME_APP_ADJ; 14897 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14898 app.cached = false; 14899 app.adjType = "home"; 14900 } 14901 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14902 procState = ActivityManager.PROCESS_STATE_HOME; 14903 } 14904 } 14905 14906 if (app == mPreviousProcess && app.activities.size() > 0) { 14907 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14908 // This was the previous process that showed UI to the user. 14909 // We want to try to keep it around more aggressively, to give 14910 // a good experience around switching between two apps. 14911 adj = ProcessList.PREVIOUS_APP_ADJ; 14912 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14913 app.cached = false; 14914 app.adjType = "previous"; 14915 } 14916 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14917 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14918 } 14919 } 14920 14921 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14922 + " reason=" + app.adjType); 14923 14924 // By default, we use the computed adjustment. It may be changed if 14925 // there are applications dependent on our services or providers, but 14926 // this gives us a baseline and makes sure we don't get into an 14927 // infinite recursion. 14928 app.adjSeq = mAdjSeq; 14929 app.curRawAdj = adj; 14930 app.hasStartedServices = false; 14931 14932 if (mBackupTarget != null && app == mBackupTarget.app) { 14933 // If possible we want to avoid killing apps while they're being backed up 14934 if (adj > ProcessList.BACKUP_APP_ADJ) { 14935 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14936 adj = ProcessList.BACKUP_APP_ADJ; 14937 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14938 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14939 } 14940 app.adjType = "backup"; 14941 app.cached = false; 14942 } 14943 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14944 procState = ActivityManager.PROCESS_STATE_BACKUP; 14945 } 14946 } 14947 14948 boolean mayBeTop = false; 14949 14950 for (int is = app.services.size()-1; 14951 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14952 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14953 || procState > ActivityManager.PROCESS_STATE_TOP); 14954 is--) { 14955 ServiceRecord s = app.services.valueAt(is); 14956 if (s.startRequested) { 14957 app.hasStartedServices = true; 14958 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14959 procState = ActivityManager.PROCESS_STATE_SERVICE; 14960 } 14961 if (app.hasShownUi && app != mHomeProcess) { 14962 // If this process has shown some UI, let it immediately 14963 // go to the LRU list because it may be pretty heavy with 14964 // UI stuff. We'll tag it with a label just to help 14965 // debug and understand what is going on. 14966 if (adj > ProcessList.SERVICE_ADJ) { 14967 app.adjType = "cch-started-ui-services"; 14968 } 14969 } else { 14970 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14971 // This service has seen some activity within 14972 // recent memory, so we will keep its process ahead 14973 // of the background processes. 14974 if (adj > ProcessList.SERVICE_ADJ) { 14975 adj = ProcessList.SERVICE_ADJ; 14976 app.adjType = "started-services"; 14977 app.cached = false; 14978 } 14979 } 14980 // If we have let the service slide into the background 14981 // state, still have some text describing what it is doing 14982 // even though the service no longer has an impact. 14983 if (adj > ProcessList.SERVICE_ADJ) { 14984 app.adjType = "cch-started-services"; 14985 } 14986 } 14987 // Don't kill this process because it is doing work; it 14988 // has said it is doing work. 14989 app.keeping = true; 14990 } 14991 for (int conni = s.connections.size()-1; 14992 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14993 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14994 || procState > ActivityManager.PROCESS_STATE_TOP); 14995 conni--) { 14996 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14997 for (int i = 0; 14998 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14999 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15000 || procState > ActivityManager.PROCESS_STATE_TOP); 15001 i++) { 15002 // XXX should compute this based on the max of 15003 // all connected clients. 15004 ConnectionRecord cr = clist.get(i); 15005 if (cr.binding.client == app) { 15006 // Binding to ourself is not interesting. 15007 continue; 15008 } 15009 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 15010 ProcessRecord client = cr.binding.client; 15011 int clientAdj = computeOomAdjLocked(client, cachedAdj, 15012 TOP_APP, doingAll, now); 15013 int clientProcState = client.curProcState; 15014 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15015 // If the other app is cached for any reason, for purposes here 15016 // we are going to consider it empty. The specific cached state 15017 // doesn't propagate except under certain conditions. 15018 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15019 } 15020 String adjType = null; 15021 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 15022 // Not doing bind OOM management, so treat 15023 // this guy more like a started service. 15024 if (app.hasShownUi && app != mHomeProcess) { 15025 // If this process has shown some UI, let it immediately 15026 // go to the LRU list because it may be pretty heavy with 15027 // UI stuff. We'll tag it with a label just to help 15028 // debug and understand what is going on. 15029 if (adj > clientAdj) { 15030 adjType = "cch-bound-ui-services"; 15031 } 15032 app.cached = false; 15033 clientAdj = adj; 15034 clientProcState = procState; 15035 } else { 15036 if (now >= (s.lastActivity 15037 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15038 // This service has not seen activity within 15039 // recent memory, so allow it to drop to the 15040 // LRU list if there is no other reason to keep 15041 // it around. We'll also tag it with a label just 15042 // to help debug and undertand what is going on. 15043 if (adj > clientAdj) { 15044 adjType = "cch-bound-services"; 15045 } 15046 clientAdj = adj; 15047 } 15048 } 15049 } 15050 if (adj > clientAdj) { 15051 // If this process has recently shown UI, and 15052 // the process that is binding to it is less 15053 // important than being visible, then we don't 15054 // care about the binding as much as we care 15055 // about letting this process get into the LRU 15056 // list to be killed and restarted if needed for 15057 // memory. 15058 if (app.hasShownUi && app != mHomeProcess 15059 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15060 adjType = "cch-bound-ui-services"; 15061 } else { 15062 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15063 |Context.BIND_IMPORTANT)) != 0) { 15064 adj = clientAdj; 15065 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15066 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15067 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15068 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15069 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15070 adj = clientAdj; 15071 } else { 15072 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15073 adj = ProcessList.VISIBLE_APP_ADJ; 15074 } 15075 } 15076 if (!client.cached) { 15077 app.cached = false; 15078 } 15079 if (client.keeping) { 15080 app.keeping = true; 15081 } 15082 adjType = "service"; 15083 } 15084 } 15085 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15086 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15087 schedGroup = Process.THREAD_GROUP_DEFAULT; 15088 } 15089 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15090 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15091 // Special handling of clients who are in the top state. 15092 // We *may* want to consider this process to be in the 15093 // top state as well, but only if there is not another 15094 // reason for it to be running. Being on the top is a 15095 // special state, meaning you are specifically running 15096 // for the current top app. If the process is already 15097 // running in the background for some other reason, it 15098 // is more important to continue considering it to be 15099 // in the background state. 15100 mayBeTop = true; 15101 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15102 } else { 15103 // Special handling for above-top states (persistent 15104 // processes). These should not bring the current process 15105 // into the top state, since they are not on top. Instead 15106 // give them the best state after that. 15107 clientProcState = 15108 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15109 } 15110 } 15111 } else { 15112 if (clientProcState < 15113 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15114 clientProcState = 15115 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15116 } 15117 } 15118 if (procState > clientProcState) { 15119 procState = clientProcState; 15120 } 15121 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15122 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15123 app.pendingUiClean = true; 15124 } 15125 if (adjType != null) { 15126 app.adjType = adjType; 15127 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15128 .REASON_SERVICE_IN_USE; 15129 app.adjSource = cr.binding.client; 15130 app.adjSourceOom = clientAdj; 15131 app.adjTarget = s.name; 15132 } 15133 } 15134 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15135 app.treatLikeActivity = true; 15136 } 15137 final ActivityRecord a = cr.activity; 15138 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15139 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15140 (a.visible || a.state == ActivityState.RESUMED 15141 || a.state == ActivityState.PAUSING)) { 15142 adj = ProcessList.FOREGROUND_APP_ADJ; 15143 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15144 schedGroup = Process.THREAD_GROUP_DEFAULT; 15145 } 15146 app.cached = false; 15147 app.adjType = "service"; 15148 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15149 .REASON_SERVICE_IN_USE; 15150 app.adjSource = a; 15151 app.adjSourceOom = adj; 15152 app.adjTarget = s.name; 15153 } 15154 } 15155 } 15156 } 15157 } 15158 15159 for (int provi = app.pubProviders.size()-1; 15160 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15161 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15162 || procState > ActivityManager.PROCESS_STATE_TOP); 15163 provi--) { 15164 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15165 for (int i = cpr.connections.size()-1; 15166 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15167 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15168 || procState > ActivityManager.PROCESS_STATE_TOP); 15169 i--) { 15170 ContentProviderConnection conn = cpr.connections.get(i); 15171 ProcessRecord client = conn.client; 15172 if (client == app) { 15173 // Being our own client is not interesting. 15174 continue; 15175 } 15176 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15177 int clientProcState = client.curProcState; 15178 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15179 // If the other app is cached for any reason, for purposes here 15180 // we are going to consider it empty. 15181 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15182 } 15183 if (adj > clientAdj) { 15184 if (app.hasShownUi && app != mHomeProcess 15185 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15186 app.adjType = "cch-ui-provider"; 15187 } else { 15188 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15189 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15190 app.adjType = "provider"; 15191 } 15192 app.cached &= client.cached; 15193 app.keeping |= client.keeping; 15194 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15195 .REASON_PROVIDER_IN_USE; 15196 app.adjSource = client; 15197 app.adjSourceOom = clientAdj; 15198 app.adjTarget = cpr.name; 15199 } 15200 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15201 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15202 // Special handling of clients who are in the top state. 15203 // We *may* want to consider this process to be in the 15204 // top state as well, but only if there is not another 15205 // reason for it to be running. Being on the top is a 15206 // special state, meaning you are specifically running 15207 // for the current top app. If the process is already 15208 // running in the background for some other reason, it 15209 // is more important to continue considering it to be 15210 // in the background state. 15211 mayBeTop = true; 15212 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15213 } else { 15214 // Special handling for above-top states (persistent 15215 // processes). These should not bring the current process 15216 // into the top state, since they are not on top. Instead 15217 // give them the best state after that. 15218 clientProcState = 15219 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15220 } 15221 } 15222 if (procState > clientProcState) { 15223 procState = clientProcState; 15224 } 15225 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15226 schedGroup = Process.THREAD_GROUP_DEFAULT; 15227 } 15228 } 15229 // If the provider has external (non-framework) process 15230 // dependencies, ensure that its adjustment is at least 15231 // FOREGROUND_APP_ADJ. 15232 if (cpr.hasExternalProcessHandles()) { 15233 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15234 adj = ProcessList.FOREGROUND_APP_ADJ; 15235 schedGroup = Process.THREAD_GROUP_DEFAULT; 15236 app.cached = false; 15237 app.keeping = true; 15238 app.adjType = "provider"; 15239 app.adjTarget = cpr.name; 15240 } 15241 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15242 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15243 } 15244 } 15245 } 15246 15247 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15248 // A client of one of our services or providers is in the top state. We 15249 // *may* want to be in the top state, but not if we are already running in 15250 // the background for some other reason. For the decision here, we are going 15251 // to pick out a few specific states that we want to remain in when a client 15252 // is top (states that tend to be longer-term) and otherwise allow it to go 15253 // to the top state. 15254 switch (procState) { 15255 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15256 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15257 case ActivityManager.PROCESS_STATE_SERVICE: 15258 // These all are longer-term states, so pull them up to the top 15259 // of the background states, but not all the way to the top state. 15260 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15261 break; 15262 default: 15263 // Otherwise, top is a better choice, so take it. 15264 procState = ActivityManager.PROCESS_STATE_TOP; 15265 break; 15266 } 15267 } 15268 15269 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15270 if (app.hasClientActivities) { 15271 // This is a cached process, but with client activities. Mark it so. 15272 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15273 app.adjType = "cch-client-act"; 15274 } else if (app.treatLikeActivity) { 15275 // This is a cached process, but somebody wants us to treat it like it has 15276 // an activity, okay! 15277 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15278 app.adjType = "cch-as-act"; 15279 } 15280 } 15281 15282 if (adj == ProcessList.SERVICE_ADJ) { 15283 if (doingAll) { 15284 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15285 mNewNumServiceProcs++; 15286 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15287 if (!app.serviceb) { 15288 // This service isn't far enough down on the LRU list to 15289 // normally be a B service, but if we are low on RAM and it 15290 // is large we want to force it down since we would prefer to 15291 // keep launcher over it. 15292 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15293 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15294 app.serviceHighRam = true; 15295 app.serviceb = true; 15296 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15297 } else { 15298 mNewNumAServiceProcs++; 15299 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15300 } 15301 } else { 15302 app.serviceHighRam = false; 15303 } 15304 } 15305 if (app.serviceb) { 15306 adj = ProcessList.SERVICE_B_ADJ; 15307 } 15308 } 15309 15310 app.curRawAdj = adj; 15311 15312 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15313 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15314 if (adj > app.maxAdj) { 15315 adj = app.maxAdj; 15316 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15317 schedGroup = Process.THREAD_GROUP_DEFAULT; 15318 } 15319 } 15320 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15321 app.keeping = true; 15322 } 15323 15324 // Do final modification to adj. Everything we do between here and applying 15325 // the final setAdj must be done in this function, because we will also use 15326 // it when computing the final cached adj later. Note that we don't need to 15327 // worry about this for max adj above, since max adj will always be used to 15328 // keep it out of the cached vaues. 15329 app.curAdj = app.modifyRawOomAdj(adj); 15330 app.curSchedGroup = schedGroup; 15331 app.curProcState = procState; 15332 app.foregroundActivities = foregroundActivities; 15333 15334 return app.curRawAdj; 15335 } 15336 15337 /** 15338 * Schedule PSS collection of a process. 15339 */ 15340 void requestPssLocked(ProcessRecord proc, int procState) { 15341 if (mPendingPssProcesses.contains(proc)) { 15342 return; 15343 } 15344 if (mPendingPssProcesses.size() == 0) { 15345 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15346 } 15347 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15348 proc.pssProcState = procState; 15349 mPendingPssProcesses.add(proc); 15350 } 15351 15352 /** 15353 * Schedule PSS collection of all processes. 15354 */ 15355 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15356 if (!always) { 15357 if (now < (mLastFullPssTime + 15358 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15359 return; 15360 } 15361 } 15362 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15363 mLastFullPssTime = now; 15364 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15365 mPendingPssProcesses.clear(); 15366 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15367 ProcessRecord app = mLruProcesses.get(i); 15368 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15369 app.pssProcState = app.setProcState; 15370 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15371 isSleeping(), now); 15372 mPendingPssProcesses.add(app); 15373 } 15374 } 15375 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15376 } 15377 15378 /** 15379 * Ask a given process to GC right now. 15380 */ 15381 final void performAppGcLocked(ProcessRecord app) { 15382 try { 15383 app.lastRequestedGc = SystemClock.uptimeMillis(); 15384 if (app.thread != null) { 15385 if (app.reportLowMemory) { 15386 app.reportLowMemory = false; 15387 app.thread.scheduleLowMemory(); 15388 } else { 15389 app.thread.processInBackground(); 15390 } 15391 } 15392 } catch (Exception e) { 15393 // whatever. 15394 } 15395 } 15396 15397 /** 15398 * Returns true if things are idle enough to perform GCs. 15399 */ 15400 private final boolean canGcNowLocked() { 15401 boolean processingBroadcasts = false; 15402 for (BroadcastQueue q : mBroadcastQueues) { 15403 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15404 processingBroadcasts = true; 15405 } 15406 } 15407 return !processingBroadcasts 15408 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15409 } 15410 15411 /** 15412 * Perform GCs on all processes that are waiting for it, but only 15413 * if things are idle. 15414 */ 15415 final void performAppGcsLocked() { 15416 final int N = mProcessesToGc.size(); 15417 if (N <= 0) { 15418 return; 15419 } 15420 if (canGcNowLocked()) { 15421 while (mProcessesToGc.size() > 0) { 15422 ProcessRecord proc = mProcessesToGc.remove(0); 15423 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15424 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15425 <= SystemClock.uptimeMillis()) { 15426 // To avoid spamming the system, we will GC processes one 15427 // at a time, waiting a few seconds between each. 15428 performAppGcLocked(proc); 15429 scheduleAppGcsLocked(); 15430 return; 15431 } else { 15432 // It hasn't been long enough since we last GCed this 15433 // process... put it in the list to wait for its time. 15434 addProcessToGcListLocked(proc); 15435 break; 15436 } 15437 } 15438 } 15439 15440 scheduleAppGcsLocked(); 15441 } 15442 } 15443 15444 /** 15445 * If all looks good, perform GCs on all processes waiting for them. 15446 */ 15447 final void performAppGcsIfAppropriateLocked() { 15448 if (canGcNowLocked()) { 15449 performAppGcsLocked(); 15450 return; 15451 } 15452 // Still not idle, wait some more. 15453 scheduleAppGcsLocked(); 15454 } 15455 15456 /** 15457 * Schedule the execution of all pending app GCs. 15458 */ 15459 final void scheduleAppGcsLocked() { 15460 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15461 15462 if (mProcessesToGc.size() > 0) { 15463 // Schedule a GC for the time to the next process. 15464 ProcessRecord proc = mProcessesToGc.get(0); 15465 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15466 15467 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15468 long now = SystemClock.uptimeMillis(); 15469 if (when < (now+GC_TIMEOUT)) { 15470 when = now + GC_TIMEOUT; 15471 } 15472 mHandler.sendMessageAtTime(msg, when); 15473 } 15474 } 15475 15476 /** 15477 * Add a process to the array of processes waiting to be GCed. Keeps the 15478 * list in sorted order by the last GC time. The process can't already be 15479 * on the list. 15480 */ 15481 final void addProcessToGcListLocked(ProcessRecord proc) { 15482 boolean added = false; 15483 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15484 if (mProcessesToGc.get(i).lastRequestedGc < 15485 proc.lastRequestedGc) { 15486 added = true; 15487 mProcessesToGc.add(i+1, proc); 15488 break; 15489 } 15490 } 15491 if (!added) { 15492 mProcessesToGc.add(0, proc); 15493 } 15494 } 15495 15496 /** 15497 * Set up to ask a process to GC itself. This will either do it 15498 * immediately, or put it on the list of processes to gc the next 15499 * time things are idle. 15500 */ 15501 final void scheduleAppGcLocked(ProcessRecord app) { 15502 long now = SystemClock.uptimeMillis(); 15503 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15504 return; 15505 } 15506 if (!mProcessesToGc.contains(app)) { 15507 addProcessToGcListLocked(app); 15508 scheduleAppGcsLocked(); 15509 } 15510 } 15511 15512 final void checkExcessivePowerUsageLocked(boolean doKills) { 15513 updateCpuStatsNow(); 15514 15515 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15516 boolean doWakeKills = doKills; 15517 boolean doCpuKills = doKills; 15518 if (mLastPowerCheckRealtime == 0) { 15519 doWakeKills = false; 15520 } 15521 if (mLastPowerCheckUptime == 0) { 15522 doCpuKills = false; 15523 } 15524 if (stats.isScreenOn()) { 15525 doWakeKills = false; 15526 } 15527 final long curRealtime = SystemClock.elapsedRealtime(); 15528 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15529 final long curUptime = SystemClock.uptimeMillis(); 15530 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15531 mLastPowerCheckRealtime = curRealtime; 15532 mLastPowerCheckUptime = curUptime; 15533 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15534 doWakeKills = false; 15535 } 15536 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15537 doCpuKills = false; 15538 } 15539 int i = mLruProcesses.size(); 15540 while (i > 0) { 15541 i--; 15542 ProcessRecord app = mLruProcesses.get(i); 15543 if (!app.keeping) { 15544 long wtime; 15545 synchronized (stats) { 15546 wtime = stats.getProcessWakeTime(app.info.uid, 15547 app.pid, curRealtime); 15548 } 15549 long wtimeUsed = wtime - app.lastWakeTime; 15550 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15551 if (DEBUG_POWER) { 15552 StringBuilder sb = new StringBuilder(128); 15553 sb.append("Wake for "); 15554 app.toShortString(sb); 15555 sb.append(": over "); 15556 TimeUtils.formatDuration(realtimeSince, sb); 15557 sb.append(" used "); 15558 TimeUtils.formatDuration(wtimeUsed, sb); 15559 sb.append(" ("); 15560 sb.append((wtimeUsed*100)/realtimeSince); 15561 sb.append("%)"); 15562 Slog.i(TAG, sb.toString()); 15563 sb.setLength(0); 15564 sb.append("CPU for "); 15565 app.toShortString(sb); 15566 sb.append(": over "); 15567 TimeUtils.formatDuration(uptimeSince, sb); 15568 sb.append(" used "); 15569 TimeUtils.formatDuration(cputimeUsed, sb); 15570 sb.append(" ("); 15571 sb.append((cputimeUsed*100)/uptimeSince); 15572 sb.append("%)"); 15573 Slog.i(TAG, sb.toString()); 15574 } 15575 // If a process has held a wake lock for more 15576 // than 50% of the time during this period, 15577 // that sounds bad. Kill! 15578 if (doWakeKills && realtimeSince > 0 15579 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15580 synchronized (stats) { 15581 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15582 realtimeSince, wtimeUsed); 15583 } 15584 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15585 + " during " + realtimeSince); 15586 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15587 } else if (doCpuKills && uptimeSince > 0 15588 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15589 synchronized (stats) { 15590 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15591 uptimeSince, cputimeUsed); 15592 } 15593 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15594 + " during " + uptimeSince); 15595 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15596 } else { 15597 app.lastWakeTime = wtime; 15598 app.lastCpuTime = app.curCpuTime; 15599 } 15600 } 15601 } 15602 } 15603 15604 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15605 ProcessRecord TOP_APP, boolean doingAll, long now) { 15606 boolean success = true; 15607 15608 if (app.curRawAdj != app.setRawAdj) { 15609 if (wasKeeping && !app.keeping) { 15610 // This app is no longer something we want to keep. Note 15611 // its current wake lock time to later know to kill it if 15612 // it is not behaving well. 15613 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15614 synchronized (stats) { 15615 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15616 app.pid, SystemClock.elapsedRealtime()); 15617 } 15618 app.lastCpuTime = app.curCpuTime; 15619 } 15620 15621 app.setRawAdj = app.curRawAdj; 15622 } 15623 15624 int changes = 0; 15625 15626 if (app.curAdj != app.setAdj) { 15627 ProcessList.setOomAdj(app.pid, app.curAdj); 15628 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15629 TAG, "Set " + app.pid + " " + app.processName + 15630 " adj " + app.curAdj + ": " + app.adjType); 15631 app.setAdj = app.curAdj; 15632 } 15633 15634 if (app.setSchedGroup != app.curSchedGroup) { 15635 app.setSchedGroup = app.curSchedGroup; 15636 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15637 "Setting process group of " + app.processName 15638 + " to " + app.curSchedGroup); 15639 if (app.waitingToKill != null && 15640 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15641 killUnneededProcessLocked(app, app.waitingToKill); 15642 success = false; 15643 } else { 15644 if (true) { 15645 long oldId = Binder.clearCallingIdentity(); 15646 try { 15647 Process.setProcessGroup(app.pid, app.curSchedGroup); 15648 } catch (Exception e) { 15649 Slog.w(TAG, "Failed setting process group of " + app.pid 15650 + " to " + app.curSchedGroup); 15651 e.printStackTrace(); 15652 } finally { 15653 Binder.restoreCallingIdentity(oldId); 15654 } 15655 } else { 15656 if (app.thread != null) { 15657 try { 15658 app.thread.setSchedulingGroup(app.curSchedGroup); 15659 } catch (RemoteException e) { 15660 } 15661 } 15662 } 15663 Process.setSwappiness(app.pid, 15664 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15665 } 15666 } 15667 if (app.repForegroundActivities != app.foregroundActivities) { 15668 app.repForegroundActivities = app.foregroundActivities; 15669 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15670 } 15671 if (app.repProcState != app.curProcState) { 15672 app.repProcState = app.curProcState; 15673 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15674 if (app.thread != null) { 15675 try { 15676 if (false) { 15677 //RuntimeException h = new RuntimeException("here"); 15678 Slog.i(TAG, "Sending new process state " + app.repProcState 15679 + " to " + app /*, h*/); 15680 } 15681 app.thread.setProcessState(app.repProcState); 15682 } catch (RemoteException e) { 15683 } 15684 } 15685 } 15686 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15687 app.setProcState)) { 15688 app.lastStateTime = now; 15689 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15690 isSleeping(), now); 15691 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15692 + ProcessList.makeProcStateString(app.setProcState) + " to " 15693 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15694 + (app.nextPssTime-now) + ": " + app); 15695 } else { 15696 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15697 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15698 requestPssLocked(app, app.setProcState); 15699 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15700 isSleeping(), now); 15701 } else if (false && DEBUG_PSS) { 15702 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15703 } 15704 } 15705 if (app.setProcState != app.curProcState) { 15706 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15707 "Proc state change of " + app.processName 15708 + " to " + app.curProcState); 15709 app.setProcState = app.curProcState; 15710 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15711 app.notCachedSinceIdle = false; 15712 } 15713 if (!doingAll) { 15714 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15715 } else { 15716 app.procStateChanged = true; 15717 } 15718 } 15719 15720 if (changes != 0) { 15721 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15722 int i = mPendingProcessChanges.size()-1; 15723 ProcessChangeItem item = null; 15724 while (i >= 0) { 15725 item = mPendingProcessChanges.get(i); 15726 if (item.pid == app.pid) { 15727 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15728 break; 15729 } 15730 i--; 15731 } 15732 if (i < 0) { 15733 // No existing item in pending changes; need a new one. 15734 final int NA = mAvailProcessChanges.size(); 15735 if (NA > 0) { 15736 item = mAvailProcessChanges.remove(NA-1); 15737 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15738 } else { 15739 item = new ProcessChangeItem(); 15740 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15741 } 15742 item.changes = 0; 15743 item.pid = app.pid; 15744 item.uid = app.info.uid; 15745 if (mPendingProcessChanges.size() == 0) { 15746 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15747 "*** Enqueueing dispatch processes changed!"); 15748 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15749 } 15750 mPendingProcessChanges.add(item); 15751 } 15752 item.changes |= changes; 15753 item.processState = app.repProcState; 15754 item.foregroundActivities = app.repForegroundActivities; 15755 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15756 + Integer.toHexString(System.identityHashCode(item)) 15757 + " " + app.toShortString() + ": changes=" + item.changes 15758 + " procState=" + item.processState 15759 + " foreground=" + item.foregroundActivities 15760 + " type=" + app.adjType + " source=" + app.adjSource 15761 + " target=" + app.adjTarget); 15762 } 15763 15764 return success; 15765 } 15766 15767 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15768 if (proc.thread != null && proc.baseProcessTracker != null) { 15769 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15770 } 15771 } 15772 15773 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15774 ProcessRecord TOP_APP, boolean doingAll, long now) { 15775 if (app.thread == null) { 15776 return false; 15777 } 15778 15779 final boolean wasKeeping = app.keeping; 15780 15781 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15782 15783 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 15784 } 15785 15786 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15787 boolean oomAdj) { 15788 if (isForeground != proc.foregroundServices) { 15789 proc.foregroundServices = isForeground; 15790 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15791 proc.info.uid); 15792 if (isForeground) { 15793 if (curProcs == null) { 15794 curProcs = new ArrayList<ProcessRecord>(); 15795 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15796 } 15797 if (!curProcs.contains(proc)) { 15798 curProcs.add(proc); 15799 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15800 proc.info.packageName, proc.info.uid); 15801 } 15802 } else { 15803 if (curProcs != null) { 15804 if (curProcs.remove(proc)) { 15805 mBatteryStatsService.noteEvent( 15806 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15807 proc.info.packageName, proc.info.uid); 15808 if (curProcs.size() <= 0) { 15809 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15810 } 15811 } 15812 } 15813 } 15814 if (oomAdj) { 15815 updateOomAdjLocked(); 15816 } 15817 } 15818 } 15819 15820 private final ActivityRecord resumedAppLocked() { 15821 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15822 String pkg; 15823 int uid; 15824 if (act != null && !act.sleeping) { 15825 pkg = act.packageName; 15826 uid = act.info.applicationInfo.uid; 15827 } else { 15828 pkg = null; 15829 uid = -1; 15830 } 15831 // Has the UID or resumed package name changed? 15832 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15833 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15834 if (mCurResumedPackage != null) { 15835 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15836 mCurResumedPackage, mCurResumedUid); 15837 } 15838 mCurResumedPackage = pkg; 15839 mCurResumedUid = uid; 15840 if (mCurResumedPackage != null) { 15841 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15842 mCurResumedPackage, mCurResumedUid); 15843 } 15844 } 15845 return act; 15846 } 15847 15848 final boolean updateOomAdjLocked(ProcessRecord app) { 15849 final ActivityRecord TOP_ACT = resumedAppLocked(); 15850 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15851 final boolean wasCached = app.cached; 15852 15853 mAdjSeq++; 15854 15855 // This is the desired cached adjusment we want to tell it to use. 15856 // If our app is currently cached, we know it, and that is it. Otherwise, 15857 // we don't know it yet, and it needs to now be cached we will then 15858 // need to do a complete oom adj. 15859 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15860 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15861 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 15862 SystemClock.uptimeMillis()); 15863 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15864 // Changed to/from cached state, so apps after it in the LRU 15865 // list may also be changed. 15866 updateOomAdjLocked(); 15867 } 15868 return success; 15869 } 15870 15871 final void updateOomAdjLocked() { 15872 final ActivityRecord TOP_ACT = resumedAppLocked(); 15873 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15874 final long now = SystemClock.uptimeMillis(); 15875 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15876 final int N = mLruProcesses.size(); 15877 15878 if (false) { 15879 RuntimeException e = new RuntimeException(); 15880 e.fillInStackTrace(); 15881 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15882 } 15883 15884 mAdjSeq++; 15885 mNewNumServiceProcs = 0; 15886 mNewNumAServiceProcs = 0; 15887 15888 final int emptyProcessLimit; 15889 final int cachedProcessLimit; 15890 if (mProcessLimit <= 0) { 15891 emptyProcessLimit = cachedProcessLimit = 0; 15892 } else if (mProcessLimit == 1) { 15893 emptyProcessLimit = 1; 15894 cachedProcessLimit = 0; 15895 } else { 15896 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15897 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15898 } 15899 15900 // Let's determine how many processes we have running vs. 15901 // how many slots we have for background processes; we may want 15902 // to put multiple processes in a slot of there are enough of 15903 // them. 15904 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15905 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15906 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15907 if (numEmptyProcs > cachedProcessLimit) { 15908 // If there are more empty processes than our limit on cached 15909 // processes, then use the cached process limit for the factor. 15910 // This ensures that the really old empty processes get pushed 15911 // down to the bottom, so if we are running low on memory we will 15912 // have a better chance at keeping around more cached processes 15913 // instead of a gazillion empty processes. 15914 numEmptyProcs = cachedProcessLimit; 15915 } 15916 int emptyFactor = numEmptyProcs/numSlots; 15917 if (emptyFactor < 1) emptyFactor = 1; 15918 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15919 if (cachedFactor < 1) cachedFactor = 1; 15920 int stepCached = 0; 15921 int stepEmpty = 0; 15922 int numCached = 0; 15923 int numEmpty = 0; 15924 int numTrimming = 0; 15925 15926 mNumNonCachedProcs = 0; 15927 mNumCachedHiddenProcs = 0; 15928 15929 // First update the OOM adjustment for each of the 15930 // application processes based on their current state. 15931 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15932 int nextCachedAdj = curCachedAdj+1; 15933 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15934 int nextEmptyAdj = curEmptyAdj+2; 15935 for (int i=N-1; i>=0; i--) { 15936 ProcessRecord app = mLruProcesses.get(i); 15937 if (!app.killedByAm && app.thread != null) { 15938 app.procStateChanged = false; 15939 final boolean wasKeeping = app.keeping; 15940 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15941 15942 // If we haven't yet assigned the final cached adj 15943 // to the process, do that now. 15944 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15945 switch (app.curProcState) { 15946 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15947 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15948 // This process is a cached process holding activities... 15949 // assign it the next cached value for that type, and then 15950 // step that cached level. 15951 app.curRawAdj = curCachedAdj; 15952 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15953 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15954 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15955 + ")"); 15956 if (curCachedAdj != nextCachedAdj) { 15957 stepCached++; 15958 if (stepCached >= cachedFactor) { 15959 stepCached = 0; 15960 curCachedAdj = nextCachedAdj; 15961 nextCachedAdj += 2; 15962 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15963 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15964 } 15965 } 15966 } 15967 break; 15968 default: 15969 // For everything else, assign next empty cached process 15970 // level and bump that up. Note that this means that 15971 // long-running services that have dropped down to the 15972 // cached level will be treated as empty (since their process 15973 // state is still as a service), which is what we want. 15974 app.curRawAdj = curEmptyAdj; 15975 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15976 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15977 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15978 + ")"); 15979 if (curEmptyAdj != nextEmptyAdj) { 15980 stepEmpty++; 15981 if (stepEmpty >= emptyFactor) { 15982 stepEmpty = 0; 15983 curEmptyAdj = nextEmptyAdj; 15984 nextEmptyAdj += 2; 15985 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15986 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15987 } 15988 } 15989 } 15990 break; 15991 } 15992 } 15993 15994 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 15995 15996 // Count the number of process types. 15997 switch (app.curProcState) { 15998 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15999 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16000 mNumCachedHiddenProcs++; 16001 numCached++; 16002 if (numCached > cachedProcessLimit) { 16003 killUnneededProcessLocked(app, "cached #" + numCached); 16004 } 16005 break; 16006 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 16007 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 16008 && app.lastActivityTime < oldTime) { 16009 killUnneededProcessLocked(app, "empty for " 16010 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 16011 / 1000) + "s"); 16012 } else { 16013 numEmpty++; 16014 if (numEmpty > emptyProcessLimit) { 16015 killUnneededProcessLocked(app, "empty #" + numEmpty); 16016 } 16017 } 16018 break; 16019 default: 16020 mNumNonCachedProcs++; 16021 break; 16022 } 16023 16024 if (app.isolated && app.services.size() <= 0) { 16025 // If this is an isolated process, and there are no 16026 // services running in it, then the process is no longer 16027 // needed. We agressively kill these because we can by 16028 // definition not re-use the same process again, and it is 16029 // good to avoid having whatever code was running in them 16030 // left sitting around after no longer needed. 16031 killUnneededProcessLocked(app, "isolated not needed"); 16032 } 16033 16034 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16035 && !app.killedByAm) { 16036 numTrimming++; 16037 } 16038 } 16039 } 16040 16041 mNumServiceProcs = mNewNumServiceProcs; 16042 16043 // Now determine the memory trimming level of background processes. 16044 // Unfortunately we need to start at the back of the list to do this 16045 // properly. We only do this if the number of background apps we 16046 // are managing to keep around is less than half the maximum we desire; 16047 // if we are keeping a good number around, we'll let them use whatever 16048 // memory they want. 16049 final int numCachedAndEmpty = numCached + numEmpty; 16050 int memFactor; 16051 if (numCached <= ProcessList.TRIM_CACHED_APPS 16052 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16053 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16054 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16055 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16056 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16057 } else { 16058 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16059 } 16060 } else { 16061 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16062 } 16063 // We always allow the memory level to go up (better). We only allow it to go 16064 // down if we are in a state where that is allowed, *and* the total number of processes 16065 // has gone down since last time. 16066 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16067 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16068 + " last=" + mLastNumProcesses); 16069 if (memFactor > mLastMemoryLevel) { 16070 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16071 memFactor = mLastMemoryLevel; 16072 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16073 } 16074 } 16075 mLastMemoryLevel = memFactor; 16076 mLastNumProcesses = mLruProcesses.size(); 16077 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16078 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16079 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16080 if (mLowRamStartTime == 0) { 16081 mLowRamStartTime = now; 16082 } 16083 int step = 0; 16084 int fgTrimLevel; 16085 switch (memFactor) { 16086 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16087 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16088 break; 16089 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16090 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16091 break; 16092 default: 16093 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16094 break; 16095 } 16096 int factor = numTrimming/3; 16097 int minFactor = 2; 16098 if (mHomeProcess != null) minFactor++; 16099 if (mPreviousProcess != null) minFactor++; 16100 if (factor < minFactor) factor = minFactor; 16101 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16102 for (int i=N-1; i>=0; i--) { 16103 ProcessRecord app = mLruProcesses.get(i); 16104 if (allChanged || app.procStateChanged) { 16105 setProcessTrackerState(app, trackerMemFactor, now); 16106 app.procStateChanged = false; 16107 } 16108 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16109 && !app.killedByAm) { 16110 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16111 try { 16112 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16113 "Trimming memory of " + app.processName 16114 + " to " + curLevel); 16115 app.thread.scheduleTrimMemory(curLevel); 16116 } catch (RemoteException e) { 16117 } 16118 if (false) { 16119 // For now we won't do this; our memory trimming seems 16120 // to be good enough at this point that destroying 16121 // activities causes more harm than good. 16122 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16123 && app != mHomeProcess && app != mPreviousProcess) { 16124 // Need to do this on its own message because the stack may not 16125 // be in a consistent state at this point. 16126 // For these apps we will also finish their activities 16127 // to help them free memory. 16128 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16129 } 16130 } 16131 } 16132 app.trimMemoryLevel = curLevel; 16133 step++; 16134 if (step >= factor) { 16135 step = 0; 16136 switch (curLevel) { 16137 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16138 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16139 break; 16140 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16141 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16142 break; 16143 } 16144 } 16145 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16146 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16147 && app.thread != null) { 16148 try { 16149 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16150 "Trimming memory of heavy-weight " + app.processName 16151 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16152 app.thread.scheduleTrimMemory( 16153 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16154 } catch (RemoteException e) { 16155 } 16156 } 16157 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16158 } else { 16159 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16160 || app.systemNoUi) && app.pendingUiClean) { 16161 // If this application is now in the background and it 16162 // had done UI, then give it the special trim level to 16163 // have it free UI resources. 16164 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16165 if (app.trimMemoryLevel < level && app.thread != null) { 16166 try { 16167 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16168 "Trimming memory of bg-ui " + app.processName 16169 + " to " + level); 16170 app.thread.scheduleTrimMemory(level); 16171 } catch (RemoteException e) { 16172 } 16173 } 16174 app.pendingUiClean = false; 16175 } 16176 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16177 try { 16178 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16179 "Trimming memory of fg " + app.processName 16180 + " to " + fgTrimLevel); 16181 app.thread.scheduleTrimMemory(fgTrimLevel); 16182 } catch (RemoteException e) { 16183 } 16184 } 16185 app.trimMemoryLevel = fgTrimLevel; 16186 } 16187 } 16188 } else { 16189 if (mLowRamStartTime != 0) { 16190 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16191 mLowRamStartTime = 0; 16192 } 16193 for (int i=N-1; i>=0; i--) { 16194 ProcessRecord app = mLruProcesses.get(i); 16195 if (allChanged || app.procStateChanged) { 16196 setProcessTrackerState(app, trackerMemFactor, now); 16197 app.procStateChanged = false; 16198 } 16199 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16200 || app.systemNoUi) && app.pendingUiClean) { 16201 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16202 && app.thread != null) { 16203 try { 16204 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16205 "Trimming memory of ui hidden " + app.processName 16206 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16207 app.thread.scheduleTrimMemory( 16208 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16209 } catch (RemoteException e) { 16210 } 16211 } 16212 app.pendingUiClean = false; 16213 } 16214 app.trimMemoryLevel = 0; 16215 } 16216 } 16217 16218 if (mAlwaysFinishActivities) { 16219 // Need to do this on its own message because the stack may not 16220 // be in a consistent state at this point. 16221 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16222 } 16223 16224 if (allChanged) { 16225 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16226 } 16227 16228 if (mProcessStats.shouldWriteNowLocked(now)) { 16229 mHandler.post(new Runnable() { 16230 @Override public void run() { 16231 synchronized (ActivityManagerService.this) { 16232 mProcessStats.writeStateAsyncLocked(); 16233 } 16234 } 16235 }); 16236 } 16237 16238 if (DEBUG_OOM_ADJ) { 16239 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16240 } 16241 } 16242 16243 final void trimApplications() { 16244 synchronized (this) { 16245 int i; 16246 16247 // First remove any unused application processes whose package 16248 // has been removed. 16249 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16250 final ProcessRecord app = mRemovedProcesses.get(i); 16251 if (app.activities.size() == 0 16252 && app.curReceiver == null && app.services.size() == 0) { 16253 Slog.i( 16254 TAG, "Exiting empty application process " 16255 + app.processName + " (" 16256 + (app.thread != null ? app.thread.asBinder() : null) 16257 + ")\n"); 16258 if (app.pid > 0 && app.pid != MY_PID) { 16259 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16260 app.processName, app.setAdj, "empty"); 16261 app.killedByAm = true; 16262 Process.killProcessQuiet(app.pid); 16263 } else { 16264 try { 16265 app.thread.scheduleExit(); 16266 } catch (Exception e) { 16267 // Ignore exceptions. 16268 } 16269 } 16270 cleanUpApplicationRecordLocked(app, false, true, -1); 16271 mRemovedProcesses.remove(i); 16272 16273 if (app.persistent) { 16274 if (app.persistent) { 16275 addAppLocked(app.info, false); 16276 } 16277 } 16278 } 16279 } 16280 16281 // Now update the oom adj for all processes. 16282 updateOomAdjLocked(); 16283 } 16284 } 16285 16286 /** This method sends the specified signal to each of the persistent apps */ 16287 public void signalPersistentProcesses(int sig) throws RemoteException { 16288 if (sig != Process.SIGNAL_USR1) { 16289 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16290 } 16291 16292 synchronized (this) { 16293 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16294 != PackageManager.PERMISSION_GRANTED) { 16295 throw new SecurityException("Requires permission " 16296 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16297 } 16298 16299 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16300 ProcessRecord r = mLruProcesses.get(i); 16301 if (r.thread != null && r.persistent) { 16302 Process.sendSignal(r.pid, sig); 16303 } 16304 } 16305 } 16306 } 16307 16308 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16309 if (proc == null || proc == mProfileProc) { 16310 proc = mProfileProc; 16311 path = mProfileFile; 16312 profileType = mProfileType; 16313 clearProfilerLocked(); 16314 } 16315 if (proc == null) { 16316 return; 16317 } 16318 try { 16319 proc.thread.profilerControl(false, path, null, profileType); 16320 } catch (RemoteException e) { 16321 throw new IllegalStateException("Process disappeared"); 16322 } 16323 } 16324 16325 private void clearProfilerLocked() { 16326 if (mProfileFd != null) { 16327 try { 16328 mProfileFd.close(); 16329 } catch (IOException e) { 16330 } 16331 } 16332 mProfileApp = null; 16333 mProfileProc = null; 16334 mProfileFile = null; 16335 mProfileType = 0; 16336 mAutoStopProfiler = false; 16337 } 16338 16339 public boolean profileControl(String process, int userId, boolean start, 16340 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16341 16342 try { 16343 synchronized (this) { 16344 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16345 // its own permission. 16346 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16347 != PackageManager.PERMISSION_GRANTED) { 16348 throw new SecurityException("Requires permission " 16349 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16350 } 16351 16352 if (start && fd == null) { 16353 throw new IllegalArgumentException("null fd"); 16354 } 16355 16356 ProcessRecord proc = null; 16357 if (process != null) { 16358 proc = findProcessLocked(process, userId, "profileControl"); 16359 } 16360 16361 if (start && (proc == null || proc.thread == null)) { 16362 throw new IllegalArgumentException("Unknown process: " + process); 16363 } 16364 16365 if (start) { 16366 stopProfilerLocked(null, null, 0); 16367 setProfileApp(proc.info, proc.processName, path, fd, false); 16368 mProfileProc = proc; 16369 mProfileType = profileType; 16370 try { 16371 fd = fd.dup(); 16372 } catch (IOException e) { 16373 fd = null; 16374 } 16375 proc.thread.profilerControl(start, path, fd, profileType); 16376 fd = null; 16377 mProfileFd = null; 16378 } else { 16379 stopProfilerLocked(proc, path, profileType); 16380 if (fd != null) { 16381 try { 16382 fd.close(); 16383 } catch (IOException e) { 16384 } 16385 } 16386 } 16387 16388 return true; 16389 } 16390 } catch (RemoteException e) { 16391 throw new IllegalStateException("Process disappeared"); 16392 } finally { 16393 if (fd != null) { 16394 try { 16395 fd.close(); 16396 } catch (IOException e) { 16397 } 16398 } 16399 } 16400 } 16401 16402 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16403 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16404 userId, true, true, callName, null); 16405 ProcessRecord proc = null; 16406 try { 16407 int pid = Integer.parseInt(process); 16408 synchronized (mPidsSelfLocked) { 16409 proc = mPidsSelfLocked.get(pid); 16410 } 16411 } catch (NumberFormatException e) { 16412 } 16413 16414 if (proc == null) { 16415 ArrayMap<String, SparseArray<ProcessRecord>> all 16416 = mProcessNames.getMap(); 16417 SparseArray<ProcessRecord> procs = all.get(process); 16418 if (procs != null && procs.size() > 0) { 16419 proc = procs.valueAt(0); 16420 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16421 for (int i=1; i<procs.size(); i++) { 16422 ProcessRecord thisProc = procs.valueAt(i); 16423 if (thisProc.userId == userId) { 16424 proc = thisProc; 16425 break; 16426 } 16427 } 16428 } 16429 } 16430 } 16431 16432 return proc; 16433 } 16434 16435 public boolean dumpHeap(String process, int userId, boolean managed, 16436 String path, ParcelFileDescriptor fd) throws RemoteException { 16437 16438 try { 16439 synchronized (this) { 16440 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16441 // its own permission (same as profileControl). 16442 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16443 != PackageManager.PERMISSION_GRANTED) { 16444 throw new SecurityException("Requires permission " 16445 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16446 } 16447 16448 if (fd == null) { 16449 throw new IllegalArgumentException("null fd"); 16450 } 16451 16452 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16453 if (proc == null || proc.thread == null) { 16454 throw new IllegalArgumentException("Unknown process: " + process); 16455 } 16456 16457 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16458 if (!isDebuggable) { 16459 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16460 throw new SecurityException("Process not debuggable: " + proc); 16461 } 16462 } 16463 16464 proc.thread.dumpHeap(managed, path, fd); 16465 fd = null; 16466 return true; 16467 } 16468 } catch (RemoteException e) { 16469 throw new IllegalStateException("Process disappeared"); 16470 } finally { 16471 if (fd != null) { 16472 try { 16473 fd.close(); 16474 } catch (IOException e) { 16475 } 16476 } 16477 } 16478 } 16479 16480 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16481 public void monitor() { 16482 synchronized (this) { } 16483 } 16484 16485 void onCoreSettingsChange(Bundle settings) { 16486 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16487 ProcessRecord processRecord = mLruProcesses.get(i); 16488 try { 16489 if (processRecord.thread != null) { 16490 processRecord.thread.setCoreSettings(settings); 16491 } 16492 } catch (RemoteException re) { 16493 /* ignore */ 16494 } 16495 } 16496 } 16497 16498 // Multi-user methods 16499 16500 /** 16501 * Start user, if its not already running, but don't bring it to foreground. 16502 */ 16503 @Override 16504 public boolean startUserInBackground(final int userId) { 16505 return startUser(userId, /* foreground */ false); 16506 } 16507 16508 /** 16509 * Refreshes the list of users related to the current user when either a 16510 * user switch happens or when a new related user is started in the 16511 * background. 16512 */ 16513 private void updateCurrentProfileIdsLocked() { 16514 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16515 mCurrentUserId, false /* enabledOnly */); 16516 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16517 for (int i = 0; i < currentProfileIds.length; i++) { 16518 currentProfileIds[i] = profiles.get(i).id; 16519 } 16520 mCurrentProfileIds = currentProfileIds; 16521 } 16522 16523 private Set getProfileIdsLocked(int userId) { 16524 Set userIds = new HashSet<Integer>(); 16525 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16526 userId, false /* enabledOnly */); 16527 for (UserInfo user : profiles) { 16528 userIds.add(Integer.valueOf(user.id)); 16529 } 16530 return userIds; 16531 } 16532 16533 @Override 16534 public boolean switchUser(final int userId) { 16535 return startUser(userId, /* foregound */ true); 16536 } 16537 16538 private boolean startUser(final int userId, boolean foreground) { 16539 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16540 != PackageManager.PERMISSION_GRANTED) { 16541 String msg = "Permission Denial: switchUser() from pid=" 16542 + Binder.getCallingPid() 16543 + ", uid=" + Binder.getCallingUid() 16544 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16545 Slog.w(TAG, msg); 16546 throw new SecurityException(msg); 16547 } 16548 16549 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16550 16551 final long ident = Binder.clearCallingIdentity(); 16552 try { 16553 synchronized (this) { 16554 final int oldUserId = mCurrentUserId; 16555 if (oldUserId == userId) { 16556 return true; 16557 } 16558 16559 mStackSupervisor.setLockTaskModeLocked(null); 16560 16561 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16562 if (userInfo == null) { 16563 Slog.w(TAG, "No user info for user #" + userId); 16564 return false; 16565 } 16566 16567 if (foreground) { 16568 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16569 R.anim.screen_user_enter); 16570 } 16571 16572 boolean needStart = false; 16573 16574 // If the user we are switching to is not currently started, then 16575 // we need to start it now. 16576 if (mStartedUsers.get(userId) == null) { 16577 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16578 updateStartedUserArrayLocked(); 16579 needStart = true; 16580 } 16581 16582 final Integer userIdInt = Integer.valueOf(userId); 16583 mUserLru.remove(userIdInt); 16584 mUserLru.add(userIdInt); 16585 16586 if (foreground) { 16587 mCurrentUserId = userId; 16588 updateCurrentProfileIdsLocked(); 16589 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16590 // Once the internal notion of the active user has switched, we lock the device 16591 // with the option to show the user switcher on the keyguard. 16592 mWindowManager.lockNow(null); 16593 } else { 16594 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16595 updateCurrentProfileIdsLocked(); 16596 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16597 mUserLru.remove(currentUserIdInt); 16598 mUserLru.add(currentUserIdInt); 16599 } 16600 16601 final UserStartedState uss = mStartedUsers.get(userId); 16602 16603 // Make sure user is in the started state. If it is currently 16604 // stopping, we need to knock that off. 16605 if (uss.mState == UserStartedState.STATE_STOPPING) { 16606 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16607 // so we can just fairly silently bring the user back from 16608 // the almost-dead. 16609 uss.mState = UserStartedState.STATE_RUNNING; 16610 updateStartedUserArrayLocked(); 16611 needStart = true; 16612 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16613 // This means ACTION_SHUTDOWN has been sent, so we will 16614 // need to treat this as a new boot of the user. 16615 uss.mState = UserStartedState.STATE_BOOTING; 16616 updateStartedUserArrayLocked(); 16617 needStart = true; 16618 } 16619 16620 if (uss.mState == UserStartedState.STATE_BOOTING) { 16621 // Booting up a new user, need to tell system services about it. 16622 // Note that this is on the same handler as scheduling of broadcasts, 16623 // which is important because it needs to go first. 16624 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16625 } 16626 16627 if (foreground) { 16628 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16629 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16630 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16631 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16632 oldUserId, userId, uss)); 16633 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16634 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16635 } 16636 16637 if (needStart) { 16638 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16639 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16640 | Intent.FLAG_RECEIVER_FOREGROUND); 16641 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16642 broadcastIntentLocked(null, null, intent, 16643 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16644 false, false, MY_PID, Process.SYSTEM_UID, userId); 16645 } 16646 16647 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16648 if (userId != UserHandle.USER_OWNER) { 16649 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16650 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16651 broadcastIntentLocked(null, null, intent, null, 16652 new IIntentReceiver.Stub() { 16653 public void performReceive(Intent intent, int resultCode, 16654 String data, Bundle extras, boolean ordered, 16655 boolean sticky, int sendingUser) { 16656 userInitialized(uss, userId); 16657 } 16658 }, 0, null, null, null, AppOpsManager.OP_NONE, 16659 true, false, MY_PID, Process.SYSTEM_UID, 16660 userId); 16661 uss.initializing = true; 16662 } else { 16663 getUserManagerLocked().makeInitialized(userInfo.id); 16664 } 16665 } 16666 16667 if (foreground) { 16668 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16669 if (homeInFront) { 16670 startHomeActivityLocked(userId); 16671 } else { 16672 mStackSupervisor.resumeTopActivitiesLocked(); 16673 } 16674 EventLogTags.writeAmSwitchUser(userId); 16675 getUserManagerLocked().userForeground(userId); 16676 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16677 } else { 16678 mStackSupervisor.startBackgroundUserLocked(userId, uss); 16679 } 16680 16681 if (needStart) { 16682 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16683 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16684 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16685 broadcastIntentLocked(null, null, intent, 16686 null, new IIntentReceiver.Stub() { 16687 @Override 16688 public void performReceive(Intent intent, int resultCode, String data, 16689 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16690 throws RemoteException { 16691 } 16692 }, 0, null, null, 16693 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16694 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16695 } 16696 } 16697 } finally { 16698 Binder.restoreCallingIdentity(ident); 16699 } 16700 16701 return true; 16702 } 16703 16704 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16705 long ident = Binder.clearCallingIdentity(); 16706 try { 16707 Intent intent; 16708 if (oldUserId >= 0) { 16709 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16710 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16711 | Intent.FLAG_RECEIVER_FOREGROUND); 16712 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16713 broadcastIntentLocked(null, null, intent, 16714 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16715 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16716 } 16717 if (newUserId >= 0) { 16718 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16719 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16720 | Intent.FLAG_RECEIVER_FOREGROUND); 16721 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16722 broadcastIntentLocked(null, null, intent, 16723 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16724 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16725 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16726 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16727 | Intent.FLAG_RECEIVER_FOREGROUND); 16728 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16729 broadcastIntentLocked(null, null, intent, 16730 null, null, 0, null, null, 16731 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16732 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16733 } 16734 } finally { 16735 Binder.restoreCallingIdentity(ident); 16736 } 16737 } 16738 16739 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16740 final int newUserId) { 16741 final int N = mUserSwitchObservers.beginBroadcast(); 16742 if (N > 0) { 16743 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16744 int mCount = 0; 16745 @Override 16746 public void sendResult(Bundle data) throws RemoteException { 16747 synchronized (ActivityManagerService.this) { 16748 if (mCurUserSwitchCallback == this) { 16749 mCount++; 16750 if (mCount == N) { 16751 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16752 } 16753 } 16754 } 16755 } 16756 }; 16757 synchronized (this) { 16758 uss.switching = true; 16759 mCurUserSwitchCallback = callback; 16760 } 16761 for (int i=0; i<N; i++) { 16762 try { 16763 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16764 newUserId, callback); 16765 } catch (RemoteException e) { 16766 } 16767 } 16768 } else { 16769 synchronized (this) { 16770 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16771 } 16772 } 16773 mUserSwitchObservers.finishBroadcast(); 16774 } 16775 16776 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16777 synchronized (this) { 16778 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16779 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16780 } 16781 } 16782 16783 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16784 mCurUserSwitchCallback = null; 16785 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16786 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16787 oldUserId, newUserId, uss)); 16788 } 16789 16790 void userInitialized(UserStartedState uss, int newUserId) { 16791 completeSwitchAndInitalize(uss, newUserId, true, false); 16792 } 16793 16794 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16795 completeSwitchAndInitalize(uss, newUserId, false, true); 16796 } 16797 16798 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16799 boolean clearInitializing, boolean clearSwitching) { 16800 boolean unfrozen = false; 16801 synchronized (this) { 16802 if (clearInitializing) { 16803 uss.initializing = false; 16804 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16805 } 16806 if (clearSwitching) { 16807 uss.switching = false; 16808 } 16809 if (!uss.switching && !uss.initializing) { 16810 mWindowManager.stopFreezingScreen(); 16811 unfrozen = true; 16812 } 16813 } 16814 if (unfrozen) { 16815 final int N = mUserSwitchObservers.beginBroadcast(); 16816 for (int i=0; i<N; i++) { 16817 try { 16818 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16819 } catch (RemoteException e) { 16820 } 16821 } 16822 mUserSwitchObservers.finishBroadcast(); 16823 } 16824 } 16825 16826 void scheduleStartProfilesLocked() { 16827 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16828 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16829 DateUtils.SECOND_IN_MILLIS); 16830 } 16831 } 16832 16833 void startProfilesLocked() { 16834 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16835 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16836 mCurrentUserId, false /* enabledOnly */); 16837 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16838 for (UserInfo user : profiles) { 16839 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16840 && user.id != mCurrentUserId) { 16841 toStart.add(user); 16842 } 16843 } 16844 final int n = toStart.size(); 16845 int i = 0; 16846 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16847 startUserInBackground(toStart.get(i).id); 16848 } 16849 if (i < n) { 16850 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16851 } 16852 } 16853 16854 void finishUserBoot(UserStartedState uss) { 16855 synchronized (this) { 16856 if (uss.mState == UserStartedState.STATE_BOOTING 16857 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16858 uss.mState = UserStartedState.STATE_RUNNING; 16859 final int userId = uss.mHandle.getIdentifier(); 16860 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16861 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16862 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16863 broadcastIntentLocked(null, null, intent, 16864 null, null, 0, null, null, 16865 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16866 true, false, MY_PID, Process.SYSTEM_UID, userId); 16867 } 16868 } 16869 } 16870 16871 void finishUserSwitch(UserStartedState uss) { 16872 synchronized (this) { 16873 finishUserBoot(uss); 16874 16875 startProfilesLocked(); 16876 16877 int num = mUserLru.size(); 16878 int i = 0; 16879 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16880 Integer oldUserId = mUserLru.get(i); 16881 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16882 if (oldUss == null) { 16883 // Shouldn't happen, but be sane if it does. 16884 mUserLru.remove(i); 16885 num--; 16886 continue; 16887 } 16888 if (oldUss.mState == UserStartedState.STATE_STOPPING 16889 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16890 // This user is already stopping, doesn't count. 16891 num--; 16892 i++; 16893 continue; 16894 } 16895 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16896 // Owner and current can't be stopped, but count as running. 16897 i++; 16898 continue; 16899 } 16900 // This is a user to be stopped. 16901 stopUserLocked(oldUserId, null); 16902 num--; 16903 i++; 16904 } 16905 } 16906 } 16907 16908 @Override 16909 public int stopUser(final int userId, final IStopUserCallback callback) { 16910 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16911 != PackageManager.PERMISSION_GRANTED) { 16912 String msg = "Permission Denial: switchUser() from pid=" 16913 + Binder.getCallingPid() 16914 + ", uid=" + Binder.getCallingUid() 16915 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16916 Slog.w(TAG, msg); 16917 throw new SecurityException(msg); 16918 } 16919 if (userId <= 0) { 16920 throw new IllegalArgumentException("Can't stop primary user " + userId); 16921 } 16922 synchronized (this) { 16923 return stopUserLocked(userId, callback); 16924 } 16925 } 16926 16927 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16928 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16929 if (mCurrentUserId == userId) { 16930 return ActivityManager.USER_OP_IS_CURRENT; 16931 } 16932 16933 final UserStartedState uss = mStartedUsers.get(userId); 16934 if (uss == null) { 16935 // User is not started, nothing to do... but we do need to 16936 // callback if requested. 16937 if (callback != null) { 16938 mHandler.post(new Runnable() { 16939 @Override 16940 public void run() { 16941 try { 16942 callback.userStopped(userId); 16943 } catch (RemoteException e) { 16944 } 16945 } 16946 }); 16947 } 16948 return ActivityManager.USER_OP_SUCCESS; 16949 } 16950 16951 if (callback != null) { 16952 uss.mStopCallbacks.add(callback); 16953 } 16954 16955 if (uss.mState != UserStartedState.STATE_STOPPING 16956 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16957 uss.mState = UserStartedState.STATE_STOPPING; 16958 updateStartedUserArrayLocked(); 16959 16960 long ident = Binder.clearCallingIdentity(); 16961 try { 16962 // We are going to broadcast ACTION_USER_STOPPING and then 16963 // once that is done send a final ACTION_SHUTDOWN and then 16964 // stop the user. 16965 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16966 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16967 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16968 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16969 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16970 // This is the result receiver for the final shutdown broadcast. 16971 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16972 @Override 16973 public void performReceive(Intent intent, int resultCode, String data, 16974 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16975 finishUserStop(uss); 16976 } 16977 }; 16978 // This is the result receiver for the initial stopping broadcast. 16979 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16980 @Override 16981 public void performReceive(Intent intent, int resultCode, String data, 16982 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16983 // On to the next. 16984 synchronized (ActivityManagerService.this) { 16985 if (uss.mState != UserStartedState.STATE_STOPPING) { 16986 // Whoops, we are being started back up. Abort, abort! 16987 return; 16988 } 16989 uss.mState = UserStartedState.STATE_SHUTDOWN; 16990 } 16991 mSystemServiceManager.stopUser(userId); 16992 broadcastIntentLocked(null, null, shutdownIntent, 16993 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16994 true, false, MY_PID, Process.SYSTEM_UID, userId); 16995 } 16996 }; 16997 // Kick things off. 16998 broadcastIntentLocked(null, null, stoppingIntent, 16999 null, stoppingReceiver, 0, null, null, 17000 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17001 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17002 } finally { 17003 Binder.restoreCallingIdentity(ident); 17004 } 17005 } 17006 17007 return ActivityManager.USER_OP_SUCCESS; 17008 } 17009 17010 void finishUserStop(UserStartedState uss) { 17011 final int userId = uss.mHandle.getIdentifier(); 17012 boolean stopped; 17013 ArrayList<IStopUserCallback> callbacks; 17014 synchronized (this) { 17015 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 17016 if (mStartedUsers.get(userId) != uss) { 17017 stopped = false; 17018 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 17019 stopped = false; 17020 } else { 17021 stopped = true; 17022 // User can no longer run. 17023 mStartedUsers.remove(userId); 17024 mUserLru.remove(Integer.valueOf(userId)); 17025 updateStartedUserArrayLocked(); 17026 17027 // Clean up all state and processes associated with the user. 17028 // Kill all the processes for the user. 17029 forceStopUserLocked(userId, "finish user"); 17030 } 17031 } 17032 17033 for (int i=0; i<callbacks.size(); i++) { 17034 try { 17035 if (stopped) callbacks.get(i).userStopped(userId); 17036 else callbacks.get(i).userStopAborted(userId); 17037 } catch (RemoteException e) { 17038 } 17039 } 17040 17041 if (stopped) { 17042 mSystemServiceManager.cleanupUser(userId); 17043 synchronized (this) { 17044 mStackSupervisor.removeUserLocked(userId); 17045 } 17046 } 17047 } 17048 17049 @Override 17050 public UserInfo getCurrentUser() { 17051 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17052 != PackageManager.PERMISSION_GRANTED) && ( 17053 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17054 != PackageManager.PERMISSION_GRANTED)) { 17055 String msg = "Permission Denial: getCurrentUser() from pid=" 17056 + Binder.getCallingPid() 17057 + ", uid=" + Binder.getCallingUid() 17058 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17059 Slog.w(TAG, msg); 17060 throw new SecurityException(msg); 17061 } 17062 synchronized (this) { 17063 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17064 } 17065 } 17066 17067 int getCurrentUserIdLocked() { 17068 return mCurrentUserId; 17069 } 17070 17071 @Override 17072 public boolean isUserRunning(int userId, boolean orStopped) { 17073 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17074 != PackageManager.PERMISSION_GRANTED) { 17075 String msg = "Permission Denial: isUserRunning() from pid=" 17076 + Binder.getCallingPid() 17077 + ", uid=" + Binder.getCallingUid() 17078 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17079 Slog.w(TAG, msg); 17080 throw new SecurityException(msg); 17081 } 17082 synchronized (this) { 17083 return isUserRunningLocked(userId, orStopped); 17084 } 17085 } 17086 17087 boolean isUserRunningLocked(int userId, boolean orStopped) { 17088 UserStartedState state = mStartedUsers.get(userId); 17089 if (state == null) { 17090 return false; 17091 } 17092 if (orStopped) { 17093 return true; 17094 } 17095 return state.mState != UserStartedState.STATE_STOPPING 17096 && state.mState != UserStartedState.STATE_SHUTDOWN; 17097 } 17098 17099 @Override 17100 public int[] getRunningUserIds() { 17101 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17102 != PackageManager.PERMISSION_GRANTED) { 17103 String msg = "Permission Denial: isUserRunning() from pid=" 17104 + Binder.getCallingPid() 17105 + ", uid=" + Binder.getCallingUid() 17106 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17107 Slog.w(TAG, msg); 17108 throw new SecurityException(msg); 17109 } 17110 synchronized (this) { 17111 return mStartedUserArray; 17112 } 17113 } 17114 17115 private void updateStartedUserArrayLocked() { 17116 int num = 0; 17117 for (int i=0; i<mStartedUsers.size(); i++) { 17118 UserStartedState uss = mStartedUsers.valueAt(i); 17119 // This list does not include stopping users. 17120 if (uss.mState != UserStartedState.STATE_STOPPING 17121 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17122 num++; 17123 } 17124 } 17125 mStartedUserArray = new int[num]; 17126 num = 0; 17127 for (int i=0; i<mStartedUsers.size(); i++) { 17128 UserStartedState uss = mStartedUsers.valueAt(i); 17129 if (uss.mState != UserStartedState.STATE_STOPPING 17130 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17131 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17132 num++; 17133 } 17134 } 17135 } 17136 17137 @Override 17138 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17139 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17140 != PackageManager.PERMISSION_GRANTED) { 17141 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17142 + Binder.getCallingPid() 17143 + ", uid=" + Binder.getCallingUid() 17144 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 17145 Slog.w(TAG, msg); 17146 throw new SecurityException(msg); 17147 } 17148 17149 mUserSwitchObservers.register(observer); 17150 } 17151 17152 @Override 17153 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17154 mUserSwitchObservers.unregister(observer); 17155 } 17156 17157 private boolean userExists(int userId) { 17158 if (userId == 0) { 17159 return true; 17160 } 17161 UserManagerService ums = getUserManagerLocked(); 17162 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17163 } 17164 17165 int[] getUsersLocked() { 17166 UserManagerService ums = getUserManagerLocked(); 17167 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17168 } 17169 17170 UserManagerService getUserManagerLocked() { 17171 if (mUserManager == null) { 17172 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17173 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17174 } 17175 return mUserManager; 17176 } 17177 17178 private int applyUserId(int uid, int userId) { 17179 return UserHandle.getUid(userId, uid); 17180 } 17181 17182 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17183 if (info == null) return null; 17184 ApplicationInfo newInfo = new ApplicationInfo(info); 17185 newInfo.uid = applyUserId(info.uid, userId); 17186 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17187 + info.packageName; 17188 return newInfo; 17189 } 17190 17191 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17192 if (aInfo == null 17193 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17194 return aInfo; 17195 } 17196 17197 ActivityInfo info = new ActivityInfo(aInfo); 17198 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17199 return info; 17200 } 17201 17202 private final class LocalService extends ActivityManagerInternal { 17203 @Override 17204 public void goingToSleep() { 17205 ActivityManagerService.this.goingToSleep(); 17206 } 17207 17208 @Override 17209 public void wakingUp() { 17210 ActivityManagerService.this.wakingUp(); 17211 } 17212 } 17213 17214 /** 17215 * An implementation of IAppTask, that allows an app to manage its own tasks via 17216 * {@link android.app.ActivityManager#AppTask}. We keep track of the callingUid to ensure that 17217 * only the process that calls getAppTasks() can call the AppTask methods. 17218 */ 17219 class AppTaskImpl extends IAppTask.Stub { 17220 private int mTaskId; 17221 private int mCallingUid; 17222 17223 public AppTaskImpl(int taskId, int callingUid) { 17224 mTaskId = taskId; 17225 mCallingUid = callingUid; 17226 } 17227 17228 @Override 17229 public void finishAndRemoveTask() { 17230 // Ensure that we are called from the same process that created this AppTask 17231 if (mCallingUid != Binder.getCallingUid()) { 17232 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17233 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17234 return; 17235 } 17236 17237 synchronized (ActivityManagerService.this) { 17238 long origId = Binder.clearCallingIdentity(); 17239 try { 17240 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17241 if (tr != null) { 17242 // Only kill the process if we are not a new document 17243 int flags = tr.getBaseIntent().getFlags(); 17244 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 17245 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 17246 removeTaskByIdLocked(mTaskId, 17247 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 17248 } 17249 } finally { 17250 Binder.restoreCallingIdentity(origId); 17251 } 17252 } 17253 } 17254 17255 @Override 17256 public ActivityManager.RecentTaskInfo getTaskInfo() { 17257 // Ensure that we are called from the same process that created this AppTask 17258 if (mCallingUid != Binder.getCallingUid()) { 17259 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17260 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17261 return null; 17262 } 17263 17264 synchronized (ActivityManagerService.this) { 17265 long origId = Binder.clearCallingIdentity(); 17266 try { 17267 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17268 if (tr != null) { 17269 return createRecentTaskInfoFromTaskRecord(tr); 17270 } 17271 } finally { 17272 Binder.restoreCallingIdentity(origId); 17273 } 17274 return null; 17275 } 17276 } 17277 } 17278} 17279