ActivityManagerService.java revision dcb27fadcde2c45e14ee1658db4d16cc699ec250
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.cpuAbi; 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 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6013 return false; 6014 } 6015 6016 if (pi.applicationInfo.uid == uid) { 6017 return true; 6018 } else if (!pi.exported) { 6019 return false; 6020 } 6021 6022 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6023 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6024 try { 6025 // check if target holds top-level <provider> permissions 6026 if (!readMet && pi.readPermission != null 6027 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6028 readMet = true; 6029 } 6030 if (!writeMet && pi.writePermission != null 6031 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6032 writeMet = true; 6033 } 6034 6035 // track if unprotected read/write is allowed; any denied 6036 // <path-permission> below removes this ability 6037 boolean allowDefaultRead = pi.readPermission == null; 6038 boolean allowDefaultWrite = pi.writePermission == null; 6039 6040 // check if target holds any <path-permission> that match uri 6041 final PathPermission[] pps = pi.pathPermissions; 6042 if (pps != null) { 6043 final String path = grantUri.uri.getPath(); 6044 int i = pps.length; 6045 while (i > 0 && (!readMet || !writeMet)) { 6046 i--; 6047 PathPermission pp = pps[i]; 6048 if (pp.match(path)) { 6049 if (!readMet) { 6050 final String pprperm = pp.getReadPermission(); 6051 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6052 + pprperm + " for " + pp.getPath() 6053 + ": match=" + pp.match(path) 6054 + " check=" + pm.checkUidPermission(pprperm, uid)); 6055 if (pprperm != null) { 6056 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 6057 readMet = true; 6058 } else { 6059 allowDefaultRead = false; 6060 } 6061 } 6062 } 6063 if (!writeMet) { 6064 final String ppwperm = pp.getWritePermission(); 6065 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6066 + ppwperm + " for " + pp.getPath() 6067 + ": match=" + pp.match(path) 6068 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6069 if (ppwperm != null) { 6070 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 6071 writeMet = true; 6072 } else { 6073 allowDefaultWrite = false; 6074 } 6075 } 6076 } 6077 } 6078 } 6079 } 6080 6081 // grant unprotected <provider> read/write, if not blocked by 6082 // <path-permission> above 6083 if (allowDefaultRead) readMet = true; 6084 if (allowDefaultWrite) writeMet = true; 6085 6086 } catch (RemoteException e) { 6087 return false; 6088 } 6089 6090 return readMet && writeMet; 6091 } 6092 6093 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6094 ProviderInfo pi = null; 6095 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6096 if (cpr != null) { 6097 pi = cpr.info; 6098 } else { 6099 try { 6100 pi = AppGlobals.getPackageManager().resolveContentProvider( 6101 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6102 } catch (RemoteException ex) { 6103 } 6104 } 6105 return pi; 6106 } 6107 6108 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6109 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6110 if (targetUris != null) { 6111 return targetUris.get(grantUri); 6112 } 6113 return null; 6114 } 6115 6116 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6117 String targetPkg, int targetUid, GrantUri grantUri) { 6118 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6119 if (targetUris == null) { 6120 targetUris = Maps.newArrayMap(); 6121 mGrantedUriPermissions.put(targetUid, targetUris); 6122 } 6123 6124 UriPermission perm = targetUris.get(grantUri); 6125 if (perm == null) { 6126 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6127 targetUris.put(grantUri, perm); 6128 } 6129 6130 return perm; 6131 } 6132 6133 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6134 final int modeFlags) { 6135 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6136 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6137 : UriPermission.STRENGTH_OWNED; 6138 6139 // Root gets to do everything. 6140 if (uid == 0) { 6141 return true; 6142 } 6143 6144 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6145 if (perms == null) return false; 6146 6147 // First look for exact match 6148 final UriPermission exactPerm = perms.get(grantUri); 6149 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6150 return true; 6151 } 6152 6153 // No exact match, look for prefixes 6154 final int N = perms.size(); 6155 for (int i = 0; i < N; i++) { 6156 final UriPermission perm = perms.valueAt(i); 6157 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6158 && perm.getStrength(modeFlags) >= minStrength) { 6159 return true; 6160 } 6161 } 6162 6163 return false; 6164 } 6165 6166 @Override 6167 public int checkUriPermission(Uri uri, int pid, int uid, 6168 final int modeFlags, int userId) { 6169 enforceNotIsolatedCaller("checkUriPermission"); 6170 6171 // Another redirected-binder-call permissions check as in 6172 // {@link checkComponentPermission}. 6173 Identity tlsIdentity = sCallerIdentity.get(); 6174 if (tlsIdentity != null) { 6175 uid = tlsIdentity.uid; 6176 pid = tlsIdentity.pid; 6177 } 6178 6179 // Our own process gets to do everything. 6180 if (pid == MY_PID) { 6181 return PackageManager.PERMISSION_GRANTED; 6182 } 6183 synchronized (this) { 6184 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6185 ? PackageManager.PERMISSION_GRANTED 6186 : PackageManager.PERMISSION_DENIED; 6187 } 6188 } 6189 6190 /** 6191 * Check if the targetPkg can be granted permission to access uri by 6192 * the callingUid using the given modeFlags. Throws a security exception 6193 * if callingUid is not allowed to do this. Returns the uid of the target 6194 * if the URI permission grant should be performed; returns -1 if it is not 6195 * needed (for example targetPkg already has permission to access the URI). 6196 * If you already know the uid of the target, you can supply it in 6197 * lastTargetUid else set that to -1. 6198 */ 6199 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6200 final int modeFlags, int lastTargetUid) { 6201 if (!Intent.isAccessUriMode(modeFlags)) { 6202 return -1; 6203 } 6204 6205 if (targetPkg != null) { 6206 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6207 "Checking grant " + targetPkg + " permission to " + grantUri); 6208 } 6209 6210 final IPackageManager pm = AppGlobals.getPackageManager(); 6211 6212 // If this is not a content: uri, we can't do anything with it. 6213 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6214 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6215 "Can't grant URI permission for non-content URI: " + grantUri); 6216 return -1; 6217 } 6218 6219 final String authority = grantUri.uri.getAuthority(); 6220 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6221 if (pi == null) { 6222 Slog.w(TAG, "No content provider found for permission check: " + 6223 grantUri.uri.toSafeString()); 6224 return -1; 6225 } 6226 6227 int targetUid = lastTargetUid; 6228 if (targetUid < 0 && targetPkg != null) { 6229 try { 6230 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6231 if (targetUid < 0) { 6232 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6233 "Can't grant URI permission no uid for: " + targetPkg); 6234 return -1; 6235 } 6236 } catch (RemoteException ex) { 6237 return -1; 6238 } 6239 } 6240 6241 if (targetUid >= 0) { 6242 // First... does the target actually need this permission? 6243 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6244 // No need to grant the target this permission. 6245 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6246 "Target " + targetPkg + " already has full permission to " + grantUri); 6247 return -1; 6248 } 6249 } else { 6250 // First... there is no target package, so can anyone access it? 6251 boolean allowed = pi.exported; 6252 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6253 if (pi.readPermission != null) { 6254 allowed = false; 6255 } 6256 } 6257 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6258 if (pi.writePermission != null) { 6259 allowed = false; 6260 } 6261 } 6262 if (allowed) { 6263 return -1; 6264 } 6265 } 6266 6267 // Second... is the provider allowing granting of URI permissions? 6268 if (!pi.grantUriPermissions) { 6269 throw new SecurityException("Provider " + pi.packageName 6270 + "/" + pi.name 6271 + " does not allow granting of Uri permissions (uri " 6272 + grantUri + ")"); 6273 } 6274 if (pi.uriPermissionPatterns != null) { 6275 final int N = pi.uriPermissionPatterns.length; 6276 boolean allowed = false; 6277 for (int i=0; i<N; i++) { 6278 if (pi.uriPermissionPatterns[i] != null 6279 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6280 allowed = true; 6281 break; 6282 } 6283 } 6284 if (!allowed) { 6285 throw new SecurityException("Provider " + pi.packageName 6286 + "/" + pi.name 6287 + " does not allow granting of permission to path of Uri " 6288 + grantUri); 6289 } 6290 } 6291 6292 // Third... does the caller itself have permission to access 6293 // this uri? 6294 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6295 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6296 // Require they hold a strong enough Uri permission 6297 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6298 throw new SecurityException("Uid " + callingUid 6299 + " does not have permission to uri " + grantUri); 6300 } 6301 } 6302 } 6303 return targetUid; 6304 } 6305 6306 @Override 6307 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6308 final int modeFlags, int userId) { 6309 enforceNotIsolatedCaller("checkGrantUriPermission"); 6310 synchronized(this) { 6311 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6312 new GrantUri(userId, uri, false), modeFlags, -1); 6313 } 6314 } 6315 6316 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6317 final int modeFlags, UriPermissionOwner owner) { 6318 if (!Intent.isAccessUriMode(modeFlags)) { 6319 return; 6320 } 6321 6322 // So here we are: the caller has the assumed permission 6323 // to the uri, and the target doesn't. Let's now give this to 6324 // the target. 6325 6326 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6327 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6328 6329 final String authority = grantUri.uri.getAuthority(); 6330 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6331 if (pi == null) { 6332 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6333 return; 6334 } 6335 6336 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6337 grantUri.prefix = true; 6338 } 6339 final UriPermission perm = findOrCreateUriPermissionLocked( 6340 pi.packageName, targetPkg, targetUid, grantUri); 6341 perm.grantModes(modeFlags, owner); 6342 } 6343 6344 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6345 final int modeFlags, UriPermissionOwner owner) { 6346 if (targetPkg == null) { 6347 throw new NullPointerException("targetPkg"); 6348 } 6349 6350 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6351 -1); 6352 if (targetUid < 0) { 6353 return; 6354 } 6355 6356 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6357 owner); 6358 } 6359 6360 static class NeededUriGrants extends ArrayList<GrantUri> { 6361 final String targetPkg; 6362 final int targetUid; 6363 final int flags; 6364 6365 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6366 this.targetPkg = targetPkg; 6367 this.targetUid = targetUid; 6368 this.flags = flags; 6369 } 6370 } 6371 6372 /** 6373 * Like checkGrantUriPermissionLocked, but takes an Intent. 6374 */ 6375 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6376 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6377 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6378 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6379 + " clip=" + (intent != null ? intent.getClipData() : null) 6380 + " from " + intent + "; flags=0x" 6381 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6382 6383 if (targetPkg == null) { 6384 throw new NullPointerException("targetPkg"); 6385 } 6386 6387 if (intent == null) { 6388 return null; 6389 } 6390 Uri data = intent.getData(); 6391 ClipData clip = intent.getClipData(); 6392 if (data == null && clip == null) { 6393 return null; 6394 } 6395 6396 if (data != null) { 6397 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data); 6398 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6399 needed != null ? needed.targetUid : -1); 6400 if (targetUid > 0) { 6401 if (needed == null) { 6402 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6403 } 6404 needed.add(grantUri); 6405 } 6406 } 6407 if (clip != null) { 6408 for (int i=0; i<clip.getItemCount(); i++) { 6409 Uri uri = clip.getItemAt(i).getUri(); 6410 if (uri != null) { 6411 int targetUid = -1; 6412 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri); 6413 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6414 needed != null ? needed.targetUid : -1); 6415 if (targetUid > 0) { 6416 if (needed == null) { 6417 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6418 } 6419 needed.add(grantUri); 6420 } 6421 } else { 6422 Intent clipIntent = clip.getItemAt(i).getIntent(); 6423 if (clipIntent != null) { 6424 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6425 callingUid, targetPkg, clipIntent, mode, needed); 6426 if (newNeeded != null) { 6427 needed = newNeeded; 6428 } 6429 } 6430 } 6431 } 6432 } 6433 6434 return needed; 6435 } 6436 6437 /** 6438 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6439 */ 6440 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6441 UriPermissionOwner owner) { 6442 if (needed != null) { 6443 for (int i=0; i<needed.size(); i++) { 6444 GrantUri grantUri = needed.get(i); 6445 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6446 grantUri, needed.flags, owner); 6447 } 6448 } 6449 } 6450 6451 void grantUriPermissionFromIntentLocked(int callingUid, 6452 String targetPkg, Intent intent, UriPermissionOwner owner) { 6453 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6454 intent, intent != null ? intent.getFlags() : 0, null); 6455 if (needed == null) { 6456 return; 6457 } 6458 6459 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6460 } 6461 6462 @Override 6463 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6464 final int modeFlags, int userId) { 6465 enforceNotIsolatedCaller("grantUriPermission"); 6466 GrantUri grantUri = new GrantUri(userId, uri, false); 6467 synchronized(this) { 6468 final ProcessRecord r = getRecordForAppLocked(caller); 6469 if (r == null) { 6470 throw new SecurityException("Unable to find app for caller " 6471 + caller 6472 + " when granting permission to uri " + grantUri); 6473 } 6474 if (targetPkg == null) { 6475 throw new IllegalArgumentException("null target"); 6476 } 6477 if (grantUri == null) { 6478 throw new IllegalArgumentException("null uri"); 6479 } 6480 6481 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6482 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6483 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6484 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6485 6486 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null); 6487 } 6488 } 6489 6490 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6491 if (perm.modeFlags == 0) { 6492 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6493 perm.targetUid); 6494 if (perms != null) { 6495 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6496 "Removing " + perm.targetUid + " permission to " + perm.uri); 6497 6498 perms.remove(perm.uri); 6499 if (perms.isEmpty()) { 6500 mGrantedUriPermissions.remove(perm.targetUid); 6501 } 6502 } 6503 } 6504 } 6505 6506 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 6507 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 6508 6509 final IPackageManager pm = AppGlobals.getPackageManager(); 6510 final String authority = grantUri.uri.getAuthority(); 6511 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6512 if (pi == null) { 6513 Slog.w(TAG, "No content provider found for permission revoke: " 6514 + grantUri.toSafeString()); 6515 return; 6516 } 6517 6518 // Does the caller have this permission on the URI? 6519 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6520 // Right now, if you are not the original owner of the permission, 6521 // you are not allowed to revoke it. 6522 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6523 throw new SecurityException("Uid " + callingUid 6524 + " does not have permission to uri " + grantUri); 6525 //} 6526 } 6527 6528 boolean persistChanged = false; 6529 6530 // Go through all of the permissions and remove any that match. 6531 int N = mGrantedUriPermissions.size(); 6532 for (int i = 0; i < N; i++) { 6533 final int targetUid = mGrantedUriPermissions.keyAt(i); 6534 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6535 6536 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6537 final UriPermission perm = it.next(); 6538 if (perm.uri.sourceUserId == grantUri.sourceUserId 6539 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 6540 if (DEBUG_URI_PERMISSION) 6541 Slog.v(TAG, 6542 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6543 persistChanged |= perm.revokeModes( 6544 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6545 if (perm.modeFlags == 0) { 6546 it.remove(); 6547 } 6548 } 6549 } 6550 6551 if (perms.isEmpty()) { 6552 mGrantedUriPermissions.remove(targetUid); 6553 N--; 6554 i--; 6555 } 6556 } 6557 6558 if (persistChanged) { 6559 schedulePersistUriGrants(); 6560 } 6561 } 6562 6563 @Override 6564 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 6565 int userId) { 6566 enforceNotIsolatedCaller("revokeUriPermission"); 6567 synchronized(this) { 6568 final ProcessRecord r = getRecordForAppLocked(caller); 6569 if (r == null) { 6570 throw new SecurityException("Unable to find app for caller " 6571 + caller 6572 + " when revoking permission to uri " + uri); 6573 } 6574 if (uri == null) { 6575 Slog.w(TAG, "revokeUriPermission: null uri"); 6576 return; 6577 } 6578 6579 if (!Intent.isAccessUriMode(modeFlags)) { 6580 return; 6581 } 6582 6583 final IPackageManager pm = AppGlobals.getPackageManager(); 6584 final String authority = uri.getAuthority(); 6585 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 6586 if (pi == null) { 6587 Slog.w(TAG, "No content provider found for permission revoke: " 6588 + uri.toSafeString()); 6589 return; 6590 } 6591 6592 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 6593 } 6594 } 6595 6596 /** 6597 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6598 * given package. 6599 * 6600 * @param packageName Package name to match, or {@code null} to apply to all 6601 * packages. 6602 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6603 * to all users. 6604 * @param persistable If persistable grants should be removed. 6605 */ 6606 private void removeUriPermissionsForPackageLocked( 6607 String packageName, int userHandle, boolean persistable) { 6608 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6609 throw new IllegalArgumentException("Must narrow by either package or user"); 6610 } 6611 6612 boolean persistChanged = false; 6613 6614 int N = mGrantedUriPermissions.size(); 6615 for (int i = 0; i < N; i++) { 6616 final int targetUid = mGrantedUriPermissions.keyAt(i); 6617 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6618 6619 // Only inspect grants matching user 6620 if (userHandle == UserHandle.USER_ALL 6621 || userHandle == UserHandle.getUserId(targetUid)) { 6622 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6623 final UriPermission perm = it.next(); 6624 6625 // Only inspect grants matching package 6626 if (packageName == null || perm.sourcePkg.equals(packageName) 6627 || perm.targetPkg.equals(packageName)) { 6628 persistChanged |= perm.revokeModes( 6629 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6630 6631 // Only remove when no modes remain; any persisted grants 6632 // will keep this alive. 6633 if (perm.modeFlags == 0) { 6634 it.remove(); 6635 } 6636 } 6637 } 6638 6639 if (perms.isEmpty()) { 6640 mGrantedUriPermissions.remove(targetUid); 6641 N--; 6642 i--; 6643 } 6644 } 6645 } 6646 6647 if (persistChanged) { 6648 schedulePersistUriGrants(); 6649 } 6650 } 6651 6652 @Override 6653 public IBinder newUriPermissionOwner(String name) { 6654 enforceNotIsolatedCaller("newUriPermissionOwner"); 6655 synchronized(this) { 6656 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6657 return owner.getExternalTokenLocked(); 6658 } 6659 } 6660 6661 @Override 6662 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 6663 final int modeFlags, int userId) { 6664 synchronized(this) { 6665 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6666 if (owner == null) { 6667 throw new IllegalArgumentException("Unknown owner: " + token); 6668 } 6669 if (fromUid != Binder.getCallingUid()) { 6670 if (Binder.getCallingUid() != Process.myUid()) { 6671 // Only system code can grant URI permissions on behalf 6672 // of other users. 6673 throw new SecurityException("nice try"); 6674 } 6675 } 6676 if (targetPkg == null) { 6677 throw new IllegalArgumentException("null target"); 6678 } 6679 if (uri == null) { 6680 throw new IllegalArgumentException("null uri"); 6681 } 6682 6683 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false), 6684 modeFlags, owner); 6685 } 6686 } 6687 6688 @Override 6689 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 6690 synchronized(this) { 6691 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6692 if (owner == null) { 6693 throw new IllegalArgumentException("Unknown owner: " + token); 6694 } 6695 6696 if (uri == null) { 6697 owner.removeUriPermissionsLocked(mode); 6698 } else { 6699 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 6700 } 6701 } 6702 } 6703 6704 private void schedulePersistUriGrants() { 6705 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6706 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6707 10 * DateUtils.SECOND_IN_MILLIS); 6708 } 6709 } 6710 6711 private void writeGrantedUriPermissions() { 6712 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6713 6714 // Snapshot permissions so we can persist without lock 6715 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6716 synchronized (this) { 6717 final int size = mGrantedUriPermissions.size(); 6718 for (int i = 0; i < size; i++) { 6719 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6720 for (UriPermission perm : perms.values()) { 6721 if (perm.persistedModeFlags != 0) { 6722 persist.add(perm.snapshot()); 6723 } 6724 } 6725 } 6726 } 6727 6728 FileOutputStream fos = null; 6729 try { 6730 fos = mGrantFile.startWrite(); 6731 6732 XmlSerializer out = new FastXmlSerializer(); 6733 out.setOutput(fos, "utf-8"); 6734 out.startDocument(null, true); 6735 out.startTag(null, TAG_URI_GRANTS); 6736 for (UriPermission.Snapshot perm : persist) { 6737 out.startTag(null, TAG_URI_GRANT); 6738 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 6739 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 6740 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6741 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6742 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6743 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6744 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6745 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6746 out.endTag(null, TAG_URI_GRANT); 6747 } 6748 out.endTag(null, TAG_URI_GRANTS); 6749 out.endDocument(); 6750 6751 mGrantFile.finishWrite(fos); 6752 } catch (IOException e) { 6753 if (fos != null) { 6754 mGrantFile.failWrite(fos); 6755 } 6756 } 6757 } 6758 6759 private void readGrantedUriPermissionsLocked() { 6760 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6761 6762 final long now = System.currentTimeMillis(); 6763 6764 FileInputStream fis = null; 6765 try { 6766 fis = mGrantFile.openRead(); 6767 final XmlPullParser in = Xml.newPullParser(); 6768 in.setInput(fis, null); 6769 6770 int type; 6771 while ((type = in.next()) != END_DOCUMENT) { 6772 final String tag = in.getName(); 6773 if (type == START_TAG) { 6774 if (TAG_URI_GRANT.equals(tag)) { 6775 final int sourceUserId; 6776 final int targetUserId; 6777 final int userHandle = readIntAttribute(in, 6778 ATTR_USER_HANDLE, UserHandle.USER_NULL); 6779 if (userHandle != UserHandle.USER_NULL) { 6780 // For backwards compatibility. 6781 sourceUserId = userHandle; 6782 targetUserId = userHandle; 6783 } else { 6784 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 6785 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 6786 } 6787 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6788 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6789 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6790 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6791 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6792 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6793 6794 // Sanity check that provider still belongs to source package 6795 final ProviderInfo pi = getProviderInfoLocked( 6796 uri.getAuthority(), sourceUserId); 6797 if (pi != null && sourcePkg.equals(pi.packageName)) { 6798 int targetUid = -1; 6799 try { 6800 targetUid = AppGlobals.getPackageManager() 6801 .getPackageUid(targetPkg, targetUserId); 6802 } catch (RemoteException e) { 6803 } 6804 if (targetUid != -1) { 6805 final UriPermission perm = findOrCreateUriPermissionLocked( 6806 sourcePkg, targetPkg, targetUid, 6807 new GrantUri(sourceUserId, uri, prefix)); 6808 perm.initPersistedModes(modeFlags, createdTime); 6809 } 6810 } else { 6811 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6812 + " but instead found " + pi); 6813 } 6814 } 6815 } 6816 } 6817 } catch (FileNotFoundException e) { 6818 // Missing grants is okay 6819 } catch (IOException e) { 6820 Log.wtf(TAG, "Failed reading Uri grants", e); 6821 } catch (XmlPullParserException e) { 6822 Log.wtf(TAG, "Failed reading Uri grants", e); 6823 } finally { 6824 IoUtils.closeQuietly(fis); 6825 } 6826 } 6827 6828 @Override 6829 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6830 enforceNotIsolatedCaller("takePersistableUriPermission"); 6831 6832 Preconditions.checkFlagsArgument(modeFlags, 6833 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6834 6835 synchronized (this) { 6836 final int callingUid = Binder.getCallingUid(); 6837 boolean persistChanged = false; 6838 GrantUri grantUri = new GrantUri(userId, uri, false); 6839 6840 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6841 new GrantUri(userId, uri, false)); 6842 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6843 new GrantUri(userId, uri, true)); 6844 6845 final boolean exactValid = (exactPerm != null) 6846 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6847 final boolean prefixValid = (prefixPerm != null) 6848 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6849 6850 if (!(exactValid || prefixValid)) { 6851 throw new SecurityException("No persistable permission grants found for UID " 6852 + callingUid + " and Uri " + grantUri.toSafeString()); 6853 } 6854 6855 if (exactValid) { 6856 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6857 } 6858 if (prefixValid) { 6859 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6860 } 6861 6862 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6863 6864 if (persistChanged) { 6865 schedulePersistUriGrants(); 6866 } 6867 } 6868 } 6869 6870 @Override 6871 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6872 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6873 6874 Preconditions.checkFlagsArgument(modeFlags, 6875 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6876 6877 synchronized (this) { 6878 final int callingUid = Binder.getCallingUid(); 6879 boolean persistChanged = false; 6880 6881 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6882 new GrantUri(userId, uri, false)); 6883 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6884 new GrantUri(userId, uri, true)); 6885 if (exactPerm == null && prefixPerm == null) { 6886 throw new SecurityException("No permission grants found for UID " + callingUid 6887 + " and Uri " + uri.toSafeString()); 6888 } 6889 6890 if (exactPerm != null) { 6891 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6892 removeUriPermissionIfNeededLocked(exactPerm); 6893 } 6894 if (prefixPerm != null) { 6895 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6896 removeUriPermissionIfNeededLocked(prefixPerm); 6897 } 6898 6899 if (persistChanged) { 6900 schedulePersistUriGrants(); 6901 } 6902 } 6903 } 6904 6905 /** 6906 * Prune any older {@link UriPermission} for the given UID until outstanding 6907 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6908 * 6909 * @return if any mutations occured that require persisting. 6910 */ 6911 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6912 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6913 if (perms == null) return false; 6914 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6915 6916 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6917 for (UriPermission perm : perms.values()) { 6918 if (perm.persistedModeFlags != 0) { 6919 persisted.add(perm); 6920 } 6921 } 6922 6923 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6924 if (trimCount <= 0) return false; 6925 6926 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6927 for (int i = 0; i < trimCount; i++) { 6928 final UriPermission perm = persisted.get(i); 6929 6930 if (DEBUG_URI_PERMISSION) { 6931 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6932 } 6933 6934 perm.releasePersistableModes(~0); 6935 removeUriPermissionIfNeededLocked(perm); 6936 } 6937 6938 return true; 6939 } 6940 6941 @Override 6942 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6943 String packageName, boolean incoming) { 6944 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6945 Preconditions.checkNotNull(packageName, "packageName"); 6946 6947 final int callingUid = Binder.getCallingUid(); 6948 final IPackageManager pm = AppGlobals.getPackageManager(); 6949 try { 6950 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6951 if (packageUid != callingUid) { 6952 throw new SecurityException( 6953 "Package " + packageName + " does not belong to calling UID " + callingUid); 6954 } 6955 } catch (RemoteException e) { 6956 throw new SecurityException("Failed to verify package name ownership"); 6957 } 6958 6959 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6960 synchronized (this) { 6961 if (incoming) { 6962 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6963 callingUid); 6964 if (perms == null) { 6965 Slog.w(TAG, "No permission grants found for " + packageName); 6966 } else { 6967 for (UriPermission perm : perms.values()) { 6968 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6969 result.add(perm.buildPersistedPublicApiObject()); 6970 } 6971 } 6972 } 6973 } else { 6974 final int size = mGrantedUriPermissions.size(); 6975 for (int i = 0; i < size; i++) { 6976 final ArrayMap<GrantUri, UriPermission> perms = 6977 mGrantedUriPermissions.valueAt(i); 6978 for (UriPermission perm : perms.values()) { 6979 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6980 result.add(perm.buildPersistedPublicApiObject()); 6981 } 6982 } 6983 } 6984 } 6985 } 6986 return new ParceledListSlice<android.content.UriPermission>(result); 6987 } 6988 6989 @Override 6990 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6991 synchronized (this) { 6992 ProcessRecord app = 6993 who != null ? getRecordForAppLocked(who) : null; 6994 if (app == null) return; 6995 6996 Message msg = Message.obtain(); 6997 msg.what = WAIT_FOR_DEBUGGER_MSG; 6998 msg.obj = app; 6999 msg.arg1 = waiting ? 1 : 0; 7000 mHandler.sendMessage(msg); 7001 } 7002 } 7003 7004 @Override 7005 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7006 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7007 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7008 outInfo.availMem = Process.getFreeMemory(); 7009 outInfo.totalMem = Process.getTotalMemory(); 7010 outInfo.threshold = homeAppMem; 7011 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7012 outInfo.hiddenAppThreshold = cachedAppMem; 7013 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7014 ProcessList.SERVICE_ADJ); 7015 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7016 ProcessList.VISIBLE_APP_ADJ); 7017 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7018 ProcessList.FOREGROUND_APP_ADJ); 7019 } 7020 7021 // ========================================================= 7022 // TASK MANAGEMENT 7023 // ========================================================= 7024 7025 @Override 7026 public List<IAppTask> getAppTasks() { 7027 int callingUid = Binder.getCallingUid(); 7028 long ident = Binder.clearCallingIdentity(); 7029 synchronized(this) { 7030 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7031 try { 7032 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7033 7034 final int N = mRecentTasks.size(); 7035 for (int i = 0; i < N; i++) { 7036 TaskRecord tr = mRecentTasks.get(i); 7037 // Skip tasks that are not created by the caller 7038 if (tr.creatorUid == callingUid) { 7039 ActivityManager.RecentTaskInfo taskInfo = 7040 createRecentTaskInfoFromTaskRecord(tr); 7041 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7042 list.add(taskImpl); 7043 } 7044 } 7045 } finally { 7046 Binder.restoreCallingIdentity(ident); 7047 } 7048 return list; 7049 } 7050 } 7051 7052 @Override 7053 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7054 final int callingUid = Binder.getCallingUid(); 7055 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7056 7057 synchronized(this) { 7058 if (localLOGV) Slog.v( 7059 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7060 7061 final boolean allowed = checkCallingPermission( 7062 android.Manifest.permission.GET_TASKS) 7063 == PackageManager.PERMISSION_GRANTED; 7064 if (!allowed) { 7065 Slog.w(TAG, "getTasks: caller " + callingUid 7066 + " does not hold GET_TASKS; limiting output"); 7067 } 7068 7069 // TODO: Improve with MRU list from all ActivityStacks. 7070 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7071 } 7072 7073 return list; 7074 } 7075 7076 TaskRecord getMostRecentTask() { 7077 return mRecentTasks.get(0); 7078 } 7079 7080 /** 7081 * Creates a new RecentTaskInfo from a TaskRecord. 7082 */ 7083 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7084 ActivityManager.RecentTaskInfo rti 7085 = new ActivityManager.RecentTaskInfo(); 7086 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 7087 rti.persistentId = tr.taskId; 7088 rti.baseIntent = new Intent(tr.getBaseIntent()); 7089 rti.origActivity = tr.origActivity; 7090 rti.description = tr.lastDescription; 7091 rti.stackId = tr.stack.mStackId; 7092 rti.userId = tr.userId; 7093 7094 // Traverse upwards looking for any break between main task activities and 7095 // utility activities. 7096 final ArrayList<ActivityRecord> activities = tr.mActivities; 7097 int activityNdx; 7098 final int numActivities = activities.size(); 7099 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities; 7100 ++activityNdx) { 7101 final ActivityRecord r = activities.get(activityNdx); 7102 if (r.intent != null && 7103 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) 7104 != 0) { 7105 break; 7106 } 7107 } 7108 if (activityNdx > 0) { 7109 // Traverse downwards starting below break looking for set label, icon. 7110 // Note that if there are activities in the task but none of them set the 7111 // recent activity values, then we do not fall back to the last set 7112 // values in the TaskRecord. 7113 rti.activityValues = new ActivityManager.RecentsActivityValues(); 7114 for (--activityNdx; activityNdx >= 0; --activityNdx) { 7115 final ActivityRecord r = activities.get(activityNdx); 7116 if (r.activityValues != null) { 7117 if (rti.activityValues.label == null) { 7118 rti.activityValues.label = r.activityValues.label; 7119 tr.lastActivityValues.label = r.activityValues.label; 7120 } 7121 if (rti.activityValues.icon == null) { 7122 rti.activityValues.icon = r.activityValues.icon; 7123 tr.lastActivityValues.icon = r.activityValues.icon; 7124 } 7125 if (rti.activityValues.colorPrimary == 0) { 7126 rti.activityValues.colorPrimary = r.activityValues.colorPrimary; 7127 tr.lastActivityValues.colorPrimary = r.activityValues.colorPrimary; 7128 } 7129 } 7130 } 7131 } else { 7132 // If there are no activity records in this task, then we use the last 7133 // resolved values 7134 rti.activityValues = 7135 new ActivityManager.RecentsActivityValues(tr.lastActivityValues); 7136 } 7137 return rti; 7138 } 7139 7140 @Override 7141 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7142 int flags, int userId) { 7143 final int callingUid = Binder.getCallingUid(); 7144 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7145 false, true, "getRecentTasks", null); 7146 7147 synchronized (this) { 7148 final boolean allowed = checkCallingPermission( 7149 android.Manifest.permission.GET_TASKS) 7150 == PackageManager.PERMISSION_GRANTED; 7151 if (!allowed) { 7152 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7153 + " does not hold GET_TASKS; limiting output"); 7154 } 7155 final boolean detailed = checkCallingPermission( 7156 android.Manifest.permission.GET_DETAILED_TASKS) 7157 == PackageManager.PERMISSION_GRANTED; 7158 7159 IPackageManager pm = AppGlobals.getPackageManager(); 7160 7161 final int N = mRecentTasks.size(); 7162 ArrayList<ActivityManager.RecentTaskInfo> res 7163 = new ArrayList<ActivityManager.RecentTaskInfo>( 7164 maxNum < N ? maxNum : N); 7165 7166 final Set<Integer> includedUsers; 7167 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7168 includedUsers = getProfileIdsLocked(userId); 7169 } else { 7170 includedUsers = new HashSet<Integer>(); 7171 } 7172 includedUsers.add(Integer.valueOf(userId)); 7173 for (int i=0; i<N && maxNum > 0; i++) { 7174 TaskRecord tr = mRecentTasks.get(i); 7175 // Only add calling user or related users recent tasks 7176 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7177 7178 // Return the entry if desired by the caller. We always return 7179 // the first entry, because callers always expect this to be the 7180 // foreground app. We may filter others if the caller has 7181 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7182 // we should exclude the entry. 7183 7184 if (i == 0 7185 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7186 || (tr.intent == null) 7187 || ((tr.intent.getFlags() 7188 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7189 if (!allowed) { 7190 // If the caller doesn't have the GET_TASKS permission, then only 7191 // allow them to see a small subset of tasks -- their own and home. 7192 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7193 continue; 7194 } 7195 } 7196 7197 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7198 if (!detailed) { 7199 rti.baseIntent.replaceExtras((Bundle)null); 7200 } 7201 7202 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7203 // Check whether this activity is currently available. 7204 try { 7205 if (rti.origActivity != null) { 7206 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7207 == null) { 7208 continue; 7209 } 7210 } else if (rti.baseIntent != null) { 7211 if (pm.queryIntentActivities(rti.baseIntent, 7212 null, 0, userId) == null) { 7213 continue; 7214 } 7215 } 7216 } catch (RemoteException e) { 7217 // Will never happen. 7218 } 7219 } 7220 7221 res.add(rti); 7222 maxNum--; 7223 } 7224 } 7225 return res; 7226 } 7227 } 7228 7229 private TaskRecord recentTaskForIdLocked(int id) { 7230 final int N = mRecentTasks.size(); 7231 for (int i=0; i<N; i++) { 7232 TaskRecord tr = mRecentTasks.get(i); 7233 if (tr.taskId == id) { 7234 return tr; 7235 } 7236 } 7237 return null; 7238 } 7239 7240 @Override 7241 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7242 synchronized (this) { 7243 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7244 "getTaskThumbnails()"); 7245 TaskRecord tr = recentTaskForIdLocked(id); 7246 if (tr != null) { 7247 return tr.getTaskThumbnailsLocked(); 7248 } 7249 } 7250 return null; 7251 } 7252 7253 @Override 7254 public Bitmap getTaskTopThumbnail(int id) { 7255 synchronized (this) { 7256 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7257 "getTaskTopThumbnail()"); 7258 TaskRecord tr = recentTaskForIdLocked(id); 7259 if (tr != null) { 7260 return tr.getTaskTopThumbnailLocked(); 7261 } 7262 } 7263 return null; 7264 } 7265 7266 @Override 7267 public void setRecentsActivityValues(IBinder token, ActivityManager.RecentsActivityValues rav) { 7268 synchronized (this) { 7269 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7270 if (r != null) { 7271 r.activityValues = rav; 7272 } 7273 } 7274 } 7275 7276 @Override 7277 public boolean removeSubTask(int taskId, int subTaskIndex) { 7278 synchronized (this) { 7279 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7280 "removeSubTask()"); 7281 long ident = Binder.clearCallingIdentity(); 7282 try { 7283 TaskRecord tr = recentTaskForIdLocked(taskId); 7284 if (tr != null) { 7285 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7286 } 7287 return false; 7288 } finally { 7289 Binder.restoreCallingIdentity(ident); 7290 } 7291 } 7292 } 7293 7294 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7295 if (!pr.killedByAm) { 7296 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7297 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7298 pr.processName, pr.setAdj, reason); 7299 pr.killedByAm = true; 7300 Process.killProcessQuiet(pr.pid); 7301 } 7302 } 7303 7304 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7305 tr.disposeThumbnail(); 7306 mRecentTasks.remove(tr); 7307 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7308 Intent baseIntent = new Intent( 7309 tr.intent != null ? tr.intent : tr.affinityIntent); 7310 ComponentName component = baseIntent.getComponent(); 7311 if (component == null) { 7312 Slog.w(TAG, "Now component for base intent of task: " + tr); 7313 return; 7314 } 7315 7316 // Find any running services associated with this app. 7317 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7318 7319 if (killProcesses) { 7320 // Find any running processes associated with this app. 7321 final String pkg = component.getPackageName(); 7322 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7323 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7324 for (int i=0; i<pmap.size(); i++) { 7325 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7326 for (int j=0; j<uids.size(); j++) { 7327 ProcessRecord proc = uids.valueAt(j); 7328 if (proc.userId != tr.userId) { 7329 continue; 7330 } 7331 if (!proc.pkgList.containsKey(pkg)) { 7332 continue; 7333 } 7334 procs.add(proc); 7335 } 7336 } 7337 7338 // Kill the running processes. 7339 for (int i=0; i<procs.size(); i++) { 7340 ProcessRecord pr = procs.get(i); 7341 if (pr == mHomeProcess) { 7342 // Don't kill the home process along with tasks from the same package. 7343 continue; 7344 } 7345 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7346 killUnneededProcessLocked(pr, "remove task"); 7347 } else { 7348 pr.waitingToKill = "remove task"; 7349 } 7350 } 7351 } 7352 } 7353 7354 /** 7355 * Removes the task with the specified task id. 7356 * 7357 * @param taskId Identifier of the task to be removed. 7358 * @param flags Additional operational flags. May be 0 or 7359 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7360 * @return Returns true if the given task was found and removed. 7361 */ 7362 private boolean removeTaskByIdLocked(int taskId, int flags) { 7363 TaskRecord tr = recentTaskForIdLocked(taskId); 7364 if (tr != null) { 7365 tr.removeTaskActivitiesLocked(-1, false); 7366 cleanUpRemovedTaskLocked(tr, flags); 7367 return true; 7368 } 7369 return false; 7370 } 7371 7372 @Override 7373 public boolean removeTask(int taskId, int flags) { 7374 synchronized (this) { 7375 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7376 "removeTask()"); 7377 long ident = Binder.clearCallingIdentity(); 7378 try { 7379 return removeTaskByIdLocked(taskId, flags); 7380 } finally { 7381 Binder.restoreCallingIdentity(ident); 7382 } 7383 } 7384 } 7385 7386 /** 7387 * TODO: Add mController hook 7388 */ 7389 @Override 7390 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7391 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7392 "moveTaskToFront()"); 7393 7394 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7395 synchronized(this) { 7396 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7397 Binder.getCallingUid(), "Task to front")) { 7398 ActivityOptions.abort(options); 7399 return; 7400 } 7401 final long origId = Binder.clearCallingIdentity(); 7402 try { 7403 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7404 if (task == null) { 7405 return; 7406 } 7407 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7408 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7409 return; 7410 } 7411 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7412 } finally { 7413 Binder.restoreCallingIdentity(origId); 7414 } 7415 ActivityOptions.abort(options); 7416 } 7417 } 7418 7419 @Override 7420 public void moveTaskToBack(int taskId) { 7421 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7422 "moveTaskToBack()"); 7423 7424 synchronized(this) { 7425 TaskRecord tr = recentTaskForIdLocked(taskId); 7426 if (tr != null) { 7427 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7428 ActivityStack stack = tr.stack; 7429 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7430 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7431 Binder.getCallingUid(), "Task to back")) { 7432 return; 7433 } 7434 } 7435 final long origId = Binder.clearCallingIdentity(); 7436 try { 7437 stack.moveTaskToBackLocked(taskId, null); 7438 } finally { 7439 Binder.restoreCallingIdentity(origId); 7440 } 7441 } 7442 } 7443 } 7444 7445 /** 7446 * Moves an activity, and all of the other activities within the same task, to the bottom 7447 * of the history stack. The activity's order within the task is unchanged. 7448 * 7449 * @param token A reference to the activity we wish to move 7450 * @param nonRoot If false then this only works if the activity is the root 7451 * of a task; if true it will work for any activity in a task. 7452 * @return Returns true if the move completed, false if not. 7453 */ 7454 @Override 7455 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7456 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7457 synchronized(this) { 7458 final long origId = Binder.clearCallingIdentity(); 7459 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7460 if (taskId >= 0) { 7461 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7462 } 7463 Binder.restoreCallingIdentity(origId); 7464 } 7465 return false; 7466 } 7467 7468 @Override 7469 public void moveTaskBackwards(int task) { 7470 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7471 "moveTaskBackwards()"); 7472 7473 synchronized(this) { 7474 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7475 Binder.getCallingUid(), "Task backwards")) { 7476 return; 7477 } 7478 final long origId = Binder.clearCallingIdentity(); 7479 moveTaskBackwardsLocked(task); 7480 Binder.restoreCallingIdentity(origId); 7481 } 7482 } 7483 7484 private final void moveTaskBackwardsLocked(int task) { 7485 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7486 } 7487 7488 @Override 7489 public IBinder getHomeActivityToken() throws RemoteException { 7490 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7491 "getHomeActivityToken()"); 7492 synchronized (this) { 7493 return mStackSupervisor.getHomeActivityToken(); 7494 } 7495 } 7496 7497 @Override 7498 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7499 IActivityContainerCallback callback) throws RemoteException { 7500 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7501 "createActivityContainer()"); 7502 synchronized (this) { 7503 if (parentActivityToken == null) { 7504 throw new IllegalArgumentException("parent token must not be null"); 7505 } 7506 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7507 if (r == null) { 7508 return null; 7509 } 7510 if (callback == null) { 7511 throw new IllegalArgumentException("callback must not be null"); 7512 } 7513 return mStackSupervisor.createActivityContainer(r, callback); 7514 } 7515 } 7516 7517 @Override 7518 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7519 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7520 "deleteActivityContainer()"); 7521 synchronized (this) { 7522 mStackSupervisor.deleteActivityContainer(container); 7523 } 7524 } 7525 7526 @Override 7527 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7528 throws RemoteException { 7529 synchronized (this) { 7530 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7531 if (stack != null) { 7532 return stack.mActivityContainer; 7533 } 7534 return null; 7535 } 7536 } 7537 7538 @Override 7539 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7540 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7541 "moveTaskToStack()"); 7542 if (stackId == HOME_STACK_ID) { 7543 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7544 new RuntimeException("here").fillInStackTrace()); 7545 } 7546 synchronized (this) { 7547 long ident = Binder.clearCallingIdentity(); 7548 try { 7549 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7550 + stackId + " toTop=" + toTop); 7551 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7552 } finally { 7553 Binder.restoreCallingIdentity(ident); 7554 } 7555 } 7556 } 7557 7558 @Override 7559 public void resizeStack(int stackBoxId, Rect bounds) { 7560 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7561 "resizeStackBox()"); 7562 long ident = Binder.clearCallingIdentity(); 7563 try { 7564 mWindowManager.resizeStack(stackBoxId, bounds); 7565 } finally { 7566 Binder.restoreCallingIdentity(ident); 7567 } 7568 } 7569 7570 @Override 7571 public List<StackInfo> getAllStackInfos() { 7572 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7573 "getAllStackInfos()"); 7574 long ident = Binder.clearCallingIdentity(); 7575 try { 7576 synchronized (this) { 7577 return mStackSupervisor.getAllStackInfosLocked(); 7578 } 7579 } finally { 7580 Binder.restoreCallingIdentity(ident); 7581 } 7582 } 7583 7584 @Override 7585 public StackInfo getStackInfo(int stackId) { 7586 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7587 "getStackInfo()"); 7588 long ident = Binder.clearCallingIdentity(); 7589 try { 7590 synchronized (this) { 7591 return mStackSupervisor.getStackInfoLocked(stackId); 7592 } 7593 } finally { 7594 Binder.restoreCallingIdentity(ident); 7595 } 7596 } 7597 7598 @Override 7599 public boolean isInHomeStack(int taskId) { 7600 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7601 "getStackInfo()"); 7602 long ident = Binder.clearCallingIdentity(); 7603 try { 7604 synchronized (this) { 7605 TaskRecord tr = recentTaskForIdLocked(taskId); 7606 if (tr != null) { 7607 return tr.stack.isHomeStack(); 7608 } 7609 } 7610 } finally { 7611 Binder.restoreCallingIdentity(ident); 7612 } 7613 return false; 7614 } 7615 7616 @Override 7617 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7618 synchronized(this) { 7619 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7620 } 7621 } 7622 7623 private boolean isLockTaskAuthorized(ComponentName name) { 7624// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7625// "startLockTaskMode()"); 7626// DevicePolicyManager dpm = (DevicePolicyManager) 7627// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7628// return dpm != null && dpm.isLockTaskPermitted(name); 7629 return true; 7630 } 7631 7632 private void startLockTaskMode(TaskRecord task) { 7633 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7634 return; 7635 } 7636 long ident = Binder.clearCallingIdentity(); 7637 try { 7638 synchronized (this) { 7639 // Since we lost lock on task, make sure it is still there. 7640 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7641 if (task != null) { 7642 mStackSupervisor.setLockTaskModeLocked(task); 7643 } 7644 } 7645 } finally { 7646 Binder.restoreCallingIdentity(ident); 7647 } 7648 } 7649 7650 @Override 7651 public void startLockTaskMode(int taskId) { 7652 long ident = Binder.clearCallingIdentity(); 7653 try { 7654 final TaskRecord task; 7655 synchronized (this) { 7656 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7657 } 7658 if (task != null) { 7659 startLockTaskMode(task); 7660 } 7661 } finally { 7662 Binder.restoreCallingIdentity(ident); 7663 } 7664 } 7665 7666 @Override 7667 public void startLockTaskMode(IBinder token) { 7668 long ident = Binder.clearCallingIdentity(); 7669 try { 7670 final TaskRecord task; 7671 synchronized (this) { 7672 final ActivityRecord r = ActivityRecord.forToken(token); 7673 if (r == null) { 7674 return; 7675 } 7676 task = r.task; 7677 } 7678 if (task != null) { 7679 startLockTaskMode(task); 7680 } 7681 } finally { 7682 Binder.restoreCallingIdentity(ident); 7683 } 7684 } 7685 7686 @Override 7687 public void stopLockTaskMode() { 7688// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7689// "stopLockTaskMode()"); 7690 synchronized (this) { 7691 mStackSupervisor.setLockTaskModeLocked(null); 7692 } 7693 } 7694 7695 @Override 7696 public boolean isInLockTaskMode() { 7697 synchronized (this) { 7698 return mStackSupervisor.isInLockTaskMode(); 7699 } 7700 } 7701 7702 // ========================================================= 7703 // CONTENT PROVIDERS 7704 // ========================================================= 7705 7706 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7707 List<ProviderInfo> providers = null; 7708 try { 7709 providers = AppGlobals.getPackageManager(). 7710 queryContentProviders(app.processName, app.uid, 7711 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7712 } catch (RemoteException ex) { 7713 } 7714 if (DEBUG_MU) 7715 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7716 int userId = app.userId; 7717 if (providers != null) { 7718 int N = providers.size(); 7719 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7720 for (int i=0; i<N; i++) { 7721 ProviderInfo cpi = 7722 (ProviderInfo)providers.get(i); 7723 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7724 cpi.name, cpi.flags); 7725 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7726 // This is a singleton provider, but a user besides the 7727 // default user is asking to initialize a process it runs 7728 // in... well, no, it doesn't actually run in this process, 7729 // it runs in the process of the default user. Get rid of it. 7730 providers.remove(i); 7731 N--; 7732 i--; 7733 continue; 7734 } 7735 7736 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7737 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7738 if (cpr == null) { 7739 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7740 mProviderMap.putProviderByClass(comp, cpr); 7741 } 7742 if (DEBUG_MU) 7743 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7744 app.pubProviders.put(cpi.name, cpr); 7745 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7746 // Don't add this if it is a platform component that is marked 7747 // to run in multiple processes, because this is actually 7748 // part of the framework so doesn't make sense to track as a 7749 // separate apk in the process. 7750 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7751 } 7752 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7753 } 7754 } 7755 return providers; 7756 } 7757 7758 /** 7759 * Check if {@link ProcessRecord} has a possible chance at accessing the 7760 * given {@link ProviderInfo}. Final permission checking is always done 7761 * in {@link ContentProvider}. 7762 */ 7763 private final String checkContentProviderPermissionLocked( 7764 ProviderInfo cpi, ProcessRecord r, int userId) { 7765 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7766 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7767 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7768 // Looking for cross-user grants before to enforce the typical cross-users permissions 7769 if (userId != UserHandle.getUserId(callingUid)) { 7770 if (perms != null) { 7771 for (GrantUri grantUri : perms.keySet()) { 7772 if (grantUri.sourceUserId == userId) { 7773 String authority = grantUri.uri.getAuthority(); 7774 if (authority.equals(cpi.authority)) { 7775 return null; 7776 } 7777 } 7778 } 7779 } 7780 } 7781 userId = handleIncomingUser(callingPid, callingUid, userId, 7782 false, true, "checkContentProviderPermissionLocked", null); 7783 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7784 cpi.applicationInfo.uid, cpi.exported) 7785 == PackageManager.PERMISSION_GRANTED) { 7786 return null; 7787 } 7788 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7789 cpi.applicationInfo.uid, cpi.exported) 7790 == PackageManager.PERMISSION_GRANTED) { 7791 return null; 7792 } 7793 7794 PathPermission[] pps = cpi.pathPermissions; 7795 if (pps != null) { 7796 int i = pps.length; 7797 while (i > 0) { 7798 i--; 7799 PathPermission pp = pps[i]; 7800 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7801 cpi.applicationInfo.uid, cpi.exported) 7802 == PackageManager.PERMISSION_GRANTED) { 7803 return null; 7804 } 7805 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7806 cpi.applicationInfo.uid, cpi.exported) 7807 == PackageManager.PERMISSION_GRANTED) { 7808 return null; 7809 } 7810 } 7811 } 7812 7813 if (perms != null) { 7814 for (GrantUri grantUri : perms.keySet()) { 7815 if (grantUri.uri.getAuthority().equals(cpi.authority)) { 7816 return null; 7817 } 7818 } 7819 } 7820 7821 String msg; 7822 if (!cpi.exported) { 7823 msg = "Permission Denial: opening provider " + cpi.name 7824 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7825 + ", uid=" + callingUid + ") that is not exported from uid " 7826 + cpi.applicationInfo.uid; 7827 } else { 7828 msg = "Permission Denial: opening provider " + cpi.name 7829 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7830 + ", uid=" + callingUid + ") requires " 7831 + cpi.readPermission + " or " + cpi.writePermission; 7832 } 7833 Slog.w(TAG, msg); 7834 return msg; 7835 } 7836 7837 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7838 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7839 if (r != null) { 7840 for (int i=0; i<r.conProviders.size(); i++) { 7841 ContentProviderConnection conn = r.conProviders.get(i); 7842 if (conn.provider == cpr) { 7843 if (DEBUG_PROVIDER) Slog.v(TAG, 7844 "Adding provider requested by " 7845 + r.processName + " from process " 7846 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7847 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7848 if (stable) { 7849 conn.stableCount++; 7850 conn.numStableIncs++; 7851 } else { 7852 conn.unstableCount++; 7853 conn.numUnstableIncs++; 7854 } 7855 return conn; 7856 } 7857 } 7858 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7859 if (stable) { 7860 conn.stableCount = 1; 7861 conn.numStableIncs = 1; 7862 } else { 7863 conn.unstableCount = 1; 7864 conn.numUnstableIncs = 1; 7865 } 7866 cpr.connections.add(conn); 7867 r.conProviders.add(conn); 7868 return conn; 7869 } 7870 cpr.addExternalProcessHandleLocked(externalProcessToken); 7871 return null; 7872 } 7873 7874 boolean decProviderCountLocked(ContentProviderConnection conn, 7875 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7876 if (conn != null) { 7877 cpr = conn.provider; 7878 if (DEBUG_PROVIDER) Slog.v(TAG, 7879 "Removing provider requested by " 7880 + conn.client.processName + " from process " 7881 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7882 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7883 if (stable) { 7884 conn.stableCount--; 7885 } else { 7886 conn.unstableCount--; 7887 } 7888 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7889 cpr.connections.remove(conn); 7890 conn.client.conProviders.remove(conn); 7891 return true; 7892 } 7893 return false; 7894 } 7895 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7896 return false; 7897 } 7898 7899 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7900 String name, IBinder token, boolean stable, int userId) { 7901 ContentProviderRecord cpr; 7902 ContentProviderConnection conn = null; 7903 ProviderInfo cpi = null; 7904 7905 synchronized(this) { 7906 ProcessRecord r = null; 7907 if (caller != null) { 7908 r = getRecordForAppLocked(caller); 7909 if (r == null) { 7910 throw new SecurityException( 7911 "Unable to find app for caller " + caller 7912 + " (pid=" + Binder.getCallingPid() 7913 + ") when getting content provider " + name); 7914 } 7915 } 7916 7917 // First check if this content provider has been published... 7918 cpr = mProviderMap.getProviderByName(name, userId); 7919 boolean providerRunning = cpr != null; 7920 if (providerRunning) { 7921 cpi = cpr.info; 7922 String msg; 7923 if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) { 7924 throw new SecurityException(msg); 7925 } 7926 7927 if (r != null && cpr.canRunHere(r)) { 7928 // This provider has been published or is in the process 7929 // of being published... but it is also allowed to run 7930 // in the caller's process, so don't make a connection 7931 // and just let the caller instantiate its own instance. 7932 ContentProviderHolder holder = cpr.newHolder(null); 7933 // don't give caller the provider object, it needs 7934 // to make its own. 7935 holder.provider = null; 7936 return holder; 7937 } 7938 7939 final long origId = Binder.clearCallingIdentity(); 7940 7941 // In this case the provider instance already exists, so we can 7942 // return it right away. 7943 conn = incProviderCountLocked(r, cpr, token, stable); 7944 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7945 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7946 // If this is a perceptible app accessing the provider, 7947 // make sure to count it as being accessed and thus 7948 // back up on the LRU list. This is good because 7949 // content providers are often expensive to start. 7950 updateLruProcessLocked(cpr.proc, false, null); 7951 } 7952 } 7953 7954 if (cpr.proc != null) { 7955 if (false) { 7956 if (cpr.name.flattenToShortString().equals( 7957 "com.android.providers.calendar/.CalendarProvider2")) { 7958 Slog.v(TAG, "****************** KILLING " 7959 + cpr.name.flattenToShortString()); 7960 Process.killProcess(cpr.proc.pid); 7961 } 7962 } 7963 boolean success = updateOomAdjLocked(cpr.proc); 7964 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7965 // NOTE: there is still a race here where a signal could be 7966 // pending on the process even though we managed to update its 7967 // adj level. Not sure what to do about this, but at least 7968 // the race is now smaller. 7969 if (!success) { 7970 // Uh oh... it looks like the provider's process 7971 // has been killed on us. We need to wait for a new 7972 // process to be started, and make sure its death 7973 // doesn't kill our process. 7974 Slog.i(TAG, 7975 "Existing provider " + cpr.name.flattenToShortString() 7976 + " is crashing; detaching " + r); 7977 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7978 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7979 if (!lastRef) { 7980 // This wasn't the last ref our process had on 7981 // the provider... we have now been killed, bail. 7982 return null; 7983 } 7984 providerRunning = false; 7985 conn = null; 7986 } 7987 } 7988 7989 Binder.restoreCallingIdentity(origId); 7990 } 7991 7992 boolean singleton; 7993 if (!providerRunning) { 7994 try { 7995 cpi = AppGlobals.getPackageManager(). 7996 resolveContentProvider(name, 7997 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7998 } catch (RemoteException ex) { 7999 } 8000 if (cpi == null) { 8001 return null; 8002 } 8003 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8004 cpi.name, cpi.flags); 8005 if (singleton) { 8006 userId = 0; 8007 } 8008 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 8009 8010 String msg; 8011 if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) { 8012 throw new SecurityException(msg); 8013 } 8014 8015 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 8016 && !cpi.processName.equals("system")) { 8017 // If this content provider does not run in the system 8018 // process, and the system is not yet ready to run other 8019 // processes, then fail fast instead of hanging. 8020 throw new IllegalArgumentException( 8021 "Attempt to launch content provider before system ready"); 8022 } 8023 8024 // Make sure that the user who owns this provider is started. If not, 8025 // we don't want to allow it to run. 8026 if (mStartedUsers.get(userId) == null) { 8027 Slog.w(TAG, "Unable to launch app " 8028 + cpi.applicationInfo.packageName + "/" 8029 + cpi.applicationInfo.uid + " for provider " 8030 + name + ": user " + userId + " is stopped"); 8031 return null; 8032 } 8033 8034 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8035 cpr = mProviderMap.getProviderByClass(comp, userId); 8036 final boolean firstClass = cpr == null; 8037 if (firstClass) { 8038 try { 8039 ApplicationInfo ai = 8040 AppGlobals.getPackageManager(). 8041 getApplicationInfo( 8042 cpi.applicationInfo.packageName, 8043 STOCK_PM_FLAGS, userId); 8044 if (ai == null) { 8045 Slog.w(TAG, "No package info for content provider " 8046 + cpi.name); 8047 return null; 8048 } 8049 ai = getAppInfoForUser(ai, userId); 8050 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8051 } catch (RemoteException ex) { 8052 // pm is in same process, this will never happen. 8053 } 8054 } 8055 8056 if (r != null && cpr.canRunHere(r)) { 8057 // If this is a multiprocess provider, then just return its 8058 // info and allow the caller to instantiate it. Only do 8059 // this if the provider is the same user as the caller's 8060 // process, or can run as root (so can be in any process). 8061 return cpr.newHolder(null); 8062 } 8063 8064 if (DEBUG_PROVIDER) { 8065 RuntimeException e = new RuntimeException("here"); 8066 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8067 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8068 } 8069 8070 // This is single process, and our app is now connecting to it. 8071 // See if we are already in the process of launching this 8072 // provider. 8073 final int N = mLaunchingProviders.size(); 8074 int i; 8075 for (i=0; i<N; i++) { 8076 if (mLaunchingProviders.get(i) == cpr) { 8077 break; 8078 } 8079 } 8080 8081 // If the provider is not already being launched, then get it 8082 // started. 8083 if (i >= N) { 8084 final long origId = Binder.clearCallingIdentity(); 8085 8086 try { 8087 // Content provider is now in use, its package can't be stopped. 8088 try { 8089 AppGlobals.getPackageManager().setPackageStoppedState( 8090 cpr.appInfo.packageName, false, userId); 8091 } catch (RemoteException e) { 8092 } catch (IllegalArgumentException e) { 8093 Slog.w(TAG, "Failed trying to unstop package " 8094 + cpr.appInfo.packageName + ": " + e); 8095 } 8096 8097 // Use existing process if already started 8098 ProcessRecord proc = getProcessRecordLocked( 8099 cpi.processName, cpr.appInfo.uid, false); 8100 if (proc != null && proc.thread != null) { 8101 if (DEBUG_PROVIDER) { 8102 Slog.d(TAG, "Installing in existing process " + proc); 8103 } 8104 proc.pubProviders.put(cpi.name, cpr); 8105 try { 8106 proc.thread.scheduleInstallProvider(cpi); 8107 } catch (RemoteException e) { 8108 } 8109 } else { 8110 proc = startProcessLocked(cpi.processName, 8111 cpr.appInfo, false, 0, "content provider", 8112 new ComponentName(cpi.applicationInfo.packageName, 8113 cpi.name), false, false, false); 8114 if (proc == null) { 8115 Slog.w(TAG, "Unable to launch app " 8116 + cpi.applicationInfo.packageName + "/" 8117 + cpi.applicationInfo.uid + " for provider " 8118 + name + ": process is bad"); 8119 return null; 8120 } 8121 } 8122 cpr.launchingApp = proc; 8123 mLaunchingProviders.add(cpr); 8124 } finally { 8125 Binder.restoreCallingIdentity(origId); 8126 } 8127 } 8128 8129 // Make sure the provider is published (the same provider class 8130 // may be published under multiple names). 8131 if (firstClass) { 8132 mProviderMap.putProviderByClass(comp, cpr); 8133 } 8134 8135 mProviderMap.putProviderByName(name, cpr); 8136 conn = incProviderCountLocked(r, cpr, token, stable); 8137 if (conn != null) { 8138 conn.waiting = true; 8139 } 8140 } 8141 } 8142 8143 // Wait for the provider to be published... 8144 synchronized (cpr) { 8145 while (cpr.provider == null) { 8146 if (cpr.launchingApp == null) { 8147 Slog.w(TAG, "Unable to launch app " 8148 + cpi.applicationInfo.packageName + "/" 8149 + cpi.applicationInfo.uid + " for provider " 8150 + name + ": launching app became null"); 8151 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8152 UserHandle.getUserId(cpi.applicationInfo.uid), 8153 cpi.applicationInfo.packageName, 8154 cpi.applicationInfo.uid, name); 8155 return null; 8156 } 8157 try { 8158 if (DEBUG_MU) { 8159 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8160 + cpr.launchingApp); 8161 } 8162 if (conn != null) { 8163 conn.waiting = true; 8164 } 8165 cpr.wait(); 8166 } catch (InterruptedException ex) { 8167 } finally { 8168 if (conn != null) { 8169 conn.waiting = false; 8170 } 8171 } 8172 } 8173 } 8174 return cpr != null ? cpr.newHolder(conn) : null; 8175 } 8176 8177 @Override 8178 public final ContentProviderHolder getContentProvider( 8179 IApplicationThread caller, String name, int userId, boolean stable) { 8180 enforceNotIsolatedCaller("getContentProvider"); 8181 if (caller == null) { 8182 String msg = "null IApplicationThread when getting content provider " 8183 + name; 8184 Slog.w(TAG, msg); 8185 throw new SecurityException(msg); 8186 } 8187 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8188 // with cross-user grant. 8189 return getContentProviderImpl(caller, name, null, stable, userId); 8190 } 8191 8192 public ContentProviderHolder getContentProviderExternal( 8193 String name, int userId, IBinder token) { 8194 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8195 "Do not have permission in call getContentProviderExternal()"); 8196 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8197 false, true, "getContentProvider", null); 8198 return getContentProviderExternalUnchecked(name, token, userId); 8199 } 8200 8201 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8202 IBinder token, int userId) { 8203 return getContentProviderImpl(null, name, token, true, userId); 8204 } 8205 8206 /** 8207 * Drop a content provider from a ProcessRecord's bookkeeping 8208 */ 8209 public void removeContentProvider(IBinder connection, boolean stable) { 8210 enforceNotIsolatedCaller("removeContentProvider"); 8211 long ident = Binder.clearCallingIdentity(); 8212 try { 8213 synchronized (this) { 8214 ContentProviderConnection conn; 8215 try { 8216 conn = (ContentProviderConnection)connection; 8217 } catch (ClassCastException e) { 8218 String msg ="removeContentProvider: " + connection 8219 + " not a ContentProviderConnection"; 8220 Slog.w(TAG, msg); 8221 throw new IllegalArgumentException(msg); 8222 } 8223 if (conn == null) { 8224 throw new NullPointerException("connection is null"); 8225 } 8226 if (decProviderCountLocked(conn, null, null, stable)) { 8227 updateOomAdjLocked(); 8228 } 8229 } 8230 } finally { 8231 Binder.restoreCallingIdentity(ident); 8232 } 8233 } 8234 8235 public void removeContentProviderExternal(String name, IBinder token) { 8236 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8237 "Do not have permission in call removeContentProviderExternal()"); 8238 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8239 } 8240 8241 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8242 synchronized (this) { 8243 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8244 if(cpr == null) { 8245 //remove from mProvidersByClass 8246 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8247 return; 8248 } 8249 8250 //update content provider record entry info 8251 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8252 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8253 if (localCpr.hasExternalProcessHandles()) { 8254 if (localCpr.removeExternalProcessHandleLocked(token)) { 8255 updateOomAdjLocked(); 8256 } else { 8257 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8258 + " with no external reference for token: " 8259 + token + "."); 8260 } 8261 } else { 8262 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8263 + " with no external references."); 8264 } 8265 } 8266 } 8267 8268 public final void publishContentProviders(IApplicationThread caller, 8269 List<ContentProviderHolder> providers) { 8270 if (providers == null) { 8271 return; 8272 } 8273 8274 enforceNotIsolatedCaller("publishContentProviders"); 8275 synchronized (this) { 8276 final ProcessRecord r = getRecordForAppLocked(caller); 8277 if (DEBUG_MU) 8278 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8279 if (r == null) { 8280 throw new SecurityException( 8281 "Unable to find app for caller " + caller 8282 + " (pid=" + Binder.getCallingPid() 8283 + ") when publishing content providers"); 8284 } 8285 8286 final long origId = Binder.clearCallingIdentity(); 8287 8288 final int N = providers.size(); 8289 for (int i=0; i<N; i++) { 8290 ContentProviderHolder src = providers.get(i); 8291 if (src == null || src.info == null || src.provider == null) { 8292 continue; 8293 } 8294 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8295 if (DEBUG_MU) 8296 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8297 if (dst != null) { 8298 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8299 mProviderMap.putProviderByClass(comp, dst); 8300 String names[] = dst.info.authority.split(";"); 8301 for (int j = 0; j < names.length; j++) { 8302 mProviderMap.putProviderByName(names[j], dst); 8303 } 8304 8305 int NL = mLaunchingProviders.size(); 8306 int j; 8307 for (j=0; j<NL; j++) { 8308 if (mLaunchingProviders.get(j) == dst) { 8309 mLaunchingProviders.remove(j); 8310 j--; 8311 NL--; 8312 } 8313 } 8314 synchronized (dst) { 8315 dst.provider = src.provider; 8316 dst.proc = r; 8317 dst.notifyAll(); 8318 } 8319 updateOomAdjLocked(r); 8320 } 8321 } 8322 8323 Binder.restoreCallingIdentity(origId); 8324 } 8325 } 8326 8327 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8328 ContentProviderConnection conn; 8329 try { 8330 conn = (ContentProviderConnection)connection; 8331 } catch (ClassCastException e) { 8332 String msg ="refContentProvider: " + connection 8333 + " not a ContentProviderConnection"; 8334 Slog.w(TAG, msg); 8335 throw new IllegalArgumentException(msg); 8336 } 8337 if (conn == null) { 8338 throw new NullPointerException("connection is null"); 8339 } 8340 8341 synchronized (this) { 8342 if (stable > 0) { 8343 conn.numStableIncs += stable; 8344 } 8345 stable = conn.stableCount + stable; 8346 if (stable < 0) { 8347 throw new IllegalStateException("stableCount < 0: " + stable); 8348 } 8349 8350 if (unstable > 0) { 8351 conn.numUnstableIncs += unstable; 8352 } 8353 unstable = conn.unstableCount + unstable; 8354 if (unstable < 0) { 8355 throw new IllegalStateException("unstableCount < 0: " + unstable); 8356 } 8357 8358 if ((stable+unstable) <= 0) { 8359 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8360 + stable + " unstable=" + unstable); 8361 } 8362 conn.stableCount = stable; 8363 conn.unstableCount = unstable; 8364 return !conn.dead; 8365 } 8366 } 8367 8368 public void unstableProviderDied(IBinder connection) { 8369 ContentProviderConnection conn; 8370 try { 8371 conn = (ContentProviderConnection)connection; 8372 } catch (ClassCastException e) { 8373 String msg ="refContentProvider: " + connection 8374 + " not a ContentProviderConnection"; 8375 Slog.w(TAG, msg); 8376 throw new IllegalArgumentException(msg); 8377 } 8378 if (conn == null) { 8379 throw new NullPointerException("connection is null"); 8380 } 8381 8382 // Safely retrieve the content provider associated with the connection. 8383 IContentProvider provider; 8384 synchronized (this) { 8385 provider = conn.provider.provider; 8386 } 8387 8388 if (provider == null) { 8389 // Um, yeah, we're way ahead of you. 8390 return; 8391 } 8392 8393 // Make sure the caller is being honest with us. 8394 if (provider.asBinder().pingBinder()) { 8395 // Er, no, still looks good to us. 8396 synchronized (this) { 8397 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8398 + " says " + conn + " died, but we don't agree"); 8399 return; 8400 } 8401 } 8402 8403 // Well look at that! It's dead! 8404 synchronized (this) { 8405 if (conn.provider.provider != provider) { 8406 // But something changed... good enough. 8407 return; 8408 } 8409 8410 ProcessRecord proc = conn.provider.proc; 8411 if (proc == null || proc.thread == null) { 8412 // Seems like the process is already cleaned up. 8413 return; 8414 } 8415 8416 // As far as we're concerned, this is just like receiving a 8417 // death notification... just a bit prematurely. 8418 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8419 + ") early provider death"); 8420 final long ident = Binder.clearCallingIdentity(); 8421 try { 8422 appDiedLocked(proc, proc.pid, proc.thread); 8423 } finally { 8424 Binder.restoreCallingIdentity(ident); 8425 } 8426 } 8427 } 8428 8429 @Override 8430 public void appNotRespondingViaProvider(IBinder connection) { 8431 enforceCallingPermission( 8432 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8433 8434 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8435 if (conn == null) { 8436 Slog.w(TAG, "ContentProviderConnection is null"); 8437 return; 8438 } 8439 8440 final ProcessRecord host = conn.provider.proc; 8441 if (host == null) { 8442 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8443 return; 8444 } 8445 8446 final long token = Binder.clearCallingIdentity(); 8447 try { 8448 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8449 } finally { 8450 Binder.restoreCallingIdentity(token); 8451 } 8452 } 8453 8454 public final void installSystemProviders() { 8455 List<ProviderInfo> providers; 8456 synchronized (this) { 8457 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8458 providers = generateApplicationProvidersLocked(app); 8459 if (providers != null) { 8460 for (int i=providers.size()-1; i>=0; i--) { 8461 ProviderInfo pi = (ProviderInfo)providers.get(i); 8462 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8463 Slog.w(TAG, "Not installing system proc provider " + pi.name 8464 + ": not system .apk"); 8465 providers.remove(i); 8466 } 8467 } 8468 } 8469 } 8470 if (providers != null) { 8471 mSystemThread.installSystemProviders(providers); 8472 } 8473 8474 mCoreSettingsObserver = new CoreSettingsObserver(this); 8475 8476 mUsageStatsService.monitorPackages(); 8477 } 8478 8479 /** 8480 * Allows app to retrieve the MIME type of a URI without having permission 8481 * to access its content provider. 8482 * 8483 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8484 * 8485 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8486 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8487 */ 8488 public String getProviderMimeType(Uri uri, int userId) { 8489 enforceNotIsolatedCaller("getProviderMimeType"); 8490 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8491 userId, false, true, "getProviderMimeType", null); 8492 final String name = uri.getAuthority(); 8493 final long ident = Binder.clearCallingIdentity(); 8494 ContentProviderHolder holder = null; 8495 8496 try { 8497 holder = getContentProviderExternalUnchecked(name, null, userId); 8498 if (holder != null) { 8499 return holder.provider.getType(uri); 8500 } 8501 } catch (RemoteException e) { 8502 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8503 return null; 8504 } finally { 8505 if (holder != null) { 8506 removeContentProviderExternalUnchecked(name, null, userId); 8507 } 8508 Binder.restoreCallingIdentity(ident); 8509 } 8510 8511 return null; 8512 } 8513 8514 // ========================================================= 8515 // GLOBAL MANAGEMENT 8516 // ========================================================= 8517 8518 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8519 boolean isolated) { 8520 String proc = customProcess != null ? customProcess : info.processName; 8521 BatteryStatsImpl.Uid.Proc ps = null; 8522 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8523 int uid = info.uid; 8524 if (isolated) { 8525 int userId = UserHandle.getUserId(uid); 8526 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8527 while (true) { 8528 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8529 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8530 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8531 } 8532 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8533 mNextIsolatedProcessUid++; 8534 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8535 // No process for this uid, use it. 8536 break; 8537 } 8538 stepsLeft--; 8539 if (stepsLeft <= 0) { 8540 return null; 8541 } 8542 } 8543 } 8544 return new ProcessRecord(stats, info, proc, uid); 8545 } 8546 8547 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8548 ProcessRecord app; 8549 if (!isolated) { 8550 app = getProcessRecordLocked(info.processName, info.uid, true); 8551 } else { 8552 app = null; 8553 } 8554 8555 if (app == null) { 8556 app = newProcessRecordLocked(info, null, isolated); 8557 mProcessNames.put(info.processName, app.uid, app); 8558 if (isolated) { 8559 mIsolatedProcesses.put(app.uid, app); 8560 } 8561 updateLruProcessLocked(app, false, null); 8562 updateOomAdjLocked(); 8563 } 8564 8565 // This package really, really can not be stopped. 8566 try { 8567 AppGlobals.getPackageManager().setPackageStoppedState( 8568 info.packageName, false, UserHandle.getUserId(app.uid)); 8569 } catch (RemoteException e) { 8570 } catch (IllegalArgumentException e) { 8571 Slog.w(TAG, "Failed trying to unstop package " 8572 + info.packageName + ": " + e); 8573 } 8574 8575 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8576 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8577 app.persistent = true; 8578 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8579 } 8580 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8581 mPersistentStartingProcesses.add(app); 8582 startProcessLocked(app, "added application", app.processName); 8583 } 8584 8585 return app; 8586 } 8587 8588 public void unhandledBack() { 8589 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8590 "unhandledBack()"); 8591 8592 synchronized(this) { 8593 final long origId = Binder.clearCallingIdentity(); 8594 try { 8595 getFocusedStack().unhandledBackLocked(); 8596 } finally { 8597 Binder.restoreCallingIdentity(origId); 8598 } 8599 } 8600 } 8601 8602 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8603 enforceNotIsolatedCaller("openContentUri"); 8604 final int userId = UserHandle.getCallingUserId(); 8605 String name = uri.getAuthority(); 8606 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8607 ParcelFileDescriptor pfd = null; 8608 if (cph != null) { 8609 // We record the binder invoker's uid in thread-local storage before 8610 // going to the content provider to open the file. Later, in the code 8611 // that handles all permissions checks, we look for this uid and use 8612 // that rather than the Activity Manager's own uid. The effect is that 8613 // we do the check against the caller's permissions even though it looks 8614 // to the content provider like the Activity Manager itself is making 8615 // the request. 8616 sCallerIdentity.set(new Identity( 8617 Binder.getCallingPid(), Binder.getCallingUid())); 8618 try { 8619 pfd = cph.provider.openFile(null, uri, "r", null); 8620 } catch (FileNotFoundException e) { 8621 // do nothing; pfd will be returned null 8622 } finally { 8623 // Ensure that whatever happens, we clean up the identity state 8624 sCallerIdentity.remove(); 8625 } 8626 8627 // We've got the fd now, so we're done with the provider. 8628 removeContentProviderExternalUnchecked(name, null, userId); 8629 } else { 8630 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8631 } 8632 return pfd; 8633 } 8634 8635 // Actually is sleeping or shutting down or whatever else in the future 8636 // is an inactive state. 8637 public boolean isSleepingOrShuttingDown() { 8638 return mSleeping || mShuttingDown; 8639 } 8640 8641 public boolean isSleeping() { 8642 return mSleeping; 8643 } 8644 8645 void goingToSleep() { 8646 synchronized(this) { 8647 mWentToSleep = true; 8648 updateEventDispatchingLocked(); 8649 goToSleepIfNeededLocked(); 8650 } 8651 } 8652 8653 void finishRunningVoiceLocked() { 8654 if (mRunningVoice) { 8655 mRunningVoice = false; 8656 goToSleepIfNeededLocked(); 8657 } 8658 } 8659 8660 void goToSleepIfNeededLocked() { 8661 if (mWentToSleep && !mRunningVoice) { 8662 if (!mSleeping) { 8663 mSleeping = true; 8664 mStackSupervisor.goingToSleepLocked(); 8665 8666 // Initialize the wake times of all processes. 8667 checkExcessivePowerUsageLocked(false); 8668 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8669 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8670 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8671 } 8672 } 8673 } 8674 8675 @Override 8676 public boolean shutdown(int timeout) { 8677 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8678 != PackageManager.PERMISSION_GRANTED) { 8679 throw new SecurityException("Requires permission " 8680 + android.Manifest.permission.SHUTDOWN); 8681 } 8682 8683 boolean timedout = false; 8684 8685 synchronized(this) { 8686 mShuttingDown = true; 8687 updateEventDispatchingLocked(); 8688 timedout = mStackSupervisor.shutdownLocked(timeout); 8689 } 8690 8691 mAppOpsService.shutdown(); 8692 mUsageStatsService.shutdown(); 8693 mBatteryStatsService.shutdown(); 8694 synchronized (this) { 8695 mProcessStats.shutdownLocked(); 8696 } 8697 8698 return timedout; 8699 } 8700 8701 public final void activitySlept(IBinder token) { 8702 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8703 8704 final long origId = Binder.clearCallingIdentity(); 8705 8706 synchronized (this) { 8707 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8708 if (r != null) { 8709 mStackSupervisor.activitySleptLocked(r); 8710 } 8711 } 8712 8713 Binder.restoreCallingIdentity(origId); 8714 } 8715 8716 void logLockScreen(String msg) { 8717 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8718 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8719 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8720 mStackSupervisor.mDismissKeyguardOnNextActivity); 8721 } 8722 8723 private void comeOutOfSleepIfNeededLocked() { 8724 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8725 if (mSleeping) { 8726 mSleeping = false; 8727 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8728 } 8729 } 8730 } 8731 8732 void wakingUp() { 8733 synchronized(this) { 8734 mWentToSleep = false; 8735 updateEventDispatchingLocked(); 8736 comeOutOfSleepIfNeededLocked(); 8737 } 8738 } 8739 8740 void startRunningVoiceLocked() { 8741 if (!mRunningVoice) { 8742 mRunningVoice = true; 8743 comeOutOfSleepIfNeededLocked(); 8744 } 8745 } 8746 8747 private void updateEventDispatchingLocked() { 8748 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8749 } 8750 8751 public void setLockScreenShown(boolean shown) { 8752 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8753 != PackageManager.PERMISSION_GRANTED) { 8754 throw new SecurityException("Requires permission " 8755 + android.Manifest.permission.DEVICE_POWER); 8756 } 8757 8758 synchronized(this) { 8759 long ident = Binder.clearCallingIdentity(); 8760 try { 8761 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8762 mLockScreenShown = shown; 8763 comeOutOfSleepIfNeededLocked(); 8764 } finally { 8765 Binder.restoreCallingIdentity(ident); 8766 } 8767 } 8768 } 8769 8770 public void stopAppSwitches() { 8771 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8772 != PackageManager.PERMISSION_GRANTED) { 8773 throw new SecurityException("Requires permission " 8774 + android.Manifest.permission.STOP_APP_SWITCHES); 8775 } 8776 8777 synchronized(this) { 8778 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8779 + APP_SWITCH_DELAY_TIME; 8780 mDidAppSwitch = false; 8781 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8782 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8783 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8784 } 8785 } 8786 8787 public void resumeAppSwitches() { 8788 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8789 != PackageManager.PERMISSION_GRANTED) { 8790 throw new SecurityException("Requires permission " 8791 + android.Manifest.permission.STOP_APP_SWITCHES); 8792 } 8793 8794 synchronized(this) { 8795 // Note that we don't execute any pending app switches... we will 8796 // let those wait until either the timeout, or the next start 8797 // activity request. 8798 mAppSwitchesAllowedTime = 0; 8799 } 8800 } 8801 8802 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8803 String name) { 8804 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8805 return true; 8806 } 8807 8808 final int perm = checkComponentPermission( 8809 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8810 callingUid, -1, true); 8811 if (perm == PackageManager.PERMISSION_GRANTED) { 8812 return true; 8813 } 8814 8815 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8816 return false; 8817 } 8818 8819 public void setDebugApp(String packageName, boolean waitForDebugger, 8820 boolean persistent) { 8821 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8822 "setDebugApp()"); 8823 8824 long ident = Binder.clearCallingIdentity(); 8825 try { 8826 // Note that this is not really thread safe if there are multiple 8827 // callers into it at the same time, but that's not a situation we 8828 // care about. 8829 if (persistent) { 8830 final ContentResolver resolver = mContext.getContentResolver(); 8831 Settings.Global.putString( 8832 resolver, Settings.Global.DEBUG_APP, 8833 packageName); 8834 Settings.Global.putInt( 8835 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8836 waitForDebugger ? 1 : 0); 8837 } 8838 8839 synchronized (this) { 8840 if (!persistent) { 8841 mOrigDebugApp = mDebugApp; 8842 mOrigWaitForDebugger = mWaitForDebugger; 8843 } 8844 mDebugApp = packageName; 8845 mWaitForDebugger = waitForDebugger; 8846 mDebugTransient = !persistent; 8847 if (packageName != null) { 8848 forceStopPackageLocked(packageName, -1, false, false, true, true, 8849 false, UserHandle.USER_ALL, "set debug app"); 8850 } 8851 } 8852 } finally { 8853 Binder.restoreCallingIdentity(ident); 8854 } 8855 } 8856 8857 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8858 synchronized (this) { 8859 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8860 if (!isDebuggable) { 8861 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8862 throw new SecurityException("Process not debuggable: " + app.packageName); 8863 } 8864 } 8865 8866 mOpenGlTraceApp = processName; 8867 } 8868 } 8869 8870 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8871 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8872 synchronized (this) { 8873 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8874 if (!isDebuggable) { 8875 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8876 throw new SecurityException("Process not debuggable: " + app.packageName); 8877 } 8878 } 8879 mProfileApp = processName; 8880 mProfileFile = profileFile; 8881 if (mProfileFd != null) { 8882 try { 8883 mProfileFd.close(); 8884 } catch (IOException e) { 8885 } 8886 mProfileFd = null; 8887 } 8888 mProfileFd = profileFd; 8889 mProfileType = 0; 8890 mAutoStopProfiler = autoStopProfiler; 8891 } 8892 } 8893 8894 @Override 8895 public void setAlwaysFinish(boolean enabled) { 8896 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8897 "setAlwaysFinish()"); 8898 8899 Settings.Global.putInt( 8900 mContext.getContentResolver(), 8901 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8902 8903 synchronized (this) { 8904 mAlwaysFinishActivities = enabled; 8905 } 8906 } 8907 8908 @Override 8909 public void setActivityController(IActivityController controller) { 8910 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8911 "setActivityController()"); 8912 synchronized (this) { 8913 mController = controller; 8914 Watchdog.getInstance().setActivityController(controller); 8915 } 8916 } 8917 8918 @Override 8919 public void setUserIsMonkey(boolean userIsMonkey) { 8920 synchronized (this) { 8921 synchronized (mPidsSelfLocked) { 8922 final int callingPid = Binder.getCallingPid(); 8923 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8924 if (precessRecord == null) { 8925 throw new SecurityException("Unknown process: " + callingPid); 8926 } 8927 if (precessRecord.instrumentationUiAutomationConnection == null) { 8928 throw new SecurityException("Only an instrumentation process " 8929 + "with a UiAutomation can call setUserIsMonkey"); 8930 } 8931 } 8932 mUserIsMonkey = userIsMonkey; 8933 } 8934 } 8935 8936 @Override 8937 public boolean isUserAMonkey() { 8938 synchronized (this) { 8939 // If there is a controller also implies the user is a monkey. 8940 return (mUserIsMonkey || mController != null); 8941 } 8942 } 8943 8944 public void requestBugReport() { 8945 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8946 SystemProperties.set("ctl.start", "bugreport"); 8947 } 8948 8949 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8950 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8951 } 8952 8953 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8954 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8955 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8956 } 8957 return KEY_DISPATCHING_TIMEOUT; 8958 } 8959 8960 @Override 8961 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8962 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8963 != PackageManager.PERMISSION_GRANTED) { 8964 throw new SecurityException("Requires permission " 8965 + android.Manifest.permission.FILTER_EVENTS); 8966 } 8967 ProcessRecord proc; 8968 long timeout; 8969 synchronized (this) { 8970 synchronized (mPidsSelfLocked) { 8971 proc = mPidsSelfLocked.get(pid); 8972 } 8973 timeout = getInputDispatchingTimeoutLocked(proc); 8974 } 8975 8976 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8977 return -1; 8978 } 8979 8980 return timeout; 8981 } 8982 8983 /** 8984 * Handle input dispatching timeouts. 8985 * Returns whether input dispatching should be aborted or not. 8986 */ 8987 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8988 final ActivityRecord activity, final ActivityRecord parent, 8989 final boolean aboveSystem, String reason) { 8990 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8991 != PackageManager.PERMISSION_GRANTED) { 8992 throw new SecurityException("Requires permission " 8993 + android.Manifest.permission.FILTER_EVENTS); 8994 } 8995 8996 final String annotation; 8997 if (reason == null) { 8998 annotation = "Input dispatching timed out"; 8999 } else { 9000 annotation = "Input dispatching timed out (" + reason + ")"; 9001 } 9002 9003 if (proc != null) { 9004 synchronized (this) { 9005 if (proc.debugging) { 9006 return false; 9007 } 9008 9009 if (mDidDexOpt) { 9010 // Give more time since we were dexopting. 9011 mDidDexOpt = false; 9012 return false; 9013 } 9014 9015 if (proc.instrumentationClass != null) { 9016 Bundle info = new Bundle(); 9017 info.putString("shortMsg", "keyDispatchingTimedOut"); 9018 info.putString("longMsg", annotation); 9019 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 9020 return true; 9021 } 9022 } 9023 mHandler.post(new Runnable() { 9024 @Override 9025 public void run() { 9026 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9027 } 9028 }); 9029 } 9030 9031 return true; 9032 } 9033 9034 public Bundle getAssistContextExtras(int requestType) { 9035 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9036 "getAssistContextExtras()"); 9037 PendingAssistExtras pae; 9038 Bundle extras = new Bundle(); 9039 synchronized (this) { 9040 ActivityRecord activity = getFocusedStack().mResumedActivity; 9041 if (activity == null) { 9042 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9043 return null; 9044 } 9045 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9046 if (activity.app == null || activity.app.thread == null) { 9047 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9048 return extras; 9049 } 9050 if (activity.app.pid == Binder.getCallingPid()) { 9051 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9052 return extras; 9053 } 9054 pae = new PendingAssistExtras(activity); 9055 try { 9056 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9057 requestType); 9058 mPendingAssistExtras.add(pae); 9059 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9060 } catch (RemoteException e) { 9061 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9062 return extras; 9063 } 9064 } 9065 synchronized (pae) { 9066 while (!pae.haveResult) { 9067 try { 9068 pae.wait(); 9069 } catch (InterruptedException e) { 9070 } 9071 } 9072 if (pae.result != null) { 9073 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9074 } 9075 } 9076 synchronized (this) { 9077 mPendingAssistExtras.remove(pae); 9078 mHandler.removeCallbacks(pae); 9079 } 9080 return extras; 9081 } 9082 9083 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9084 PendingAssistExtras pae = (PendingAssistExtras)token; 9085 synchronized (pae) { 9086 pae.result = extras; 9087 pae.haveResult = true; 9088 pae.notifyAll(); 9089 } 9090 } 9091 9092 public void registerProcessObserver(IProcessObserver observer) { 9093 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9094 "registerProcessObserver()"); 9095 synchronized (this) { 9096 mProcessObservers.register(observer); 9097 } 9098 } 9099 9100 @Override 9101 public void unregisterProcessObserver(IProcessObserver observer) { 9102 synchronized (this) { 9103 mProcessObservers.unregister(observer); 9104 } 9105 } 9106 9107 @Override 9108 public boolean convertFromTranslucent(IBinder token) { 9109 final long origId = Binder.clearCallingIdentity(); 9110 try { 9111 synchronized (this) { 9112 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9113 if (r == null) { 9114 return false; 9115 } 9116 if (r.changeWindowTranslucency(true)) { 9117 mWindowManager.setAppFullscreen(token, true); 9118 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9119 return true; 9120 } 9121 return false; 9122 } 9123 } finally { 9124 Binder.restoreCallingIdentity(origId); 9125 } 9126 } 9127 9128 @Override 9129 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9130 final long origId = Binder.clearCallingIdentity(); 9131 try { 9132 synchronized (this) { 9133 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9134 if (r == null) { 9135 return false; 9136 } 9137 if (r.changeWindowTranslucency(false)) { 9138 r.task.stack.convertToTranslucent(r, options); 9139 mWindowManager.setAppFullscreen(token, false); 9140 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9141 return true; 9142 } 9143 return false; 9144 } 9145 } finally { 9146 Binder.restoreCallingIdentity(origId); 9147 } 9148 } 9149 9150 @Override 9151 public ActivityOptions getActivityOptions(IBinder token) { 9152 final long origId = Binder.clearCallingIdentity(); 9153 try { 9154 synchronized (this) { 9155 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9156 if (r != null) { 9157 final ActivityOptions activityOptions = r.pendingOptions; 9158 r.pendingOptions = null; 9159 return activityOptions; 9160 } 9161 return null; 9162 } 9163 } finally { 9164 Binder.restoreCallingIdentity(origId); 9165 } 9166 } 9167 9168 @Override 9169 public void setImmersive(IBinder token, boolean immersive) { 9170 synchronized(this) { 9171 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9172 if (r == null) { 9173 throw new IllegalArgumentException(); 9174 } 9175 r.immersive = immersive; 9176 9177 // update associated state if we're frontmost 9178 if (r == mFocusedActivity) { 9179 if (DEBUG_IMMERSIVE) { 9180 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9181 } 9182 applyUpdateLockStateLocked(r); 9183 } 9184 } 9185 } 9186 9187 @Override 9188 public boolean isImmersive(IBinder token) { 9189 synchronized (this) { 9190 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9191 if (r == null) { 9192 throw new IllegalArgumentException(); 9193 } 9194 return r.immersive; 9195 } 9196 } 9197 9198 public boolean isTopActivityImmersive() { 9199 enforceNotIsolatedCaller("startActivity"); 9200 synchronized (this) { 9201 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9202 return (r != null) ? r.immersive : false; 9203 } 9204 } 9205 9206 public final void enterSafeMode() { 9207 synchronized(this) { 9208 // It only makes sense to do this before the system is ready 9209 // and started launching other packages. 9210 if (!mSystemReady) { 9211 try { 9212 AppGlobals.getPackageManager().enterSafeMode(); 9213 } catch (RemoteException e) { 9214 } 9215 } 9216 9217 mSafeMode = true; 9218 } 9219 } 9220 9221 public final void showSafeModeOverlay() { 9222 View v = LayoutInflater.from(mContext).inflate( 9223 com.android.internal.R.layout.safe_mode, null); 9224 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9225 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9226 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9227 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9228 lp.gravity = Gravity.BOTTOM | Gravity.START; 9229 lp.format = v.getBackground().getOpacity(); 9230 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9231 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9232 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9233 ((WindowManager)mContext.getSystemService( 9234 Context.WINDOW_SERVICE)).addView(v, lp); 9235 } 9236 9237 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9238 if (!(sender instanceof PendingIntentRecord)) { 9239 return; 9240 } 9241 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9242 synchronized (stats) { 9243 if (mBatteryStatsService.isOnBattery()) { 9244 mBatteryStatsService.enforceCallingPermission(); 9245 PendingIntentRecord rec = (PendingIntentRecord)sender; 9246 int MY_UID = Binder.getCallingUid(); 9247 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9248 BatteryStatsImpl.Uid.Pkg pkg = 9249 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9250 sourcePkg != null ? sourcePkg : rec.key.packageName); 9251 pkg.incWakeupsLocked(); 9252 } 9253 } 9254 } 9255 9256 public boolean killPids(int[] pids, String pReason, boolean secure) { 9257 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9258 throw new SecurityException("killPids only available to the system"); 9259 } 9260 String reason = (pReason == null) ? "Unknown" : pReason; 9261 // XXX Note: don't acquire main activity lock here, because the window 9262 // manager calls in with its locks held. 9263 9264 boolean killed = false; 9265 synchronized (mPidsSelfLocked) { 9266 int[] types = new int[pids.length]; 9267 int worstType = 0; 9268 for (int i=0; i<pids.length; i++) { 9269 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9270 if (proc != null) { 9271 int type = proc.setAdj; 9272 types[i] = type; 9273 if (type > worstType) { 9274 worstType = type; 9275 } 9276 } 9277 } 9278 9279 // If the worst oom_adj is somewhere in the cached proc LRU range, 9280 // then constrain it so we will kill all cached procs. 9281 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9282 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9283 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9284 } 9285 9286 // If this is not a secure call, don't let it kill processes that 9287 // are important. 9288 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9289 worstType = ProcessList.SERVICE_ADJ; 9290 } 9291 9292 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9293 for (int i=0; i<pids.length; i++) { 9294 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9295 if (proc == null) { 9296 continue; 9297 } 9298 int adj = proc.setAdj; 9299 if (adj >= worstType && !proc.killedByAm) { 9300 killUnneededProcessLocked(proc, reason); 9301 killed = true; 9302 } 9303 } 9304 } 9305 return killed; 9306 } 9307 9308 @Override 9309 public void killUid(int uid, String reason) { 9310 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9311 throw new SecurityException("killUid only available to the system"); 9312 } 9313 synchronized (this) { 9314 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9315 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9316 reason != null ? reason : "kill uid"); 9317 } 9318 } 9319 9320 @Override 9321 public boolean killProcessesBelowForeground(String reason) { 9322 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9323 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9324 } 9325 9326 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9327 } 9328 9329 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9330 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9331 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9332 } 9333 9334 boolean killed = false; 9335 synchronized (mPidsSelfLocked) { 9336 final int size = mPidsSelfLocked.size(); 9337 for (int i = 0; i < size; i++) { 9338 final int pid = mPidsSelfLocked.keyAt(i); 9339 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9340 if (proc == null) continue; 9341 9342 final int adj = proc.setAdj; 9343 if (adj > belowAdj && !proc.killedByAm) { 9344 killUnneededProcessLocked(proc, reason); 9345 killed = true; 9346 } 9347 } 9348 } 9349 return killed; 9350 } 9351 9352 @Override 9353 public void hang(final IBinder who, boolean allowRestart) { 9354 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9355 != PackageManager.PERMISSION_GRANTED) { 9356 throw new SecurityException("Requires permission " 9357 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9358 } 9359 9360 final IBinder.DeathRecipient death = new DeathRecipient() { 9361 @Override 9362 public void binderDied() { 9363 synchronized (this) { 9364 notifyAll(); 9365 } 9366 } 9367 }; 9368 9369 try { 9370 who.linkToDeath(death, 0); 9371 } catch (RemoteException e) { 9372 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9373 return; 9374 } 9375 9376 synchronized (this) { 9377 Watchdog.getInstance().setAllowRestart(allowRestart); 9378 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9379 synchronized (death) { 9380 while (who.isBinderAlive()) { 9381 try { 9382 death.wait(); 9383 } catch (InterruptedException e) { 9384 } 9385 } 9386 } 9387 Watchdog.getInstance().setAllowRestart(true); 9388 } 9389 } 9390 9391 @Override 9392 public void restart() { 9393 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9394 != PackageManager.PERMISSION_GRANTED) { 9395 throw new SecurityException("Requires permission " 9396 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9397 } 9398 9399 Log.i(TAG, "Sending shutdown broadcast..."); 9400 9401 BroadcastReceiver br = new BroadcastReceiver() { 9402 @Override public void onReceive(Context context, Intent intent) { 9403 // Now the broadcast is done, finish up the low-level shutdown. 9404 Log.i(TAG, "Shutting down activity manager..."); 9405 shutdown(10000); 9406 Log.i(TAG, "Shutdown complete, restarting!"); 9407 Process.killProcess(Process.myPid()); 9408 System.exit(10); 9409 } 9410 }; 9411 9412 // First send the high-level shut down broadcast. 9413 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9414 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9415 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9416 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9417 mContext.sendOrderedBroadcastAsUser(intent, 9418 UserHandle.ALL, null, br, mHandler, 0, null, null); 9419 */ 9420 br.onReceive(mContext, intent); 9421 } 9422 9423 private long getLowRamTimeSinceIdle(long now) { 9424 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9425 } 9426 9427 @Override 9428 public void performIdleMaintenance() { 9429 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9430 != PackageManager.PERMISSION_GRANTED) { 9431 throw new SecurityException("Requires permission " 9432 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9433 } 9434 9435 synchronized (this) { 9436 final long now = SystemClock.uptimeMillis(); 9437 final long timeSinceLastIdle = now - mLastIdleTime; 9438 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9439 mLastIdleTime = now; 9440 mLowRamTimeSinceLastIdle = 0; 9441 if (mLowRamStartTime != 0) { 9442 mLowRamStartTime = now; 9443 } 9444 9445 StringBuilder sb = new StringBuilder(128); 9446 sb.append("Idle maintenance over "); 9447 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9448 sb.append(" low RAM for "); 9449 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9450 Slog.i(TAG, sb.toString()); 9451 9452 // If at least 1/3 of our time since the last idle period has been spent 9453 // with RAM low, then we want to kill processes. 9454 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9455 9456 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9457 ProcessRecord proc = mLruProcesses.get(i); 9458 if (proc.notCachedSinceIdle) { 9459 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9460 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9461 if (doKilling && proc.initialIdlePss != 0 9462 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9463 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9464 + " from " + proc.initialIdlePss + ")"); 9465 } 9466 } 9467 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9468 proc.notCachedSinceIdle = true; 9469 proc.initialIdlePss = 0; 9470 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9471 isSleeping(), now); 9472 } 9473 } 9474 9475 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9476 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9477 } 9478 } 9479 9480 private void retrieveSettings() { 9481 final ContentResolver resolver = mContext.getContentResolver(); 9482 String debugApp = Settings.Global.getString( 9483 resolver, Settings.Global.DEBUG_APP); 9484 boolean waitForDebugger = Settings.Global.getInt( 9485 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9486 boolean alwaysFinishActivities = Settings.Global.getInt( 9487 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9488 boolean forceRtl = Settings.Global.getInt( 9489 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9490 // Transfer any global setting for forcing RTL layout, into a System Property 9491 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9492 9493 Configuration configuration = new Configuration(); 9494 Settings.System.getConfiguration(resolver, configuration); 9495 if (forceRtl) { 9496 // This will take care of setting the correct layout direction flags 9497 configuration.setLayoutDirection(configuration.locale); 9498 } 9499 9500 synchronized (this) { 9501 mDebugApp = mOrigDebugApp = debugApp; 9502 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9503 mAlwaysFinishActivities = alwaysFinishActivities; 9504 // This happens before any activities are started, so we can 9505 // change mConfiguration in-place. 9506 updateConfigurationLocked(configuration, null, false, true); 9507 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9508 } 9509 } 9510 9511 public boolean testIsSystemReady() { 9512 // no need to synchronize(this) just to read & return the value 9513 return mSystemReady; 9514 } 9515 9516 private static File getCalledPreBootReceiversFile() { 9517 File dataDir = Environment.getDataDirectory(); 9518 File systemDir = new File(dataDir, "system"); 9519 File fname = new File(systemDir, "called_pre_boots.dat"); 9520 return fname; 9521 } 9522 9523 static final int LAST_DONE_VERSION = 10000; 9524 9525 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9526 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9527 File file = getCalledPreBootReceiversFile(); 9528 FileInputStream fis = null; 9529 try { 9530 fis = new FileInputStream(file); 9531 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9532 int fvers = dis.readInt(); 9533 if (fvers == LAST_DONE_VERSION) { 9534 String vers = dis.readUTF(); 9535 String codename = dis.readUTF(); 9536 String build = dis.readUTF(); 9537 if (android.os.Build.VERSION.RELEASE.equals(vers) 9538 && android.os.Build.VERSION.CODENAME.equals(codename) 9539 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9540 int num = dis.readInt(); 9541 while (num > 0) { 9542 num--; 9543 String pkg = dis.readUTF(); 9544 String cls = dis.readUTF(); 9545 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9546 } 9547 } 9548 } 9549 } catch (FileNotFoundException e) { 9550 } catch (IOException e) { 9551 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9552 } finally { 9553 if (fis != null) { 9554 try { 9555 fis.close(); 9556 } catch (IOException e) { 9557 } 9558 } 9559 } 9560 return lastDoneReceivers; 9561 } 9562 9563 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9564 File file = getCalledPreBootReceiversFile(); 9565 FileOutputStream fos = null; 9566 DataOutputStream dos = null; 9567 try { 9568 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9569 fos = new FileOutputStream(file); 9570 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9571 dos.writeInt(LAST_DONE_VERSION); 9572 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9573 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9574 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9575 dos.writeInt(list.size()); 9576 for (int i=0; i<list.size(); i++) { 9577 dos.writeUTF(list.get(i).getPackageName()); 9578 dos.writeUTF(list.get(i).getClassName()); 9579 } 9580 } catch (IOException e) { 9581 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9582 file.delete(); 9583 } finally { 9584 FileUtils.sync(fos); 9585 if (dos != null) { 9586 try { 9587 dos.close(); 9588 } catch (IOException e) { 9589 // TODO Auto-generated catch block 9590 e.printStackTrace(); 9591 } 9592 } 9593 } 9594 } 9595 9596 public void systemReady(final Runnable goingCallback) { 9597 synchronized(this) { 9598 if (mSystemReady) { 9599 if (goingCallback != null) goingCallback.run(); 9600 return; 9601 } 9602 9603 // Check to see if there are any update receivers to run. 9604 if (!mDidUpdate) { 9605 if (mWaitingUpdate) { 9606 return; 9607 } 9608 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9609 List<ResolveInfo> ris = null; 9610 try { 9611 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9612 intent, null, 0, 0); 9613 } catch (RemoteException e) { 9614 } 9615 if (ris != null) { 9616 for (int i=ris.size()-1; i>=0; i--) { 9617 if ((ris.get(i).activityInfo.applicationInfo.flags 9618 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9619 ris.remove(i); 9620 } 9621 } 9622 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9623 9624 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9625 9626 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9627 for (int i=0; i<ris.size(); i++) { 9628 ActivityInfo ai = ris.get(i).activityInfo; 9629 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9630 if (lastDoneReceivers.contains(comp)) { 9631 // We already did the pre boot receiver for this app with the current 9632 // platform version, so don't do it again... 9633 ris.remove(i); 9634 i--; 9635 // ...however, do keep it as one that has been done, so we don't 9636 // forget about it when rewriting the file of last done receivers. 9637 doneReceivers.add(comp); 9638 } 9639 } 9640 9641 final int[] users = getUsersLocked(); 9642 for (int i=0; i<ris.size(); i++) { 9643 ActivityInfo ai = ris.get(i).activityInfo; 9644 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9645 doneReceivers.add(comp); 9646 intent.setComponent(comp); 9647 for (int j=0; j<users.length; j++) { 9648 IIntentReceiver finisher = null; 9649 if (i == ris.size()-1 && j == users.length-1) { 9650 finisher = new IIntentReceiver.Stub() { 9651 public void performReceive(Intent intent, int resultCode, 9652 String data, Bundle extras, boolean ordered, 9653 boolean sticky, int sendingUser) { 9654 // The raw IIntentReceiver interface is called 9655 // with the AM lock held, so redispatch to 9656 // execute our code without the lock. 9657 mHandler.post(new Runnable() { 9658 public void run() { 9659 synchronized (ActivityManagerService.this) { 9660 mDidUpdate = true; 9661 } 9662 writeLastDonePreBootReceivers(doneReceivers); 9663 showBootMessage(mContext.getText( 9664 R.string.android_upgrading_complete), 9665 false); 9666 systemReady(goingCallback); 9667 } 9668 }); 9669 } 9670 }; 9671 } 9672 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9673 + " for user " + users[j]); 9674 broadcastIntentLocked(null, null, intent, null, finisher, 9675 0, null, null, null, AppOpsManager.OP_NONE, 9676 true, false, MY_PID, Process.SYSTEM_UID, 9677 users[j]); 9678 if (finisher != null) { 9679 mWaitingUpdate = true; 9680 } 9681 } 9682 } 9683 } 9684 if (mWaitingUpdate) { 9685 return; 9686 } 9687 mDidUpdate = true; 9688 } 9689 9690 mAppOpsService.systemReady(); 9691 mUsageStatsService.systemReady(); 9692 mSystemReady = true; 9693 } 9694 9695 ArrayList<ProcessRecord> procsToKill = null; 9696 synchronized(mPidsSelfLocked) { 9697 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9698 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9699 if (!isAllowedWhileBooting(proc.info)){ 9700 if (procsToKill == null) { 9701 procsToKill = new ArrayList<ProcessRecord>(); 9702 } 9703 procsToKill.add(proc); 9704 } 9705 } 9706 } 9707 9708 synchronized(this) { 9709 if (procsToKill != null) { 9710 for (int i=procsToKill.size()-1; i>=0; i--) { 9711 ProcessRecord proc = procsToKill.get(i); 9712 Slog.i(TAG, "Removing system update proc: " + proc); 9713 removeProcessLocked(proc, true, false, "system update done"); 9714 } 9715 } 9716 9717 // Now that we have cleaned up any update processes, we 9718 // are ready to start launching real processes and know that 9719 // we won't trample on them any more. 9720 mProcessesReady = true; 9721 } 9722 9723 Slog.i(TAG, "System now ready"); 9724 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9725 SystemClock.uptimeMillis()); 9726 9727 synchronized(this) { 9728 // Make sure we have no pre-ready processes sitting around. 9729 9730 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9731 ResolveInfo ri = mContext.getPackageManager() 9732 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9733 STOCK_PM_FLAGS); 9734 CharSequence errorMsg = null; 9735 if (ri != null) { 9736 ActivityInfo ai = ri.activityInfo; 9737 ApplicationInfo app = ai.applicationInfo; 9738 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9739 mTopAction = Intent.ACTION_FACTORY_TEST; 9740 mTopData = null; 9741 mTopComponent = new ComponentName(app.packageName, 9742 ai.name); 9743 } else { 9744 errorMsg = mContext.getResources().getText( 9745 com.android.internal.R.string.factorytest_not_system); 9746 } 9747 } else { 9748 errorMsg = mContext.getResources().getText( 9749 com.android.internal.R.string.factorytest_no_action); 9750 } 9751 if (errorMsg != null) { 9752 mTopAction = null; 9753 mTopData = null; 9754 mTopComponent = null; 9755 Message msg = Message.obtain(); 9756 msg.what = SHOW_FACTORY_ERROR_MSG; 9757 msg.getData().putCharSequence("msg", errorMsg); 9758 mHandler.sendMessage(msg); 9759 } 9760 } 9761 } 9762 9763 retrieveSettings(); 9764 9765 synchronized (this) { 9766 readGrantedUriPermissionsLocked(); 9767 } 9768 9769 if (goingCallback != null) goingCallback.run(); 9770 9771 mSystemServiceManager.startUser(mCurrentUserId); 9772 9773 synchronized (this) { 9774 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9775 try { 9776 List apps = AppGlobals.getPackageManager(). 9777 getPersistentApplications(STOCK_PM_FLAGS); 9778 if (apps != null) { 9779 int N = apps.size(); 9780 int i; 9781 for (i=0; i<N; i++) { 9782 ApplicationInfo info 9783 = (ApplicationInfo)apps.get(i); 9784 if (info != null && 9785 !info.packageName.equals("android")) { 9786 addAppLocked(info, false); 9787 } 9788 } 9789 } 9790 } catch (RemoteException ex) { 9791 // pm is in same process, this will never happen. 9792 } 9793 } 9794 9795 // Start up initial activity. 9796 mBooting = true; 9797 9798 try { 9799 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9800 Message msg = Message.obtain(); 9801 msg.what = SHOW_UID_ERROR_MSG; 9802 mHandler.sendMessage(msg); 9803 } 9804 } catch (RemoteException e) { 9805 } 9806 9807 long ident = Binder.clearCallingIdentity(); 9808 try { 9809 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9810 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9811 | Intent.FLAG_RECEIVER_FOREGROUND); 9812 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9813 broadcastIntentLocked(null, null, intent, 9814 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9815 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9816 intent = new Intent(Intent.ACTION_USER_STARTING); 9817 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9818 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9819 broadcastIntentLocked(null, null, intent, 9820 null, new IIntentReceiver.Stub() { 9821 @Override 9822 public void performReceive(Intent intent, int resultCode, String data, 9823 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9824 throws RemoteException { 9825 } 9826 }, 0, null, null, 9827 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9828 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9829 } catch (Throwable t) { 9830 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 9831 } finally { 9832 Binder.restoreCallingIdentity(ident); 9833 } 9834 mStackSupervisor.resumeTopActivitiesLocked(); 9835 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9836 } 9837 } 9838 9839 private boolean makeAppCrashingLocked(ProcessRecord app, 9840 String shortMsg, String longMsg, String stackTrace) { 9841 app.crashing = true; 9842 app.crashingReport = generateProcessError(app, 9843 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9844 startAppProblemLocked(app); 9845 app.stopFreezingAllLocked(); 9846 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9847 } 9848 9849 private void makeAppNotRespondingLocked(ProcessRecord app, 9850 String activity, String shortMsg, String longMsg) { 9851 app.notResponding = true; 9852 app.notRespondingReport = generateProcessError(app, 9853 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9854 activity, shortMsg, longMsg, null); 9855 startAppProblemLocked(app); 9856 app.stopFreezingAllLocked(); 9857 } 9858 9859 /** 9860 * Generate a process error record, suitable for attachment to a ProcessRecord. 9861 * 9862 * @param app The ProcessRecord in which the error occurred. 9863 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9864 * ActivityManager.AppErrorStateInfo 9865 * @param activity The activity associated with the crash, if known. 9866 * @param shortMsg Short message describing the crash. 9867 * @param longMsg Long message describing the crash. 9868 * @param stackTrace Full crash stack trace, may be null. 9869 * 9870 * @return Returns a fully-formed AppErrorStateInfo record. 9871 */ 9872 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9873 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9874 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9875 9876 report.condition = condition; 9877 report.processName = app.processName; 9878 report.pid = app.pid; 9879 report.uid = app.info.uid; 9880 report.tag = activity; 9881 report.shortMsg = shortMsg; 9882 report.longMsg = longMsg; 9883 report.stackTrace = stackTrace; 9884 9885 return report; 9886 } 9887 9888 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9889 synchronized (this) { 9890 app.crashing = false; 9891 app.crashingReport = null; 9892 app.notResponding = false; 9893 app.notRespondingReport = null; 9894 if (app.anrDialog == fromDialog) { 9895 app.anrDialog = null; 9896 } 9897 if (app.waitDialog == fromDialog) { 9898 app.waitDialog = null; 9899 } 9900 if (app.pid > 0 && app.pid != MY_PID) { 9901 handleAppCrashLocked(app, null, null, null); 9902 killUnneededProcessLocked(app, "user request after error"); 9903 } 9904 } 9905 } 9906 9907 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9908 String stackTrace) { 9909 long now = SystemClock.uptimeMillis(); 9910 9911 Long crashTime; 9912 if (!app.isolated) { 9913 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9914 } else { 9915 crashTime = null; 9916 } 9917 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9918 // This process loses! 9919 Slog.w(TAG, "Process " + app.info.processName 9920 + " has crashed too many times: killing!"); 9921 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9922 app.userId, app.info.processName, app.uid); 9923 mStackSupervisor.handleAppCrashLocked(app); 9924 if (!app.persistent) { 9925 // We don't want to start this process again until the user 9926 // explicitly does so... but for persistent process, we really 9927 // need to keep it running. If a persistent process is actually 9928 // repeatedly crashing, then badness for everyone. 9929 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9930 app.info.processName); 9931 if (!app.isolated) { 9932 // XXX We don't have a way to mark isolated processes 9933 // as bad, since they don't have a peristent identity. 9934 mBadProcesses.put(app.info.processName, app.uid, 9935 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9936 mProcessCrashTimes.remove(app.info.processName, app.uid); 9937 } 9938 app.bad = true; 9939 app.removed = true; 9940 // Don't let services in this process be restarted and potentially 9941 // annoy the user repeatedly. Unless it is persistent, since those 9942 // processes run critical code. 9943 removeProcessLocked(app, false, false, "crash"); 9944 mStackSupervisor.resumeTopActivitiesLocked(); 9945 return false; 9946 } 9947 mStackSupervisor.resumeTopActivitiesLocked(); 9948 } else { 9949 mStackSupervisor.finishTopRunningActivityLocked(app); 9950 } 9951 9952 // Bump up the crash count of any services currently running in the proc. 9953 for (int i=app.services.size()-1; i>=0; i--) { 9954 // Any services running in the application need to be placed 9955 // back in the pending list. 9956 ServiceRecord sr = app.services.valueAt(i); 9957 sr.crashCount++; 9958 } 9959 9960 // If the crashing process is what we consider to be the "home process" and it has been 9961 // replaced by a third-party app, clear the package preferred activities from packages 9962 // with a home activity running in the process to prevent a repeatedly crashing app 9963 // from blocking the user to manually clear the list. 9964 final ArrayList<ActivityRecord> activities = app.activities; 9965 if (app == mHomeProcess && activities.size() > 0 9966 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9967 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9968 final ActivityRecord r = activities.get(activityNdx); 9969 if (r.isHomeActivity()) { 9970 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9971 try { 9972 ActivityThread.getPackageManager() 9973 .clearPackagePreferredActivities(r.packageName); 9974 } catch (RemoteException c) { 9975 // pm is in same process, this will never happen. 9976 } 9977 } 9978 } 9979 } 9980 9981 if (!app.isolated) { 9982 // XXX Can't keep track of crash times for isolated processes, 9983 // because they don't have a perisistent identity. 9984 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9985 } 9986 9987 return true; 9988 } 9989 9990 void startAppProblemLocked(ProcessRecord app) { 9991 if (app.userId == mCurrentUserId) { 9992 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9993 mContext, app.info.packageName, app.info.flags); 9994 } else { 9995 // If this app is not running under the current user, then we 9996 // can't give it a report button because that would require 9997 // launching the report UI under a different user. 9998 app.errorReportReceiver = null; 9999 } 10000 skipCurrentReceiverLocked(app); 10001 } 10002 10003 void skipCurrentReceiverLocked(ProcessRecord app) { 10004 for (BroadcastQueue queue : mBroadcastQueues) { 10005 queue.skipCurrentReceiverLocked(app); 10006 } 10007 } 10008 10009 /** 10010 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 10011 * The application process will exit immediately after this call returns. 10012 * @param app object of the crashing app, null for the system server 10013 * @param crashInfo describing the exception 10014 */ 10015 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 10016 ProcessRecord r = findAppProcess(app, "Crash"); 10017 final String processName = app == null ? "system_server" 10018 : (r == null ? "unknown" : r.processName); 10019 10020 handleApplicationCrashInner("crash", r, processName, crashInfo); 10021 } 10022 10023 /* Native crash reporting uses this inner version because it needs to be somewhat 10024 * decoupled from the AM-managed cleanup lifecycle 10025 */ 10026 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 10027 ApplicationErrorReport.CrashInfo crashInfo) { 10028 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10029 UserHandle.getUserId(Binder.getCallingUid()), processName, 10030 r == null ? -1 : r.info.flags, 10031 crashInfo.exceptionClassName, 10032 crashInfo.exceptionMessage, 10033 crashInfo.throwFileName, 10034 crashInfo.throwLineNumber); 10035 10036 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10037 10038 crashApplication(r, crashInfo); 10039 } 10040 10041 public void handleApplicationStrictModeViolation( 10042 IBinder app, 10043 int violationMask, 10044 StrictMode.ViolationInfo info) { 10045 ProcessRecord r = findAppProcess(app, "StrictMode"); 10046 if (r == null) { 10047 return; 10048 } 10049 10050 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10051 Integer stackFingerprint = info.hashCode(); 10052 boolean logIt = true; 10053 synchronized (mAlreadyLoggedViolatedStacks) { 10054 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10055 logIt = false; 10056 // TODO: sub-sample into EventLog for these, with 10057 // the info.durationMillis? Then we'd get 10058 // the relative pain numbers, without logging all 10059 // the stack traces repeatedly. We'd want to do 10060 // likewise in the client code, which also does 10061 // dup suppression, before the Binder call. 10062 } else { 10063 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10064 mAlreadyLoggedViolatedStacks.clear(); 10065 } 10066 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10067 } 10068 } 10069 if (logIt) { 10070 logStrictModeViolationToDropBox(r, info); 10071 } 10072 } 10073 10074 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10075 AppErrorResult result = new AppErrorResult(); 10076 synchronized (this) { 10077 final long origId = Binder.clearCallingIdentity(); 10078 10079 Message msg = Message.obtain(); 10080 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10081 HashMap<String, Object> data = new HashMap<String, Object>(); 10082 data.put("result", result); 10083 data.put("app", r); 10084 data.put("violationMask", violationMask); 10085 data.put("info", info); 10086 msg.obj = data; 10087 mHandler.sendMessage(msg); 10088 10089 Binder.restoreCallingIdentity(origId); 10090 } 10091 int res = result.get(); 10092 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10093 } 10094 } 10095 10096 // Depending on the policy in effect, there could be a bunch of 10097 // these in quick succession so we try to batch these together to 10098 // minimize disk writes, number of dropbox entries, and maximize 10099 // compression, by having more fewer, larger records. 10100 private void logStrictModeViolationToDropBox( 10101 ProcessRecord process, 10102 StrictMode.ViolationInfo info) { 10103 if (info == null) { 10104 return; 10105 } 10106 final boolean isSystemApp = process == null || 10107 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10108 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10109 final String processName = process == null ? "unknown" : process.processName; 10110 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10111 final DropBoxManager dbox = (DropBoxManager) 10112 mContext.getSystemService(Context.DROPBOX_SERVICE); 10113 10114 // Exit early if the dropbox isn't configured to accept this report type. 10115 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10116 10117 boolean bufferWasEmpty; 10118 boolean needsFlush; 10119 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10120 synchronized (sb) { 10121 bufferWasEmpty = sb.length() == 0; 10122 appendDropBoxProcessHeaders(process, processName, sb); 10123 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10124 sb.append("System-App: ").append(isSystemApp).append("\n"); 10125 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10126 if (info.violationNumThisLoop != 0) { 10127 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10128 } 10129 if (info.numAnimationsRunning != 0) { 10130 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10131 } 10132 if (info.broadcastIntentAction != null) { 10133 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10134 } 10135 if (info.durationMillis != -1) { 10136 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10137 } 10138 if (info.numInstances != -1) { 10139 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10140 } 10141 if (info.tags != null) { 10142 for (String tag : info.tags) { 10143 sb.append("Span-Tag: ").append(tag).append("\n"); 10144 } 10145 } 10146 sb.append("\n"); 10147 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10148 sb.append(info.crashInfo.stackTrace); 10149 } 10150 sb.append("\n"); 10151 10152 // Only buffer up to ~64k. Various logging bits truncate 10153 // things at 128k. 10154 needsFlush = (sb.length() > 64 * 1024); 10155 } 10156 10157 // Flush immediately if the buffer's grown too large, or this 10158 // is a non-system app. Non-system apps are isolated with a 10159 // different tag & policy and not batched. 10160 // 10161 // Batching is useful during internal testing with 10162 // StrictMode settings turned up high. Without batching, 10163 // thousands of separate files could be created on boot. 10164 if (!isSystemApp || needsFlush) { 10165 new Thread("Error dump: " + dropboxTag) { 10166 @Override 10167 public void run() { 10168 String report; 10169 synchronized (sb) { 10170 report = sb.toString(); 10171 sb.delete(0, sb.length()); 10172 sb.trimToSize(); 10173 } 10174 if (report.length() != 0) { 10175 dbox.addText(dropboxTag, report); 10176 } 10177 } 10178 }.start(); 10179 return; 10180 } 10181 10182 // System app batching: 10183 if (!bufferWasEmpty) { 10184 // An existing dropbox-writing thread is outstanding, so 10185 // we don't need to start it up. The existing thread will 10186 // catch the buffer appends we just did. 10187 return; 10188 } 10189 10190 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10191 // (After this point, we shouldn't access AMS internal data structures.) 10192 new Thread("Error dump: " + dropboxTag) { 10193 @Override 10194 public void run() { 10195 // 5 second sleep to let stacks arrive and be batched together 10196 try { 10197 Thread.sleep(5000); // 5 seconds 10198 } catch (InterruptedException e) {} 10199 10200 String errorReport; 10201 synchronized (mStrictModeBuffer) { 10202 errorReport = mStrictModeBuffer.toString(); 10203 if (errorReport.length() == 0) { 10204 return; 10205 } 10206 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10207 mStrictModeBuffer.trimToSize(); 10208 } 10209 dbox.addText(dropboxTag, errorReport); 10210 } 10211 }.start(); 10212 } 10213 10214 /** 10215 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10216 * @param app object of the crashing app, null for the system server 10217 * @param tag reported by the caller 10218 * @param crashInfo describing the context of the error 10219 * @return true if the process should exit immediately (WTF is fatal) 10220 */ 10221 public boolean handleApplicationWtf(IBinder app, String tag, 10222 ApplicationErrorReport.CrashInfo crashInfo) { 10223 ProcessRecord r = findAppProcess(app, "WTF"); 10224 final String processName = app == null ? "system_server" 10225 : (r == null ? "unknown" : r.processName); 10226 10227 EventLog.writeEvent(EventLogTags.AM_WTF, 10228 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10229 processName, 10230 r == null ? -1 : r.info.flags, 10231 tag, crashInfo.exceptionMessage); 10232 10233 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10234 10235 if (r != null && r.pid != Process.myPid() && 10236 Settings.Global.getInt(mContext.getContentResolver(), 10237 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10238 crashApplication(r, crashInfo); 10239 return true; 10240 } else { 10241 return false; 10242 } 10243 } 10244 10245 /** 10246 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10247 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10248 */ 10249 private ProcessRecord findAppProcess(IBinder app, String reason) { 10250 if (app == null) { 10251 return null; 10252 } 10253 10254 synchronized (this) { 10255 final int NP = mProcessNames.getMap().size(); 10256 for (int ip=0; ip<NP; ip++) { 10257 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10258 final int NA = apps.size(); 10259 for (int ia=0; ia<NA; ia++) { 10260 ProcessRecord p = apps.valueAt(ia); 10261 if (p.thread != null && p.thread.asBinder() == app) { 10262 return p; 10263 } 10264 } 10265 } 10266 10267 Slog.w(TAG, "Can't find mystery application for " + reason 10268 + " from pid=" + Binder.getCallingPid() 10269 + " uid=" + Binder.getCallingUid() + ": " + app); 10270 return null; 10271 } 10272 } 10273 10274 /** 10275 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10276 * to append various headers to the dropbox log text. 10277 */ 10278 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10279 StringBuilder sb) { 10280 // Watchdog thread ends up invoking this function (with 10281 // a null ProcessRecord) to add the stack file to dropbox. 10282 // Do not acquire a lock on this (am) in such cases, as it 10283 // could cause a potential deadlock, if and when watchdog 10284 // is invoked due to unavailability of lock on am and it 10285 // would prevent watchdog from killing system_server. 10286 if (process == null) { 10287 sb.append("Process: ").append(processName).append("\n"); 10288 return; 10289 } 10290 // Note: ProcessRecord 'process' is guarded by the service 10291 // instance. (notably process.pkgList, which could otherwise change 10292 // concurrently during execution of this method) 10293 synchronized (this) { 10294 sb.append("Process: ").append(processName).append("\n"); 10295 int flags = process.info.flags; 10296 IPackageManager pm = AppGlobals.getPackageManager(); 10297 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10298 for (int ip=0; ip<process.pkgList.size(); ip++) { 10299 String pkg = process.pkgList.keyAt(ip); 10300 sb.append("Package: ").append(pkg); 10301 try { 10302 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10303 if (pi != null) { 10304 sb.append(" v").append(pi.versionCode); 10305 if (pi.versionName != null) { 10306 sb.append(" (").append(pi.versionName).append(")"); 10307 } 10308 } 10309 } catch (RemoteException e) { 10310 Slog.e(TAG, "Error getting package info: " + pkg, e); 10311 } 10312 sb.append("\n"); 10313 } 10314 } 10315 } 10316 10317 private static String processClass(ProcessRecord process) { 10318 if (process == null || process.pid == MY_PID) { 10319 return "system_server"; 10320 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10321 return "system_app"; 10322 } else { 10323 return "data_app"; 10324 } 10325 } 10326 10327 /** 10328 * Write a description of an error (crash, WTF, ANR) to the drop box. 10329 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10330 * @param process which caused the error, null means the system server 10331 * @param activity which triggered the error, null if unknown 10332 * @param parent activity related to the error, null if unknown 10333 * @param subject line related to the error, null if absent 10334 * @param report in long form describing the error, null if absent 10335 * @param logFile to include in the report, null if none 10336 * @param crashInfo giving an application stack trace, null if absent 10337 */ 10338 public void addErrorToDropBox(String eventType, 10339 ProcessRecord process, String processName, ActivityRecord activity, 10340 ActivityRecord parent, String subject, 10341 final String report, final File logFile, 10342 final ApplicationErrorReport.CrashInfo crashInfo) { 10343 // NOTE -- this must never acquire the ActivityManagerService lock, 10344 // otherwise the watchdog may be prevented from resetting the system. 10345 10346 final String dropboxTag = processClass(process) + "_" + eventType; 10347 final DropBoxManager dbox = (DropBoxManager) 10348 mContext.getSystemService(Context.DROPBOX_SERVICE); 10349 10350 // Exit early if the dropbox isn't configured to accept this report type. 10351 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10352 10353 final StringBuilder sb = new StringBuilder(1024); 10354 appendDropBoxProcessHeaders(process, processName, sb); 10355 if (activity != null) { 10356 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10357 } 10358 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10359 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10360 } 10361 if (parent != null && parent != activity) { 10362 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10363 } 10364 if (subject != null) { 10365 sb.append("Subject: ").append(subject).append("\n"); 10366 } 10367 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10368 if (Debug.isDebuggerConnected()) { 10369 sb.append("Debugger: Connected\n"); 10370 } 10371 sb.append("\n"); 10372 10373 // Do the rest in a worker thread to avoid blocking the caller on I/O 10374 // (After this point, we shouldn't access AMS internal data structures.) 10375 Thread worker = new Thread("Error dump: " + dropboxTag) { 10376 @Override 10377 public void run() { 10378 if (report != null) { 10379 sb.append(report); 10380 } 10381 if (logFile != null) { 10382 try { 10383 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10384 "\n\n[[TRUNCATED]]")); 10385 } catch (IOException e) { 10386 Slog.e(TAG, "Error reading " + logFile, e); 10387 } 10388 } 10389 if (crashInfo != null && crashInfo.stackTrace != null) { 10390 sb.append(crashInfo.stackTrace); 10391 } 10392 10393 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10394 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10395 if (lines > 0) { 10396 sb.append("\n"); 10397 10398 // Merge several logcat streams, and take the last N lines 10399 InputStreamReader input = null; 10400 try { 10401 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10402 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10403 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10404 10405 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10406 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10407 input = new InputStreamReader(logcat.getInputStream()); 10408 10409 int num; 10410 char[] buf = new char[8192]; 10411 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10412 } catch (IOException e) { 10413 Slog.e(TAG, "Error running logcat", e); 10414 } finally { 10415 if (input != null) try { input.close(); } catch (IOException e) {} 10416 } 10417 } 10418 10419 dbox.addText(dropboxTag, sb.toString()); 10420 } 10421 }; 10422 10423 if (process == null) { 10424 // If process is null, we are being called from some internal code 10425 // and may be about to die -- run this synchronously. 10426 worker.run(); 10427 } else { 10428 worker.start(); 10429 } 10430 } 10431 10432 /** 10433 * Bring up the "unexpected error" dialog box for a crashing app. 10434 * Deal with edge cases (intercepts from instrumented applications, 10435 * ActivityController, error intent receivers, that sort of thing). 10436 * @param r the application crashing 10437 * @param crashInfo describing the failure 10438 */ 10439 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10440 long timeMillis = System.currentTimeMillis(); 10441 String shortMsg = crashInfo.exceptionClassName; 10442 String longMsg = crashInfo.exceptionMessage; 10443 String stackTrace = crashInfo.stackTrace; 10444 if (shortMsg != null && longMsg != null) { 10445 longMsg = shortMsg + ": " + longMsg; 10446 } else if (shortMsg != null) { 10447 longMsg = shortMsg; 10448 } 10449 10450 AppErrorResult result = new AppErrorResult(); 10451 synchronized (this) { 10452 if (mController != null) { 10453 try { 10454 String name = r != null ? r.processName : null; 10455 int pid = r != null ? r.pid : Binder.getCallingPid(); 10456 if (!mController.appCrashed(name, pid, 10457 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10458 Slog.w(TAG, "Force-killing crashed app " + name 10459 + " at watcher's request"); 10460 Process.killProcess(pid); 10461 return; 10462 } 10463 } catch (RemoteException e) { 10464 mController = null; 10465 Watchdog.getInstance().setActivityController(null); 10466 } 10467 } 10468 10469 final long origId = Binder.clearCallingIdentity(); 10470 10471 // If this process is running instrumentation, finish it. 10472 if (r != null && r.instrumentationClass != null) { 10473 Slog.w(TAG, "Error in app " + r.processName 10474 + " running instrumentation " + r.instrumentationClass + ":"); 10475 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10476 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10477 Bundle info = new Bundle(); 10478 info.putString("shortMsg", shortMsg); 10479 info.putString("longMsg", longMsg); 10480 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10481 Binder.restoreCallingIdentity(origId); 10482 return; 10483 } 10484 10485 // If we can't identify the process or it's already exceeded its crash quota, 10486 // quit right away without showing a crash dialog. 10487 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10488 Binder.restoreCallingIdentity(origId); 10489 return; 10490 } 10491 10492 Message msg = Message.obtain(); 10493 msg.what = SHOW_ERROR_MSG; 10494 HashMap data = new HashMap(); 10495 data.put("result", result); 10496 data.put("app", r); 10497 msg.obj = data; 10498 mHandler.sendMessage(msg); 10499 10500 Binder.restoreCallingIdentity(origId); 10501 } 10502 10503 int res = result.get(); 10504 10505 Intent appErrorIntent = null; 10506 synchronized (this) { 10507 if (r != null && !r.isolated) { 10508 // XXX Can't keep track of crash time for isolated processes, 10509 // since they don't have a persistent identity. 10510 mProcessCrashTimes.put(r.info.processName, r.uid, 10511 SystemClock.uptimeMillis()); 10512 } 10513 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10514 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10515 } 10516 } 10517 10518 if (appErrorIntent != null) { 10519 try { 10520 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10521 } catch (ActivityNotFoundException e) { 10522 Slog.w(TAG, "bug report receiver dissappeared", e); 10523 } 10524 } 10525 } 10526 10527 Intent createAppErrorIntentLocked(ProcessRecord r, 10528 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10529 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10530 if (report == null) { 10531 return null; 10532 } 10533 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10534 result.setComponent(r.errorReportReceiver); 10535 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10536 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10537 return result; 10538 } 10539 10540 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10541 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10542 if (r.errorReportReceiver == null) { 10543 return null; 10544 } 10545 10546 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10547 return null; 10548 } 10549 10550 ApplicationErrorReport report = new ApplicationErrorReport(); 10551 report.packageName = r.info.packageName; 10552 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10553 report.processName = r.processName; 10554 report.time = timeMillis; 10555 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10556 10557 if (r.crashing || r.forceCrashReport) { 10558 report.type = ApplicationErrorReport.TYPE_CRASH; 10559 report.crashInfo = crashInfo; 10560 } else if (r.notResponding) { 10561 report.type = ApplicationErrorReport.TYPE_ANR; 10562 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10563 10564 report.anrInfo.activity = r.notRespondingReport.tag; 10565 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10566 report.anrInfo.info = r.notRespondingReport.longMsg; 10567 } 10568 10569 return report; 10570 } 10571 10572 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10573 enforceNotIsolatedCaller("getProcessesInErrorState"); 10574 // assume our apps are happy - lazy create the list 10575 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10576 10577 final boolean allUsers = ActivityManager.checkUidPermission( 10578 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10579 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10580 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10581 10582 synchronized (this) { 10583 10584 // iterate across all processes 10585 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10586 ProcessRecord app = mLruProcesses.get(i); 10587 if (!allUsers && app.userId != userId) { 10588 continue; 10589 } 10590 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10591 // This one's in trouble, so we'll generate a report for it 10592 // crashes are higher priority (in case there's a crash *and* an anr) 10593 ActivityManager.ProcessErrorStateInfo report = null; 10594 if (app.crashing) { 10595 report = app.crashingReport; 10596 } else if (app.notResponding) { 10597 report = app.notRespondingReport; 10598 } 10599 10600 if (report != null) { 10601 if (errList == null) { 10602 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10603 } 10604 errList.add(report); 10605 } else { 10606 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10607 " crashing = " + app.crashing + 10608 " notResponding = " + app.notResponding); 10609 } 10610 } 10611 } 10612 } 10613 10614 return errList; 10615 } 10616 10617 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10618 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10619 if (currApp != null) { 10620 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10621 } 10622 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10623 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10624 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10625 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10626 if (currApp != null) { 10627 currApp.lru = 0; 10628 } 10629 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10630 } else if (adj >= ProcessList.SERVICE_ADJ) { 10631 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10632 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10633 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10634 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10635 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10636 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10637 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10638 } else { 10639 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10640 } 10641 } 10642 10643 private void fillInProcMemInfo(ProcessRecord app, 10644 ActivityManager.RunningAppProcessInfo outInfo) { 10645 outInfo.pid = app.pid; 10646 outInfo.uid = app.info.uid; 10647 if (mHeavyWeightProcess == app) { 10648 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10649 } 10650 if (app.persistent) { 10651 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10652 } 10653 if (app.activities.size() > 0) { 10654 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10655 } 10656 outInfo.lastTrimLevel = app.trimMemoryLevel; 10657 int adj = app.curAdj; 10658 outInfo.importance = oomAdjToImportance(adj, outInfo); 10659 outInfo.importanceReasonCode = app.adjTypeCode; 10660 outInfo.processState = app.curProcState; 10661 } 10662 10663 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10664 enforceNotIsolatedCaller("getRunningAppProcesses"); 10665 // Lazy instantiation of list 10666 List<ActivityManager.RunningAppProcessInfo> runList = null; 10667 final boolean allUsers = ActivityManager.checkUidPermission( 10668 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10669 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10670 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10671 synchronized (this) { 10672 // Iterate across all processes 10673 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10674 ProcessRecord app = mLruProcesses.get(i); 10675 if (!allUsers && app.userId != userId) { 10676 continue; 10677 } 10678 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10679 // Generate process state info for running application 10680 ActivityManager.RunningAppProcessInfo currApp = 10681 new ActivityManager.RunningAppProcessInfo(app.processName, 10682 app.pid, app.getPackageList()); 10683 fillInProcMemInfo(app, currApp); 10684 if (app.adjSource instanceof ProcessRecord) { 10685 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10686 currApp.importanceReasonImportance = oomAdjToImportance( 10687 app.adjSourceOom, null); 10688 } else if (app.adjSource instanceof ActivityRecord) { 10689 ActivityRecord r = (ActivityRecord)app.adjSource; 10690 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10691 } 10692 if (app.adjTarget instanceof ComponentName) { 10693 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10694 } 10695 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10696 // + " lru=" + currApp.lru); 10697 if (runList == null) { 10698 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10699 } 10700 runList.add(currApp); 10701 } 10702 } 10703 } 10704 return runList; 10705 } 10706 10707 public List<ApplicationInfo> getRunningExternalApplications() { 10708 enforceNotIsolatedCaller("getRunningExternalApplications"); 10709 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10710 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10711 if (runningApps != null && runningApps.size() > 0) { 10712 Set<String> extList = new HashSet<String>(); 10713 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10714 if (app.pkgList != null) { 10715 for (String pkg : app.pkgList) { 10716 extList.add(pkg); 10717 } 10718 } 10719 } 10720 IPackageManager pm = AppGlobals.getPackageManager(); 10721 for (String pkg : extList) { 10722 try { 10723 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10724 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10725 retList.add(info); 10726 } 10727 } catch (RemoteException e) { 10728 } 10729 } 10730 } 10731 return retList; 10732 } 10733 10734 @Override 10735 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10736 enforceNotIsolatedCaller("getMyMemoryState"); 10737 synchronized (this) { 10738 ProcessRecord proc; 10739 synchronized (mPidsSelfLocked) { 10740 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10741 } 10742 fillInProcMemInfo(proc, outInfo); 10743 } 10744 } 10745 10746 @Override 10747 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10748 if (checkCallingPermission(android.Manifest.permission.DUMP) 10749 != PackageManager.PERMISSION_GRANTED) { 10750 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10751 + Binder.getCallingPid() 10752 + ", uid=" + Binder.getCallingUid() 10753 + " without permission " 10754 + android.Manifest.permission.DUMP); 10755 return; 10756 } 10757 10758 boolean dumpAll = false; 10759 boolean dumpClient = false; 10760 String dumpPackage = null; 10761 10762 int opti = 0; 10763 while (opti < args.length) { 10764 String opt = args[opti]; 10765 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10766 break; 10767 } 10768 opti++; 10769 if ("-a".equals(opt)) { 10770 dumpAll = true; 10771 } else if ("-c".equals(opt)) { 10772 dumpClient = true; 10773 } else if ("-h".equals(opt)) { 10774 pw.println("Activity manager dump options:"); 10775 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10776 pw.println(" cmd may be one of:"); 10777 pw.println(" a[ctivities]: activity stack state"); 10778 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10779 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10780 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10781 pw.println(" o[om]: out of memory management"); 10782 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10783 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10784 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10785 pw.println(" service [COMP_SPEC]: service client-side state"); 10786 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10787 pw.println(" all: dump all activities"); 10788 pw.println(" top: dump the top activity"); 10789 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10790 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10791 pw.println(" a partial substring in a component name, a"); 10792 pw.println(" hex object identifier."); 10793 pw.println(" -a: include all available server state."); 10794 pw.println(" -c: include client state."); 10795 return; 10796 } else { 10797 pw.println("Unknown argument: " + opt + "; use -h for help"); 10798 } 10799 } 10800 10801 long origId = Binder.clearCallingIdentity(); 10802 boolean more = false; 10803 // Is the caller requesting to dump a particular piece of data? 10804 if (opti < args.length) { 10805 String cmd = args[opti]; 10806 opti++; 10807 if ("activities".equals(cmd) || "a".equals(cmd)) { 10808 synchronized (this) { 10809 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10810 } 10811 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10812 String[] newArgs; 10813 String name; 10814 if (opti >= args.length) { 10815 name = null; 10816 newArgs = EMPTY_STRING_ARRAY; 10817 } else { 10818 name = args[opti]; 10819 opti++; 10820 newArgs = new String[args.length - opti]; 10821 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10822 args.length - opti); 10823 } 10824 synchronized (this) { 10825 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10826 } 10827 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10828 String[] newArgs; 10829 String name; 10830 if (opti >= args.length) { 10831 name = null; 10832 newArgs = EMPTY_STRING_ARRAY; 10833 } else { 10834 name = args[opti]; 10835 opti++; 10836 newArgs = new String[args.length - opti]; 10837 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10838 args.length - opti); 10839 } 10840 synchronized (this) { 10841 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10842 } 10843 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10844 String[] newArgs; 10845 String name; 10846 if (opti >= args.length) { 10847 name = null; 10848 newArgs = EMPTY_STRING_ARRAY; 10849 } else { 10850 name = args[opti]; 10851 opti++; 10852 newArgs = new String[args.length - opti]; 10853 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10854 args.length - opti); 10855 } 10856 synchronized (this) { 10857 dumpProcessesLocked(fd, pw, args, opti, true, name); 10858 } 10859 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10860 synchronized (this) { 10861 dumpOomLocked(fd, pw, args, opti, true); 10862 } 10863 } else if ("provider".equals(cmd)) { 10864 String[] newArgs; 10865 String name; 10866 if (opti >= args.length) { 10867 name = null; 10868 newArgs = EMPTY_STRING_ARRAY; 10869 } else { 10870 name = args[opti]; 10871 opti++; 10872 newArgs = new String[args.length - opti]; 10873 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10874 } 10875 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10876 pw.println("No providers match: " + name); 10877 pw.println("Use -h for help."); 10878 } 10879 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10880 synchronized (this) { 10881 dumpProvidersLocked(fd, pw, args, opti, true, null); 10882 } 10883 } else if ("service".equals(cmd)) { 10884 String[] newArgs; 10885 String name; 10886 if (opti >= args.length) { 10887 name = null; 10888 newArgs = EMPTY_STRING_ARRAY; 10889 } else { 10890 name = args[opti]; 10891 opti++; 10892 newArgs = new String[args.length - opti]; 10893 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10894 args.length - opti); 10895 } 10896 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10897 pw.println("No services match: " + name); 10898 pw.println("Use -h for help."); 10899 } 10900 } else if ("package".equals(cmd)) { 10901 String[] newArgs; 10902 if (opti >= args.length) { 10903 pw.println("package: no package name specified"); 10904 pw.println("Use -h for help."); 10905 } else { 10906 dumpPackage = args[opti]; 10907 opti++; 10908 newArgs = new String[args.length - opti]; 10909 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10910 args.length - opti); 10911 args = newArgs; 10912 opti = 0; 10913 more = true; 10914 } 10915 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10916 synchronized (this) { 10917 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10918 } 10919 } else { 10920 // Dumping a single activity? 10921 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10922 pw.println("Bad activity command, or no activities match: " + cmd); 10923 pw.println("Use -h for help."); 10924 } 10925 } 10926 if (!more) { 10927 Binder.restoreCallingIdentity(origId); 10928 return; 10929 } 10930 } 10931 10932 // No piece of data specified, dump everything. 10933 synchronized (this) { 10934 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10935 pw.println(); 10936 if (dumpAll) { 10937 pw.println("-------------------------------------------------------------------------------"); 10938 } 10939 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10940 pw.println(); 10941 if (dumpAll) { 10942 pw.println("-------------------------------------------------------------------------------"); 10943 } 10944 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10945 pw.println(); 10946 if (dumpAll) { 10947 pw.println("-------------------------------------------------------------------------------"); 10948 } 10949 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10950 pw.println(); 10951 if (dumpAll) { 10952 pw.println("-------------------------------------------------------------------------------"); 10953 } 10954 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10955 pw.println(); 10956 if (dumpAll) { 10957 pw.println("-------------------------------------------------------------------------------"); 10958 } 10959 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10960 } 10961 Binder.restoreCallingIdentity(origId); 10962 } 10963 10964 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10965 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10966 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10967 10968 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10969 dumpPackage); 10970 boolean needSep = printedAnything; 10971 10972 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10973 dumpPackage, needSep, " mFocusedActivity: "); 10974 if (printed) { 10975 printedAnything = true; 10976 needSep = false; 10977 } 10978 10979 if (dumpPackage == null) { 10980 if (needSep) { 10981 pw.println(); 10982 } 10983 needSep = true; 10984 printedAnything = true; 10985 mStackSupervisor.dump(pw, " "); 10986 } 10987 10988 if (mRecentTasks.size() > 0) { 10989 boolean printedHeader = false; 10990 10991 final int N = mRecentTasks.size(); 10992 for (int i=0; i<N; i++) { 10993 TaskRecord tr = mRecentTasks.get(i); 10994 if (dumpPackage != null) { 10995 if (tr.realActivity == null || 10996 !dumpPackage.equals(tr.realActivity)) { 10997 continue; 10998 } 10999 } 11000 if (!printedHeader) { 11001 if (needSep) { 11002 pw.println(); 11003 } 11004 pw.println(" Recent tasks:"); 11005 printedHeader = true; 11006 printedAnything = true; 11007 } 11008 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 11009 pw.println(tr); 11010 if (dumpAll) { 11011 mRecentTasks.get(i).dump(pw, " "); 11012 } 11013 } 11014 } 11015 11016 if (!printedAnything) { 11017 pw.println(" (nothing)"); 11018 } 11019 } 11020 11021 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11022 int opti, boolean dumpAll, String dumpPackage) { 11023 boolean needSep = false; 11024 boolean printedAnything = false; 11025 int numPers = 0; 11026 11027 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11028 11029 if (dumpAll) { 11030 final int NP = mProcessNames.getMap().size(); 11031 for (int ip=0; ip<NP; ip++) { 11032 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11033 final int NA = procs.size(); 11034 for (int ia=0; ia<NA; ia++) { 11035 ProcessRecord r = procs.valueAt(ia); 11036 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11037 continue; 11038 } 11039 if (!needSep) { 11040 pw.println(" All known processes:"); 11041 needSep = true; 11042 printedAnything = true; 11043 } 11044 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11045 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11046 pw.print(" "); pw.println(r); 11047 r.dump(pw, " "); 11048 if (r.persistent) { 11049 numPers++; 11050 } 11051 } 11052 } 11053 } 11054 11055 if (mIsolatedProcesses.size() > 0) { 11056 boolean printed = false; 11057 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11058 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11059 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11060 continue; 11061 } 11062 if (!printed) { 11063 if (needSep) { 11064 pw.println(); 11065 } 11066 pw.println(" Isolated process list (sorted by uid):"); 11067 printedAnything = true; 11068 printed = true; 11069 needSep = true; 11070 } 11071 pw.println(String.format("%sIsolated #%2d: %s", 11072 " ", i, r.toString())); 11073 } 11074 } 11075 11076 if (mLruProcesses.size() > 0) { 11077 if (needSep) { 11078 pw.println(); 11079 } 11080 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11081 pw.print(" total, non-act at "); 11082 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11083 pw.print(", non-svc at "); 11084 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11085 pw.println("):"); 11086 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11087 needSep = true; 11088 printedAnything = true; 11089 } 11090 11091 if (dumpAll || dumpPackage != null) { 11092 synchronized (mPidsSelfLocked) { 11093 boolean printed = false; 11094 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11095 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11096 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11097 continue; 11098 } 11099 if (!printed) { 11100 if (needSep) pw.println(); 11101 needSep = true; 11102 pw.println(" PID mappings:"); 11103 printed = true; 11104 printedAnything = true; 11105 } 11106 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11107 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11108 } 11109 } 11110 } 11111 11112 if (mForegroundProcesses.size() > 0) { 11113 synchronized (mPidsSelfLocked) { 11114 boolean printed = false; 11115 for (int i=0; i<mForegroundProcesses.size(); i++) { 11116 ProcessRecord r = mPidsSelfLocked.get( 11117 mForegroundProcesses.valueAt(i).pid); 11118 if (dumpPackage != null && (r == null 11119 || !r.pkgList.containsKey(dumpPackage))) { 11120 continue; 11121 } 11122 if (!printed) { 11123 if (needSep) pw.println(); 11124 needSep = true; 11125 pw.println(" Foreground Processes:"); 11126 printed = true; 11127 printedAnything = true; 11128 } 11129 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11130 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11131 } 11132 } 11133 } 11134 11135 if (mPersistentStartingProcesses.size() > 0) { 11136 if (needSep) pw.println(); 11137 needSep = true; 11138 printedAnything = true; 11139 pw.println(" Persisent processes that are starting:"); 11140 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11141 "Starting Norm", "Restarting PERS", dumpPackage); 11142 } 11143 11144 if (mRemovedProcesses.size() > 0) { 11145 if (needSep) pw.println(); 11146 needSep = true; 11147 printedAnything = true; 11148 pw.println(" Processes that are being removed:"); 11149 dumpProcessList(pw, this, mRemovedProcesses, " ", 11150 "Removed Norm", "Removed PERS", dumpPackage); 11151 } 11152 11153 if (mProcessesOnHold.size() > 0) { 11154 if (needSep) pw.println(); 11155 needSep = true; 11156 printedAnything = true; 11157 pw.println(" Processes that are on old until the system is ready:"); 11158 dumpProcessList(pw, this, mProcessesOnHold, " ", 11159 "OnHold Norm", "OnHold PERS", dumpPackage); 11160 } 11161 11162 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11163 11164 if (mProcessCrashTimes.getMap().size() > 0) { 11165 boolean printed = false; 11166 long now = SystemClock.uptimeMillis(); 11167 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11168 final int NP = pmap.size(); 11169 for (int ip=0; ip<NP; ip++) { 11170 String pname = pmap.keyAt(ip); 11171 SparseArray<Long> uids = pmap.valueAt(ip); 11172 final int N = uids.size(); 11173 for (int i=0; i<N; i++) { 11174 int puid = uids.keyAt(i); 11175 ProcessRecord r = mProcessNames.get(pname, puid); 11176 if (dumpPackage != null && (r == null 11177 || !r.pkgList.containsKey(dumpPackage))) { 11178 continue; 11179 } 11180 if (!printed) { 11181 if (needSep) pw.println(); 11182 needSep = true; 11183 pw.println(" Time since processes crashed:"); 11184 printed = true; 11185 printedAnything = true; 11186 } 11187 pw.print(" Process "); pw.print(pname); 11188 pw.print(" uid "); pw.print(puid); 11189 pw.print(": last crashed "); 11190 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11191 pw.println(" ago"); 11192 } 11193 } 11194 } 11195 11196 if (mBadProcesses.getMap().size() > 0) { 11197 boolean printed = false; 11198 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11199 final int NP = pmap.size(); 11200 for (int ip=0; ip<NP; ip++) { 11201 String pname = pmap.keyAt(ip); 11202 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11203 final int N = uids.size(); 11204 for (int i=0; i<N; i++) { 11205 int puid = uids.keyAt(i); 11206 ProcessRecord r = mProcessNames.get(pname, puid); 11207 if (dumpPackage != null && (r == null 11208 || !r.pkgList.containsKey(dumpPackage))) { 11209 continue; 11210 } 11211 if (!printed) { 11212 if (needSep) pw.println(); 11213 needSep = true; 11214 pw.println(" Bad processes:"); 11215 printedAnything = true; 11216 } 11217 BadProcessInfo info = uids.valueAt(i); 11218 pw.print(" Bad process "); pw.print(pname); 11219 pw.print(" uid "); pw.print(puid); 11220 pw.print(": crashed at time "); pw.println(info.time); 11221 if (info.shortMsg != null) { 11222 pw.print(" Short msg: "); pw.println(info.shortMsg); 11223 } 11224 if (info.longMsg != null) { 11225 pw.print(" Long msg: "); pw.println(info.longMsg); 11226 } 11227 if (info.stack != null) { 11228 pw.println(" Stack:"); 11229 int lastPos = 0; 11230 for (int pos=0; pos<info.stack.length(); pos++) { 11231 if (info.stack.charAt(pos) == '\n') { 11232 pw.print(" "); 11233 pw.write(info.stack, lastPos, pos-lastPos); 11234 pw.println(); 11235 lastPos = pos+1; 11236 } 11237 } 11238 if (lastPos < info.stack.length()) { 11239 pw.print(" "); 11240 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11241 pw.println(); 11242 } 11243 } 11244 } 11245 } 11246 } 11247 11248 if (dumpPackage == null) { 11249 pw.println(); 11250 needSep = false; 11251 pw.println(" mStartedUsers:"); 11252 for (int i=0; i<mStartedUsers.size(); i++) { 11253 UserStartedState uss = mStartedUsers.valueAt(i); 11254 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11255 pw.print(": "); uss.dump("", pw); 11256 } 11257 pw.print(" mStartedUserArray: ["); 11258 for (int i=0; i<mStartedUserArray.length; i++) { 11259 if (i > 0) pw.print(", "); 11260 pw.print(mStartedUserArray[i]); 11261 } 11262 pw.println("]"); 11263 pw.print(" mUserLru: ["); 11264 for (int i=0; i<mUserLru.size(); i++) { 11265 if (i > 0) pw.print(", "); 11266 pw.print(mUserLru.get(i)); 11267 } 11268 pw.println("]"); 11269 if (dumpAll) { 11270 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11271 } 11272 } 11273 if (mHomeProcess != null && (dumpPackage == null 11274 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11275 if (needSep) { 11276 pw.println(); 11277 needSep = false; 11278 } 11279 pw.println(" mHomeProcess: " + mHomeProcess); 11280 } 11281 if (mPreviousProcess != null && (dumpPackage == null 11282 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11283 if (needSep) { 11284 pw.println(); 11285 needSep = false; 11286 } 11287 pw.println(" mPreviousProcess: " + mPreviousProcess); 11288 } 11289 if (dumpAll) { 11290 StringBuilder sb = new StringBuilder(128); 11291 sb.append(" mPreviousProcessVisibleTime: "); 11292 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11293 pw.println(sb); 11294 } 11295 if (mHeavyWeightProcess != null && (dumpPackage == null 11296 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11297 if (needSep) { 11298 pw.println(); 11299 needSep = false; 11300 } 11301 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11302 } 11303 if (dumpPackage == null) { 11304 pw.println(" mConfiguration: " + mConfiguration); 11305 } 11306 if (dumpAll) { 11307 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11308 if (mCompatModePackages.getPackages().size() > 0) { 11309 boolean printed = false; 11310 for (Map.Entry<String, Integer> entry 11311 : mCompatModePackages.getPackages().entrySet()) { 11312 String pkg = entry.getKey(); 11313 int mode = entry.getValue(); 11314 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11315 continue; 11316 } 11317 if (!printed) { 11318 pw.println(" mScreenCompatPackages:"); 11319 printed = true; 11320 } 11321 pw.print(" "); pw.print(pkg); pw.print(": "); 11322 pw.print(mode); pw.println(); 11323 } 11324 } 11325 } 11326 if (dumpPackage == null) { 11327 if (mSleeping || mWentToSleep || mLockScreenShown) { 11328 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11329 + " mLockScreenShown " + mLockScreenShown); 11330 } 11331 if (mShuttingDown || mRunningVoice) { 11332 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11333 } 11334 } 11335 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11336 || mOrigWaitForDebugger) { 11337 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11338 || dumpPackage.equals(mOrigDebugApp)) { 11339 if (needSep) { 11340 pw.println(); 11341 needSep = false; 11342 } 11343 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11344 + " mDebugTransient=" + mDebugTransient 11345 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11346 } 11347 } 11348 if (mOpenGlTraceApp != null) { 11349 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11350 if (needSep) { 11351 pw.println(); 11352 needSep = false; 11353 } 11354 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11355 } 11356 } 11357 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11358 || mProfileFd != null) { 11359 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11360 if (needSep) { 11361 pw.println(); 11362 needSep = false; 11363 } 11364 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11365 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11366 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11367 + mAutoStopProfiler); 11368 } 11369 } 11370 if (dumpPackage == null) { 11371 if (mAlwaysFinishActivities || mController != null) { 11372 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11373 + " mController=" + mController); 11374 } 11375 if (dumpAll) { 11376 pw.println(" Total persistent processes: " + numPers); 11377 pw.println(" mProcessesReady=" + mProcessesReady 11378 + " mSystemReady=" + mSystemReady); 11379 pw.println(" mBooting=" + mBooting 11380 + " mBooted=" + mBooted 11381 + " mFactoryTest=" + mFactoryTest); 11382 pw.print(" mLastPowerCheckRealtime="); 11383 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11384 pw.println(""); 11385 pw.print(" mLastPowerCheckUptime="); 11386 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11387 pw.println(""); 11388 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11389 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11390 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11391 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11392 + " (" + mLruProcesses.size() + " total)" 11393 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11394 + " mNumServiceProcs=" + mNumServiceProcs 11395 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11396 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11397 + " mLastMemoryLevel" + mLastMemoryLevel 11398 + " mLastNumProcesses" + mLastNumProcesses); 11399 long now = SystemClock.uptimeMillis(); 11400 pw.print(" mLastIdleTime="); 11401 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11402 pw.print(" mLowRamSinceLastIdle="); 11403 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11404 pw.println(); 11405 } 11406 } 11407 11408 if (!printedAnything) { 11409 pw.println(" (nothing)"); 11410 } 11411 } 11412 11413 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11414 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11415 if (mProcessesToGc.size() > 0) { 11416 boolean printed = false; 11417 long now = SystemClock.uptimeMillis(); 11418 for (int i=0; i<mProcessesToGc.size(); i++) { 11419 ProcessRecord proc = mProcessesToGc.get(i); 11420 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11421 continue; 11422 } 11423 if (!printed) { 11424 if (needSep) pw.println(); 11425 needSep = true; 11426 pw.println(" Processes that are waiting to GC:"); 11427 printed = true; 11428 } 11429 pw.print(" Process "); pw.println(proc); 11430 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11431 pw.print(", last gced="); 11432 pw.print(now-proc.lastRequestedGc); 11433 pw.print(" ms ago, last lowMem="); 11434 pw.print(now-proc.lastLowMemory); 11435 pw.println(" ms ago"); 11436 11437 } 11438 } 11439 return needSep; 11440 } 11441 11442 void printOomLevel(PrintWriter pw, String name, int adj) { 11443 pw.print(" "); 11444 if (adj >= 0) { 11445 pw.print(' '); 11446 if (adj < 10) pw.print(' '); 11447 } else { 11448 if (adj > -10) pw.print(' '); 11449 } 11450 pw.print(adj); 11451 pw.print(": "); 11452 pw.print(name); 11453 pw.print(" ("); 11454 pw.print(mProcessList.getMemLevel(adj)/1024); 11455 pw.println(" kB)"); 11456 } 11457 11458 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11459 int opti, boolean dumpAll) { 11460 boolean needSep = false; 11461 11462 if (mLruProcesses.size() > 0) { 11463 if (needSep) pw.println(); 11464 needSep = true; 11465 pw.println(" OOM levels:"); 11466 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11467 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11468 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11469 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11470 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11471 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11472 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11473 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11474 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11475 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11476 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11477 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11478 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11479 11480 if (needSep) pw.println(); 11481 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11482 pw.print(" total, non-act at "); 11483 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11484 pw.print(", non-svc at "); 11485 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11486 pw.println("):"); 11487 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11488 needSep = true; 11489 } 11490 11491 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11492 11493 pw.println(); 11494 pw.println(" mHomeProcess: " + mHomeProcess); 11495 pw.println(" mPreviousProcess: " + mPreviousProcess); 11496 if (mHeavyWeightProcess != null) { 11497 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11498 } 11499 11500 return true; 11501 } 11502 11503 /** 11504 * There are three ways to call this: 11505 * - no provider specified: dump all the providers 11506 * - a flattened component name that matched an existing provider was specified as the 11507 * first arg: dump that one provider 11508 * - the first arg isn't the flattened component name of an existing provider: 11509 * dump all providers whose component contains the first arg as a substring 11510 */ 11511 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11512 int opti, boolean dumpAll) { 11513 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11514 } 11515 11516 static class ItemMatcher { 11517 ArrayList<ComponentName> components; 11518 ArrayList<String> strings; 11519 ArrayList<Integer> objects; 11520 boolean all; 11521 11522 ItemMatcher() { 11523 all = true; 11524 } 11525 11526 void build(String name) { 11527 ComponentName componentName = ComponentName.unflattenFromString(name); 11528 if (componentName != null) { 11529 if (components == null) { 11530 components = new ArrayList<ComponentName>(); 11531 } 11532 components.add(componentName); 11533 all = false; 11534 } else { 11535 int objectId = 0; 11536 // Not a '/' separated full component name; maybe an object ID? 11537 try { 11538 objectId = Integer.parseInt(name, 16); 11539 if (objects == null) { 11540 objects = new ArrayList<Integer>(); 11541 } 11542 objects.add(objectId); 11543 all = false; 11544 } catch (RuntimeException e) { 11545 // Not an integer; just do string match. 11546 if (strings == null) { 11547 strings = new ArrayList<String>(); 11548 } 11549 strings.add(name); 11550 all = false; 11551 } 11552 } 11553 } 11554 11555 int build(String[] args, int opti) { 11556 for (; opti<args.length; opti++) { 11557 String name = args[opti]; 11558 if ("--".equals(name)) { 11559 return opti+1; 11560 } 11561 build(name); 11562 } 11563 return opti; 11564 } 11565 11566 boolean match(Object object, ComponentName comp) { 11567 if (all) { 11568 return true; 11569 } 11570 if (components != null) { 11571 for (int i=0; i<components.size(); i++) { 11572 if (components.get(i).equals(comp)) { 11573 return true; 11574 } 11575 } 11576 } 11577 if (objects != null) { 11578 for (int i=0; i<objects.size(); i++) { 11579 if (System.identityHashCode(object) == objects.get(i)) { 11580 return true; 11581 } 11582 } 11583 } 11584 if (strings != null) { 11585 String flat = comp.flattenToString(); 11586 for (int i=0; i<strings.size(); i++) { 11587 if (flat.contains(strings.get(i))) { 11588 return true; 11589 } 11590 } 11591 } 11592 return false; 11593 } 11594 } 11595 11596 /** 11597 * There are three things that cmd can be: 11598 * - a flattened component name that matches an existing activity 11599 * - the cmd arg isn't the flattened component name of an existing activity: 11600 * dump all activity whose component contains the cmd as a substring 11601 * - A hex number of the ActivityRecord object instance. 11602 */ 11603 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11604 int opti, boolean dumpAll) { 11605 ArrayList<ActivityRecord> activities; 11606 11607 synchronized (this) { 11608 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11609 } 11610 11611 if (activities.size() <= 0) { 11612 return false; 11613 } 11614 11615 String[] newArgs = new String[args.length - opti]; 11616 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11617 11618 TaskRecord lastTask = null; 11619 boolean needSep = false; 11620 for (int i=activities.size()-1; i>=0; i--) { 11621 ActivityRecord r = activities.get(i); 11622 if (needSep) { 11623 pw.println(); 11624 } 11625 needSep = true; 11626 synchronized (this) { 11627 if (lastTask != r.task) { 11628 lastTask = r.task; 11629 pw.print("TASK "); pw.print(lastTask.affinity); 11630 pw.print(" id="); pw.println(lastTask.taskId); 11631 if (dumpAll) { 11632 lastTask.dump(pw, " "); 11633 } 11634 } 11635 } 11636 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11637 } 11638 return true; 11639 } 11640 11641 /** 11642 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11643 * there is a thread associated with the activity. 11644 */ 11645 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11646 final ActivityRecord r, String[] args, boolean dumpAll) { 11647 String innerPrefix = prefix + " "; 11648 synchronized (this) { 11649 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11650 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11651 pw.print(" pid="); 11652 if (r.app != null) pw.println(r.app.pid); 11653 else pw.println("(not running)"); 11654 if (dumpAll) { 11655 r.dump(pw, innerPrefix); 11656 } 11657 } 11658 if (r.app != null && r.app.thread != null) { 11659 // flush anything that is already in the PrintWriter since the thread is going 11660 // to write to the file descriptor directly 11661 pw.flush(); 11662 try { 11663 TransferPipe tp = new TransferPipe(); 11664 try { 11665 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11666 r.appToken, innerPrefix, args); 11667 tp.go(fd); 11668 } finally { 11669 tp.kill(); 11670 } 11671 } catch (IOException e) { 11672 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11673 } catch (RemoteException e) { 11674 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11675 } 11676 } 11677 } 11678 11679 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11680 int opti, boolean dumpAll, String dumpPackage) { 11681 boolean needSep = false; 11682 boolean onlyHistory = false; 11683 boolean printedAnything = false; 11684 11685 if ("history".equals(dumpPackage)) { 11686 if (opti < args.length && "-s".equals(args[opti])) { 11687 dumpAll = false; 11688 } 11689 onlyHistory = true; 11690 dumpPackage = null; 11691 } 11692 11693 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11694 if (!onlyHistory && dumpAll) { 11695 if (mRegisteredReceivers.size() > 0) { 11696 boolean printed = false; 11697 Iterator it = mRegisteredReceivers.values().iterator(); 11698 while (it.hasNext()) { 11699 ReceiverList r = (ReceiverList)it.next(); 11700 if (dumpPackage != null && (r.app == null || 11701 !dumpPackage.equals(r.app.info.packageName))) { 11702 continue; 11703 } 11704 if (!printed) { 11705 pw.println(" Registered Receivers:"); 11706 needSep = true; 11707 printed = true; 11708 printedAnything = true; 11709 } 11710 pw.print(" * "); pw.println(r); 11711 r.dump(pw, " "); 11712 } 11713 } 11714 11715 if (mReceiverResolver.dump(pw, needSep ? 11716 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11717 " ", dumpPackage, false)) { 11718 needSep = true; 11719 printedAnything = true; 11720 } 11721 } 11722 11723 for (BroadcastQueue q : mBroadcastQueues) { 11724 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11725 printedAnything |= needSep; 11726 } 11727 11728 needSep = true; 11729 11730 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11731 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11732 if (needSep) { 11733 pw.println(); 11734 } 11735 needSep = true; 11736 printedAnything = true; 11737 pw.print(" Sticky broadcasts for user "); 11738 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11739 StringBuilder sb = new StringBuilder(128); 11740 for (Map.Entry<String, ArrayList<Intent>> ent 11741 : mStickyBroadcasts.valueAt(user).entrySet()) { 11742 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11743 if (dumpAll) { 11744 pw.println(":"); 11745 ArrayList<Intent> intents = ent.getValue(); 11746 final int N = intents.size(); 11747 for (int i=0; i<N; i++) { 11748 sb.setLength(0); 11749 sb.append(" Intent: "); 11750 intents.get(i).toShortString(sb, false, true, false, false); 11751 pw.println(sb.toString()); 11752 Bundle bundle = intents.get(i).getExtras(); 11753 if (bundle != null) { 11754 pw.print(" "); 11755 pw.println(bundle.toString()); 11756 } 11757 } 11758 } else { 11759 pw.println(""); 11760 } 11761 } 11762 } 11763 } 11764 11765 if (!onlyHistory && dumpAll) { 11766 pw.println(); 11767 for (BroadcastQueue queue : mBroadcastQueues) { 11768 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11769 + queue.mBroadcastsScheduled); 11770 } 11771 pw.println(" mHandler:"); 11772 mHandler.dump(new PrintWriterPrinter(pw), " "); 11773 needSep = true; 11774 printedAnything = true; 11775 } 11776 11777 if (!printedAnything) { 11778 pw.println(" (nothing)"); 11779 } 11780 } 11781 11782 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11783 int opti, boolean dumpAll, String dumpPackage) { 11784 boolean needSep; 11785 boolean printedAnything = false; 11786 11787 ItemMatcher matcher = new ItemMatcher(); 11788 matcher.build(args, opti); 11789 11790 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11791 11792 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11793 printedAnything |= needSep; 11794 11795 if (mLaunchingProviders.size() > 0) { 11796 boolean printed = false; 11797 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11798 ContentProviderRecord r = mLaunchingProviders.get(i); 11799 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11800 continue; 11801 } 11802 if (!printed) { 11803 if (needSep) pw.println(); 11804 needSep = true; 11805 pw.println(" Launching content providers:"); 11806 printed = true; 11807 printedAnything = true; 11808 } 11809 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11810 pw.println(r); 11811 } 11812 } 11813 11814 if (mGrantedUriPermissions.size() > 0) { 11815 boolean printed = false; 11816 int dumpUid = -2; 11817 if (dumpPackage != null) { 11818 try { 11819 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11820 } catch (NameNotFoundException e) { 11821 dumpUid = -1; 11822 } 11823 } 11824 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11825 int uid = mGrantedUriPermissions.keyAt(i); 11826 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11827 continue; 11828 } 11829 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11830 if (!printed) { 11831 if (needSep) pw.println(); 11832 needSep = true; 11833 pw.println(" Granted Uri Permissions:"); 11834 printed = true; 11835 printedAnything = true; 11836 } 11837 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11838 for (UriPermission perm : perms.values()) { 11839 pw.print(" "); pw.println(perm); 11840 if (dumpAll) { 11841 perm.dump(pw, " "); 11842 } 11843 } 11844 } 11845 } 11846 11847 if (!printedAnything) { 11848 pw.println(" (nothing)"); 11849 } 11850 } 11851 11852 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11853 int opti, boolean dumpAll, String dumpPackage) { 11854 boolean printed = false; 11855 11856 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11857 11858 if (mIntentSenderRecords.size() > 0) { 11859 Iterator<WeakReference<PendingIntentRecord>> it 11860 = mIntentSenderRecords.values().iterator(); 11861 while (it.hasNext()) { 11862 WeakReference<PendingIntentRecord> ref = it.next(); 11863 PendingIntentRecord rec = ref != null ? ref.get(): null; 11864 if (dumpPackage != null && (rec == null 11865 || !dumpPackage.equals(rec.key.packageName))) { 11866 continue; 11867 } 11868 printed = true; 11869 if (rec != null) { 11870 pw.print(" * "); pw.println(rec); 11871 if (dumpAll) { 11872 rec.dump(pw, " "); 11873 } 11874 } else { 11875 pw.print(" * "); pw.println(ref); 11876 } 11877 } 11878 } 11879 11880 if (!printed) { 11881 pw.println(" (nothing)"); 11882 } 11883 } 11884 11885 private static final int dumpProcessList(PrintWriter pw, 11886 ActivityManagerService service, List list, 11887 String prefix, String normalLabel, String persistentLabel, 11888 String dumpPackage) { 11889 int numPers = 0; 11890 final int N = list.size()-1; 11891 for (int i=N; i>=0; i--) { 11892 ProcessRecord r = (ProcessRecord)list.get(i); 11893 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11894 continue; 11895 } 11896 pw.println(String.format("%s%s #%2d: %s", 11897 prefix, (r.persistent ? persistentLabel : normalLabel), 11898 i, r.toString())); 11899 if (r.persistent) { 11900 numPers++; 11901 } 11902 } 11903 return numPers; 11904 } 11905 11906 private static final boolean dumpProcessOomList(PrintWriter pw, 11907 ActivityManagerService service, List<ProcessRecord> origList, 11908 String prefix, String normalLabel, String persistentLabel, 11909 boolean inclDetails, String dumpPackage) { 11910 11911 ArrayList<Pair<ProcessRecord, Integer>> list 11912 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11913 for (int i=0; i<origList.size(); i++) { 11914 ProcessRecord r = origList.get(i); 11915 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11916 continue; 11917 } 11918 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11919 } 11920 11921 if (list.size() <= 0) { 11922 return false; 11923 } 11924 11925 Comparator<Pair<ProcessRecord, Integer>> comparator 11926 = new Comparator<Pair<ProcessRecord, Integer>>() { 11927 @Override 11928 public int compare(Pair<ProcessRecord, Integer> object1, 11929 Pair<ProcessRecord, Integer> object2) { 11930 if (object1.first.setAdj != object2.first.setAdj) { 11931 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11932 } 11933 if (object1.second.intValue() != object2.second.intValue()) { 11934 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11935 } 11936 return 0; 11937 } 11938 }; 11939 11940 Collections.sort(list, comparator); 11941 11942 final long curRealtime = SystemClock.elapsedRealtime(); 11943 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11944 final long curUptime = SystemClock.uptimeMillis(); 11945 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11946 11947 for (int i=list.size()-1; i>=0; i--) { 11948 ProcessRecord r = list.get(i).first; 11949 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11950 char schedGroup; 11951 switch (r.setSchedGroup) { 11952 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11953 schedGroup = 'B'; 11954 break; 11955 case Process.THREAD_GROUP_DEFAULT: 11956 schedGroup = 'F'; 11957 break; 11958 default: 11959 schedGroup = '?'; 11960 break; 11961 } 11962 char foreground; 11963 if (r.foregroundActivities) { 11964 foreground = 'A'; 11965 } else if (r.foregroundServices) { 11966 foreground = 'S'; 11967 } else { 11968 foreground = ' '; 11969 } 11970 String procState = ProcessList.makeProcStateString(r.curProcState); 11971 pw.print(prefix); 11972 pw.print(r.persistent ? persistentLabel : normalLabel); 11973 pw.print(" #"); 11974 int num = (origList.size()-1)-list.get(i).second; 11975 if (num < 10) pw.print(' '); 11976 pw.print(num); 11977 pw.print(": "); 11978 pw.print(oomAdj); 11979 pw.print(' '); 11980 pw.print(schedGroup); 11981 pw.print('/'); 11982 pw.print(foreground); 11983 pw.print('/'); 11984 pw.print(procState); 11985 pw.print(" trm:"); 11986 if (r.trimMemoryLevel < 10) pw.print(' '); 11987 pw.print(r.trimMemoryLevel); 11988 pw.print(' '); 11989 pw.print(r.toShortString()); 11990 pw.print(" ("); 11991 pw.print(r.adjType); 11992 pw.println(')'); 11993 if (r.adjSource != null || r.adjTarget != null) { 11994 pw.print(prefix); 11995 pw.print(" "); 11996 if (r.adjTarget instanceof ComponentName) { 11997 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11998 } else if (r.adjTarget != null) { 11999 pw.print(r.adjTarget.toString()); 12000 } else { 12001 pw.print("{null}"); 12002 } 12003 pw.print("<="); 12004 if (r.adjSource instanceof ProcessRecord) { 12005 pw.print("Proc{"); 12006 pw.print(((ProcessRecord)r.adjSource).toShortString()); 12007 pw.println("}"); 12008 } else if (r.adjSource != null) { 12009 pw.println(r.adjSource.toString()); 12010 } else { 12011 pw.println("{null}"); 12012 } 12013 } 12014 if (inclDetails) { 12015 pw.print(prefix); 12016 pw.print(" "); 12017 pw.print("oom: max="); pw.print(r.maxAdj); 12018 pw.print(" curRaw="); pw.print(r.curRawAdj); 12019 pw.print(" setRaw="); pw.print(r.setRawAdj); 12020 pw.print(" cur="); pw.print(r.curAdj); 12021 pw.print(" set="); pw.println(r.setAdj); 12022 pw.print(prefix); 12023 pw.print(" "); 12024 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 12025 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 12026 pw.print(" lastPss="); pw.print(r.lastPss); 12027 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12028 pw.print(prefix); 12029 pw.print(" "); 12030 pw.print("keeping="); pw.print(r.keeping); 12031 pw.print(" cached="); pw.print(r.cached); 12032 pw.print(" empty="); pw.print(r.empty); 12033 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12034 12035 if (!r.keeping) { 12036 if (r.lastWakeTime != 0) { 12037 long wtime; 12038 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12039 synchronized (stats) { 12040 wtime = stats.getProcessWakeTime(r.info.uid, 12041 r.pid, curRealtime); 12042 } 12043 long timeUsed = wtime - r.lastWakeTime; 12044 pw.print(prefix); 12045 pw.print(" "); 12046 pw.print("keep awake over "); 12047 TimeUtils.formatDuration(realtimeSince, pw); 12048 pw.print(" used "); 12049 TimeUtils.formatDuration(timeUsed, pw); 12050 pw.print(" ("); 12051 pw.print((timeUsed*100)/realtimeSince); 12052 pw.println("%)"); 12053 } 12054 if (r.lastCpuTime != 0) { 12055 long timeUsed = r.curCpuTime - r.lastCpuTime; 12056 pw.print(prefix); 12057 pw.print(" "); 12058 pw.print("run cpu over "); 12059 TimeUtils.formatDuration(uptimeSince, pw); 12060 pw.print(" used "); 12061 TimeUtils.formatDuration(timeUsed, pw); 12062 pw.print(" ("); 12063 pw.print((timeUsed*100)/uptimeSince); 12064 pw.println("%)"); 12065 } 12066 } 12067 } 12068 } 12069 return true; 12070 } 12071 12072 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12073 ArrayList<ProcessRecord> procs; 12074 synchronized (this) { 12075 if (args != null && args.length > start 12076 && args[start].charAt(0) != '-') { 12077 procs = new ArrayList<ProcessRecord>(); 12078 int pid = -1; 12079 try { 12080 pid = Integer.parseInt(args[start]); 12081 } catch (NumberFormatException e) { 12082 } 12083 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12084 ProcessRecord proc = mLruProcesses.get(i); 12085 if (proc.pid == pid) { 12086 procs.add(proc); 12087 } else if (proc.processName.equals(args[start])) { 12088 procs.add(proc); 12089 } 12090 } 12091 if (procs.size() <= 0) { 12092 return null; 12093 } 12094 } else { 12095 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12096 } 12097 } 12098 return procs; 12099 } 12100 12101 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12102 PrintWriter pw, String[] args) { 12103 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12104 if (procs == null) { 12105 pw.println("No process found for: " + args[0]); 12106 return; 12107 } 12108 12109 long uptime = SystemClock.uptimeMillis(); 12110 long realtime = SystemClock.elapsedRealtime(); 12111 pw.println("Applications Graphics Acceleration Info:"); 12112 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12113 12114 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12115 ProcessRecord r = procs.get(i); 12116 if (r.thread != null) { 12117 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12118 pw.flush(); 12119 try { 12120 TransferPipe tp = new TransferPipe(); 12121 try { 12122 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12123 tp.go(fd); 12124 } finally { 12125 tp.kill(); 12126 } 12127 } catch (IOException e) { 12128 pw.println("Failure while dumping the app: " + r); 12129 pw.flush(); 12130 } catch (RemoteException e) { 12131 pw.println("Got a RemoteException while dumping the app " + r); 12132 pw.flush(); 12133 } 12134 } 12135 } 12136 } 12137 12138 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12139 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12140 if (procs == null) { 12141 pw.println("No process found for: " + args[0]); 12142 return; 12143 } 12144 12145 pw.println("Applications Database Info:"); 12146 12147 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12148 ProcessRecord r = procs.get(i); 12149 if (r.thread != null) { 12150 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12151 pw.flush(); 12152 try { 12153 TransferPipe tp = new TransferPipe(); 12154 try { 12155 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12156 tp.go(fd); 12157 } finally { 12158 tp.kill(); 12159 } 12160 } catch (IOException e) { 12161 pw.println("Failure while dumping the app: " + r); 12162 pw.flush(); 12163 } catch (RemoteException e) { 12164 pw.println("Got a RemoteException while dumping the app " + r); 12165 pw.flush(); 12166 } 12167 } 12168 } 12169 } 12170 12171 final static class MemItem { 12172 final boolean isProc; 12173 final String label; 12174 final String shortLabel; 12175 final long pss; 12176 final int id; 12177 final boolean hasActivities; 12178 ArrayList<MemItem> subitems; 12179 12180 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12181 boolean _hasActivities) { 12182 isProc = true; 12183 label = _label; 12184 shortLabel = _shortLabel; 12185 pss = _pss; 12186 id = _id; 12187 hasActivities = _hasActivities; 12188 } 12189 12190 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12191 isProc = false; 12192 label = _label; 12193 shortLabel = _shortLabel; 12194 pss = _pss; 12195 id = _id; 12196 hasActivities = false; 12197 } 12198 } 12199 12200 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12201 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12202 if (sort && !isCompact) { 12203 Collections.sort(items, new Comparator<MemItem>() { 12204 @Override 12205 public int compare(MemItem lhs, MemItem rhs) { 12206 if (lhs.pss < rhs.pss) { 12207 return 1; 12208 } else if (lhs.pss > rhs.pss) { 12209 return -1; 12210 } 12211 return 0; 12212 } 12213 }); 12214 } 12215 12216 for (int i=0; i<items.size(); i++) { 12217 MemItem mi = items.get(i); 12218 if (!isCompact) { 12219 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12220 } else if (mi.isProc) { 12221 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12222 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12223 pw.println(mi.hasActivities ? ",a" : ",e"); 12224 } else { 12225 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12226 pw.println(mi.pss); 12227 } 12228 if (mi.subitems != null) { 12229 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12230 true, isCompact); 12231 } 12232 } 12233 } 12234 12235 // These are in KB. 12236 static final long[] DUMP_MEM_BUCKETS = new long[] { 12237 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12238 120*1024, 160*1024, 200*1024, 12239 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12240 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12241 }; 12242 12243 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12244 boolean stackLike) { 12245 int start = label.lastIndexOf('.'); 12246 if (start >= 0) start++; 12247 else start = 0; 12248 int end = label.length(); 12249 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12250 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12251 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12252 out.append(bucket); 12253 out.append(stackLike ? "MB." : "MB "); 12254 out.append(label, start, end); 12255 return; 12256 } 12257 } 12258 out.append(memKB/1024); 12259 out.append(stackLike ? "MB." : "MB "); 12260 out.append(label, start, end); 12261 } 12262 12263 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12264 ProcessList.NATIVE_ADJ, 12265 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12266 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12267 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12268 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12269 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12270 }; 12271 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12272 "Native", 12273 "System", "Persistent", "Foreground", 12274 "Visible", "Perceptible", 12275 "Heavy Weight", "Backup", 12276 "A Services", "Home", 12277 "Previous", "B Services", "Cached" 12278 }; 12279 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12280 "native", 12281 "sys", "pers", "fore", 12282 "vis", "percept", 12283 "heavy", "backup", 12284 "servicea", "home", 12285 "prev", "serviceb", "cached" 12286 }; 12287 12288 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12289 long realtime, boolean isCheckinRequest, boolean isCompact) { 12290 if (isCheckinRequest || isCompact) { 12291 // short checkin version 12292 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12293 } else { 12294 pw.println("Applications Memory Usage (kB):"); 12295 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12296 } 12297 } 12298 12299 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12300 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12301 boolean dumpDetails = false; 12302 boolean dumpFullDetails = false; 12303 boolean dumpDalvik = false; 12304 boolean oomOnly = false; 12305 boolean isCompact = false; 12306 boolean localOnly = false; 12307 12308 int opti = 0; 12309 while (opti < args.length) { 12310 String opt = args[opti]; 12311 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12312 break; 12313 } 12314 opti++; 12315 if ("-a".equals(opt)) { 12316 dumpDetails = true; 12317 dumpFullDetails = true; 12318 dumpDalvik = true; 12319 } else if ("-d".equals(opt)) { 12320 dumpDalvik = true; 12321 } else if ("-c".equals(opt)) { 12322 isCompact = true; 12323 } else if ("--oom".equals(opt)) { 12324 oomOnly = true; 12325 } else if ("--local".equals(opt)) { 12326 localOnly = true; 12327 } else if ("-h".equals(opt)) { 12328 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12329 pw.println(" -a: include all available information for each process."); 12330 pw.println(" -d: include dalvik details when dumping process details."); 12331 pw.println(" -c: dump in a compact machine-parseable representation."); 12332 pw.println(" --oom: only show processes organized by oom adj."); 12333 pw.println(" --local: only collect details locally, don't call process."); 12334 pw.println("If [process] is specified it can be the name or "); 12335 pw.println("pid of a specific process to dump."); 12336 return; 12337 } else { 12338 pw.println("Unknown argument: " + opt + "; use -h for help"); 12339 } 12340 } 12341 12342 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12343 long uptime = SystemClock.uptimeMillis(); 12344 long realtime = SystemClock.elapsedRealtime(); 12345 final long[] tmpLong = new long[1]; 12346 12347 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12348 if (procs == null) { 12349 // No Java processes. Maybe they want to print a native process. 12350 if (args != null && args.length > opti 12351 && args[opti].charAt(0) != '-') { 12352 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12353 = new ArrayList<ProcessCpuTracker.Stats>(); 12354 updateCpuStatsNow(); 12355 int findPid = -1; 12356 try { 12357 findPid = Integer.parseInt(args[opti]); 12358 } catch (NumberFormatException e) { 12359 } 12360 synchronized (mProcessCpuThread) { 12361 final int N = mProcessCpuTracker.countStats(); 12362 for (int i=0; i<N; i++) { 12363 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12364 if (st.pid == findPid || (st.baseName != null 12365 && st.baseName.equals(args[opti]))) { 12366 nativeProcs.add(st); 12367 } 12368 } 12369 } 12370 if (nativeProcs.size() > 0) { 12371 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12372 isCompact); 12373 Debug.MemoryInfo mi = null; 12374 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12375 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12376 final int pid = r.pid; 12377 if (!isCheckinRequest && dumpDetails) { 12378 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12379 } 12380 if (mi == null) { 12381 mi = new Debug.MemoryInfo(); 12382 } 12383 if (dumpDetails || (!brief && !oomOnly)) { 12384 Debug.getMemoryInfo(pid, mi); 12385 } else { 12386 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12387 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12388 } 12389 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12390 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12391 if (isCheckinRequest) { 12392 pw.println(); 12393 } 12394 } 12395 return; 12396 } 12397 } 12398 pw.println("No process found for: " + args[opti]); 12399 return; 12400 } 12401 12402 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12403 dumpDetails = true; 12404 } 12405 12406 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12407 12408 String[] innerArgs = new String[args.length-opti]; 12409 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12410 12411 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12412 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12413 long nativePss=0, dalvikPss=0, otherPss=0; 12414 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12415 12416 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12417 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12418 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12419 12420 long totalPss = 0; 12421 long cachedPss = 0; 12422 12423 Debug.MemoryInfo mi = null; 12424 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12425 final ProcessRecord r = procs.get(i); 12426 final IApplicationThread thread; 12427 final int pid; 12428 final int oomAdj; 12429 final boolean hasActivities; 12430 synchronized (this) { 12431 thread = r.thread; 12432 pid = r.pid; 12433 oomAdj = r.getSetAdjWithServices(); 12434 hasActivities = r.activities.size() > 0; 12435 } 12436 if (thread != null) { 12437 if (!isCheckinRequest && dumpDetails) { 12438 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12439 } 12440 if (mi == null) { 12441 mi = new Debug.MemoryInfo(); 12442 } 12443 if (dumpDetails || (!brief && !oomOnly)) { 12444 Debug.getMemoryInfo(pid, mi); 12445 } else { 12446 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12447 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12448 } 12449 if (dumpDetails) { 12450 if (localOnly) { 12451 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12452 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12453 if (isCheckinRequest) { 12454 pw.println(); 12455 } 12456 } else { 12457 try { 12458 pw.flush(); 12459 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12460 dumpDalvik, innerArgs); 12461 } catch (RemoteException e) { 12462 if (!isCheckinRequest) { 12463 pw.println("Got RemoteException!"); 12464 pw.flush(); 12465 } 12466 } 12467 } 12468 } 12469 12470 final long myTotalPss = mi.getTotalPss(); 12471 final long myTotalUss = mi.getTotalUss(); 12472 12473 synchronized (this) { 12474 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12475 // Record this for posterity if the process has been stable. 12476 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12477 } 12478 } 12479 12480 if (!isCheckinRequest && mi != null) { 12481 totalPss += myTotalPss; 12482 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12483 (hasActivities ? " / activities)" : ")"), 12484 r.processName, myTotalPss, pid, hasActivities); 12485 procMems.add(pssItem); 12486 procMemsMap.put(pid, pssItem); 12487 12488 nativePss += mi.nativePss; 12489 dalvikPss += mi.dalvikPss; 12490 otherPss += mi.otherPss; 12491 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12492 long mem = mi.getOtherPss(j); 12493 miscPss[j] += mem; 12494 otherPss -= mem; 12495 } 12496 12497 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12498 cachedPss += myTotalPss; 12499 } 12500 12501 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12502 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12503 || oomIndex == (oomPss.length-1)) { 12504 oomPss[oomIndex] += myTotalPss; 12505 if (oomProcs[oomIndex] == null) { 12506 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12507 } 12508 oomProcs[oomIndex].add(pssItem); 12509 break; 12510 } 12511 } 12512 } 12513 } 12514 } 12515 12516 if (!isCheckinRequest && procs.size() > 1) { 12517 // If we are showing aggregations, also look for native processes to 12518 // include so that our aggregations are more accurate. 12519 updateCpuStatsNow(); 12520 synchronized (mProcessCpuThread) { 12521 final int N = mProcessCpuTracker.countStats(); 12522 for (int i=0; i<N; i++) { 12523 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12524 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12525 if (mi == null) { 12526 mi = new Debug.MemoryInfo(); 12527 } 12528 if (!brief && !oomOnly) { 12529 Debug.getMemoryInfo(st.pid, mi); 12530 } else { 12531 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12532 mi.nativePrivateDirty = (int)tmpLong[0]; 12533 } 12534 12535 final long myTotalPss = mi.getTotalPss(); 12536 totalPss += myTotalPss; 12537 12538 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12539 st.name, myTotalPss, st.pid, false); 12540 procMems.add(pssItem); 12541 12542 nativePss += mi.nativePss; 12543 dalvikPss += mi.dalvikPss; 12544 otherPss += mi.otherPss; 12545 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12546 long mem = mi.getOtherPss(j); 12547 miscPss[j] += mem; 12548 otherPss -= mem; 12549 } 12550 oomPss[0] += myTotalPss; 12551 if (oomProcs[0] == null) { 12552 oomProcs[0] = new ArrayList<MemItem>(); 12553 } 12554 oomProcs[0].add(pssItem); 12555 } 12556 } 12557 } 12558 12559 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12560 12561 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12562 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12563 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12564 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12565 String label = Debug.MemoryInfo.getOtherLabel(j); 12566 catMems.add(new MemItem(label, label, miscPss[j], j)); 12567 } 12568 12569 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12570 for (int j=0; j<oomPss.length; j++) { 12571 if (oomPss[j] != 0) { 12572 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12573 : DUMP_MEM_OOM_LABEL[j]; 12574 MemItem item = new MemItem(label, label, oomPss[j], 12575 DUMP_MEM_OOM_ADJ[j]); 12576 item.subitems = oomProcs[j]; 12577 oomMems.add(item); 12578 } 12579 } 12580 12581 if (!brief && !oomOnly && !isCompact) { 12582 pw.println(); 12583 pw.println("Total PSS by process:"); 12584 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12585 pw.println(); 12586 } 12587 if (!isCompact) { 12588 pw.println("Total PSS by OOM adjustment:"); 12589 } 12590 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12591 if (!brief && !oomOnly) { 12592 PrintWriter out = categoryPw != null ? categoryPw : pw; 12593 if (!isCompact) { 12594 out.println(); 12595 out.println("Total PSS by category:"); 12596 } 12597 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12598 } 12599 if (!isCompact) { 12600 pw.println(); 12601 } 12602 MemInfoReader memInfo = new MemInfoReader(); 12603 memInfo.readMemInfo(); 12604 if (!brief) { 12605 if (!isCompact) { 12606 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12607 pw.print(" kB (status "); 12608 switch (mLastMemoryLevel) { 12609 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12610 pw.println("normal)"); 12611 break; 12612 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12613 pw.println("moderate)"); 12614 break; 12615 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12616 pw.println("low)"); 12617 break; 12618 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12619 pw.println("critical)"); 12620 break; 12621 default: 12622 pw.print(mLastMemoryLevel); 12623 pw.println(")"); 12624 break; 12625 } 12626 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12627 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12628 pw.print(cachedPss); pw.print(" cached pss + "); 12629 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12630 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12631 } else { 12632 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12633 pw.print(cachedPss + memInfo.getCachedSizeKb() 12634 + memInfo.getFreeSizeKb()); pw.print(","); 12635 pw.println(totalPss - cachedPss); 12636 } 12637 } 12638 if (!isCompact) { 12639 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12640 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12641 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12642 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12643 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12644 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12645 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12646 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12647 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12648 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12649 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12650 } 12651 if (!brief) { 12652 if (memInfo.getZramTotalSizeKb() != 0) { 12653 if (!isCompact) { 12654 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12655 pw.print(" kB physical used for "); 12656 pw.print(memInfo.getSwapTotalSizeKb() 12657 - memInfo.getSwapFreeSizeKb()); 12658 pw.print(" kB in swap ("); 12659 pw.print(memInfo.getSwapTotalSizeKb()); 12660 pw.println(" kB total swap)"); 12661 } else { 12662 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12663 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12664 pw.println(memInfo.getSwapFreeSizeKb()); 12665 } 12666 } 12667 final int[] SINGLE_LONG_FORMAT = new int[] { 12668 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12669 }; 12670 long[] longOut = new long[1]; 12671 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12672 SINGLE_LONG_FORMAT, null, longOut, null); 12673 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12674 longOut[0] = 0; 12675 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12676 SINGLE_LONG_FORMAT, null, longOut, null); 12677 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12678 longOut[0] = 0; 12679 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12680 SINGLE_LONG_FORMAT, null, longOut, null); 12681 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12682 longOut[0] = 0; 12683 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12684 SINGLE_LONG_FORMAT, null, longOut, null); 12685 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12686 if (!isCompact) { 12687 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12688 pw.print(" KSM: "); pw.print(sharing); 12689 pw.print(" kB saved from shared "); 12690 pw.print(shared); pw.println(" kB"); 12691 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12692 pw.print(voltile); pw.println(" kB volatile"); 12693 } 12694 pw.print(" Tuning: "); 12695 pw.print(ActivityManager.staticGetMemoryClass()); 12696 pw.print(" (large "); 12697 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12698 pw.print("), oom "); 12699 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12700 pw.print(" kB"); 12701 pw.print(", restore limit "); 12702 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12703 pw.print(" kB"); 12704 if (ActivityManager.isLowRamDeviceStatic()) { 12705 pw.print(" (low-ram)"); 12706 } 12707 if (ActivityManager.isHighEndGfx()) { 12708 pw.print(" (high-end-gfx)"); 12709 } 12710 pw.println(); 12711 } else { 12712 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12713 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12714 pw.println(voltile); 12715 pw.print("tuning,"); 12716 pw.print(ActivityManager.staticGetMemoryClass()); 12717 pw.print(','); 12718 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12719 pw.print(','); 12720 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12721 if (ActivityManager.isLowRamDeviceStatic()) { 12722 pw.print(",low-ram"); 12723 } 12724 if (ActivityManager.isHighEndGfx()) { 12725 pw.print(",high-end-gfx"); 12726 } 12727 pw.println(); 12728 } 12729 } 12730 } 12731 } 12732 12733 /** 12734 * Searches array of arguments for the specified string 12735 * @param args array of argument strings 12736 * @param value value to search for 12737 * @return true if the value is contained in the array 12738 */ 12739 private static boolean scanArgs(String[] args, String value) { 12740 if (args != null) { 12741 for (String arg : args) { 12742 if (value.equals(arg)) { 12743 return true; 12744 } 12745 } 12746 } 12747 return false; 12748 } 12749 12750 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12751 ContentProviderRecord cpr, boolean always) { 12752 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12753 12754 if (!inLaunching || always) { 12755 synchronized (cpr) { 12756 cpr.launchingApp = null; 12757 cpr.notifyAll(); 12758 } 12759 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12760 String names[] = cpr.info.authority.split(";"); 12761 for (int j = 0; j < names.length; j++) { 12762 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12763 } 12764 } 12765 12766 for (int i=0; i<cpr.connections.size(); i++) { 12767 ContentProviderConnection conn = cpr.connections.get(i); 12768 if (conn.waiting) { 12769 // If this connection is waiting for the provider, then we don't 12770 // need to mess with its process unless we are always removing 12771 // or for some reason the provider is not currently launching. 12772 if (inLaunching && !always) { 12773 continue; 12774 } 12775 } 12776 ProcessRecord capp = conn.client; 12777 conn.dead = true; 12778 if (conn.stableCount > 0) { 12779 if (!capp.persistent && capp.thread != null 12780 && capp.pid != 0 12781 && capp.pid != MY_PID) { 12782 killUnneededProcessLocked(capp, "depends on provider " 12783 + cpr.name.flattenToShortString() 12784 + " in dying proc " + (proc != null ? proc.processName : "??")); 12785 } 12786 } else if (capp.thread != null && conn.provider.provider != null) { 12787 try { 12788 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12789 } catch (RemoteException e) { 12790 } 12791 // In the protocol here, we don't expect the client to correctly 12792 // clean up this connection, we'll just remove it. 12793 cpr.connections.remove(i); 12794 conn.client.conProviders.remove(conn); 12795 } 12796 } 12797 12798 if (inLaunching && always) { 12799 mLaunchingProviders.remove(cpr); 12800 } 12801 return inLaunching; 12802 } 12803 12804 /** 12805 * Main code for cleaning up a process when it has gone away. This is 12806 * called both as a result of the process dying, or directly when stopping 12807 * a process when running in single process mode. 12808 */ 12809 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12810 boolean restarting, boolean allowRestart, int index) { 12811 if (index >= 0) { 12812 removeLruProcessLocked(app); 12813 ProcessList.remove(app.pid); 12814 } 12815 12816 mProcessesToGc.remove(app); 12817 mPendingPssProcesses.remove(app); 12818 12819 // Dismiss any open dialogs. 12820 if (app.crashDialog != null && !app.forceCrashReport) { 12821 app.crashDialog.dismiss(); 12822 app.crashDialog = null; 12823 } 12824 if (app.anrDialog != null) { 12825 app.anrDialog.dismiss(); 12826 app.anrDialog = null; 12827 } 12828 if (app.waitDialog != null) { 12829 app.waitDialog.dismiss(); 12830 app.waitDialog = null; 12831 } 12832 12833 app.crashing = false; 12834 app.notResponding = false; 12835 12836 app.resetPackageList(mProcessStats); 12837 app.unlinkDeathRecipient(); 12838 app.makeInactive(mProcessStats); 12839 app.forcingToForeground = null; 12840 updateProcessForegroundLocked(app, false, false); 12841 app.foregroundActivities = false; 12842 app.hasShownUi = false; 12843 app.treatLikeActivity = false; 12844 app.hasAboveClient = false; 12845 app.hasClientActivities = false; 12846 12847 mServices.killServicesLocked(app, allowRestart); 12848 12849 boolean restart = false; 12850 12851 // Remove published content providers. 12852 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12853 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12854 final boolean always = app.bad || !allowRestart; 12855 if (removeDyingProviderLocked(app, cpr, always) || always) { 12856 // We left the provider in the launching list, need to 12857 // restart it. 12858 restart = true; 12859 } 12860 12861 cpr.provider = null; 12862 cpr.proc = null; 12863 } 12864 app.pubProviders.clear(); 12865 12866 // Take care of any launching providers waiting for this process. 12867 if (checkAppInLaunchingProvidersLocked(app, false)) { 12868 restart = true; 12869 } 12870 12871 // Unregister from connected content providers. 12872 if (!app.conProviders.isEmpty()) { 12873 for (int i=0; i<app.conProviders.size(); i++) { 12874 ContentProviderConnection conn = app.conProviders.get(i); 12875 conn.provider.connections.remove(conn); 12876 } 12877 app.conProviders.clear(); 12878 } 12879 12880 // At this point there may be remaining entries in mLaunchingProviders 12881 // where we were the only one waiting, so they are no longer of use. 12882 // Look for these and clean up if found. 12883 // XXX Commented out for now. Trying to figure out a way to reproduce 12884 // the actual situation to identify what is actually going on. 12885 if (false) { 12886 for (int i=0; i<mLaunchingProviders.size(); i++) { 12887 ContentProviderRecord cpr = (ContentProviderRecord) 12888 mLaunchingProviders.get(i); 12889 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12890 synchronized (cpr) { 12891 cpr.launchingApp = null; 12892 cpr.notifyAll(); 12893 } 12894 } 12895 } 12896 } 12897 12898 skipCurrentReceiverLocked(app); 12899 12900 // Unregister any receivers. 12901 for (int i=app.receivers.size()-1; i>=0; i--) { 12902 removeReceiverLocked(app.receivers.valueAt(i)); 12903 } 12904 app.receivers.clear(); 12905 12906 // If the app is undergoing backup, tell the backup manager about it 12907 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12908 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12909 + mBackupTarget.appInfo + " died during backup"); 12910 try { 12911 IBackupManager bm = IBackupManager.Stub.asInterface( 12912 ServiceManager.getService(Context.BACKUP_SERVICE)); 12913 bm.agentDisconnected(app.info.packageName); 12914 } catch (RemoteException e) { 12915 // can't happen; backup manager is local 12916 } 12917 } 12918 12919 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12920 ProcessChangeItem item = mPendingProcessChanges.get(i); 12921 if (item.pid == app.pid) { 12922 mPendingProcessChanges.remove(i); 12923 mAvailProcessChanges.add(item); 12924 } 12925 } 12926 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12927 12928 // If the caller is restarting this app, then leave it in its 12929 // current lists and let the caller take care of it. 12930 if (restarting) { 12931 return; 12932 } 12933 12934 if (!app.persistent || app.isolated) { 12935 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12936 "Removing non-persistent process during cleanup: " + app); 12937 mProcessNames.remove(app.processName, app.uid); 12938 mIsolatedProcesses.remove(app.uid); 12939 if (mHeavyWeightProcess == app) { 12940 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12941 mHeavyWeightProcess.userId, 0)); 12942 mHeavyWeightProcess = null; 12943 } 12944 } else if (!app.removed) { 12945 // This app is persistent, so we need to keep its record around. 12946 // If it is not already on the pending app list, add it there 12947 // and start a new process for it. 12948 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12949 mPersistentStartingProcesses.add(app); 12950 restart = true; 12951 } 12952 } 12953 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12954 "Clean-up removing on hold: " + app); 12955 mProcessesOnHold.remove(app); 12956 12957 if (app == mHomeProcess) { 12958 mHomeProcess = null; 12959 } 12960 if (app == mPreviousProcess) { 12961 mPreviousProcess = null; 12962 } 12963 12964 if (restart && !app.isolated) { 12965 // We have components that still need to be running in the 12966 // process, so re-launch it. 12967 mProcessNames.put(app.processName, app.uid, app); 12968 startProcessLocked(app, "restart", app.processName); 12969 } else if (app.pid > 0 && app.pid != MY_PID) { 12970 // Goodbye! 12971 boolean removed; 12972 synchronized (mPidsSelfLocked) { 12973 mPidsSelfLocked.remove(app.pid); 12974 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12975 } 12976 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12977 app.processName, app.info.uid); 12978 if (app.isolated) { 12979 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12980 } 12981 app.setPid(0); 12982 } 12983 } 12984 12985 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12986 // Look through the content providers we are waiting to have launched, 12987 // and if any run in this process then either schedule a restart of 12988 // the process or kill the client waiting for it if this process has 12989 // gone bad. 12990 int NL = mLaunchingProviders.size(); 12991 boolean restart = false; 12992 for (int i=0; i<NL; i++) { 12993 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12994 if (cpr.launchingApp == app) { 12995 if (!alwaysBad && !app.bad) { 12996 restart = true; 12997 } else { 12998 removeDyingProviderLocked(app, cpr, true); 12999 // cpr should have been removed from mLaunchingProviders 13000 NL = mLaunchingProviders.size(); 13001 i--; 13002 } 13003 } 13004 } 13005 return restart; 13006 } 13007 13008 // ========================================================= 13009 // SERVICES 13010 // ========================================================= 13011 13012 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 13013 int flags) { 13014 enforceNotIsolatedCaller("getServices"); 13015 synchronized (this) { 13016 return mServices.getRunningServiceInfoLocked(maxNum, flags); 13017 } 13018 } 13019 13020 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 13021 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 13022 synchronized (this) { 13023 return mServices.getRunningServiceControlPanelLocked(name); 13024 } 13025 } 13026 13027 public ComponentName startService(IApplicationThread caller, Intent service, 13028 String resolvedType, int userId) { 13029 enforceNotIsolatedCaller("startService"); 13030 // Refuse possible leaked file descriptors 13031 if (service != null && service.hasFileDescriptors() == true) { 13032 throw new IllegalArgumentException("File descriptors passed in Intent"); 13033 } 13034 13035 if (DEBUG_SERVICE) 13036 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13037 synchronized(this) { 13038 final int callingPid = Binder.getCallingPid(); 13039 final int callingUid = Binder.getCallingUid(); 13040 final long origId = Binder.clearCallingIdentity(); 13041 ComponentName res = mServices.startServiceLocked(caller, service, 13042 resolvedType, callingPid, callingUid, userId); 13043 Binder.restoreCallingIdentity(origId); 13044 return res; 13045 } 13046 } 13047 13048 ComponentName startServiceInPackage(int uid, 13049 Intent service, String resolvedType, int userId) { 13050 synchronized(this) { 13051 if (DEBUG_SERVICE) 13052 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13053 final long origId = Binder.clearCallingIdentity(); 13054 ComponentName res = mServices.startServiceLocked(null, service, 13055 resolvedType, -1, uid, userId); 13056 Binder.restoreCallingIdentity(origId); 13057 return res; 13058 } 13059 } 13060 13061 public int stopService(IApplicationThread caller, Intent service, 13062 String resolvedType, int userId) { 13063 enforceNotIsolatedCaller("stopService"); 13064 // Refuse possible leaked file descriptors 13065 if (service != null && service.hasFileDescriptors() == true) { 13066 throw new IllegalArgumentException("File descriptors passed in Intent"); 13067 } 13068 13069 synchronized(this) { 13070 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13071 } 13072 } 13073 13074 public IBinder peekService(Intent service, String resolvedType) { 13075 enforceNotIsolatedCaller("peekService"); 13076 // Refuse possible leaked file descriptors 13077 if (service != null && service.hasFileDescriptors() == true) { 13078 throw new IllegalArgumentException("File descriptors passed in Intent"); 13079 } 13080 synchronized(this) { 13081 return mServices.peekServiceLocked(service, resolvedType); 13082 } 13083 } 13084 13085 public boolean stopServiceToken(ComponentName className, IBinder token, 13086 int startId) { 13087 synchronized(this) { 13088 return mServices.stopServiceTokenLocked(className, token, startId); 13089 } 13090 } 13091 13092 public void setServiceForeground(ComponentName className, IBinder token, 13093 int id, Notification notification, boolean removeNotification) { 13094 synchronized(this) { 13095 mServices.setServiceForegroundLocked(className, token, id, notification, 13096 removeNotification); 13097 } 13098 } 13099 13100 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13101 boolean requireFull, String name, String callerPackage) { 13102 final int callingUserId = UserHandle.getUserId(callingUid); 13103 if (callingUserId != userId) { 13104 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13105 if ((requireFull || checkComponentPermission( 13106 android.Manifest.permission.INTERACT_ACROSS_USERS, 13107 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 13108 && checkComponentPermission( 13109 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 13110 callingPid, callingUid, -1, true) 13111 != PackageManager.PERMISSION_GRANTED) { 13112 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13113 // In this case, they would like to just execute as their 13114 // owner user instead of failing. 13115 userId = callingUserId; 13116 } else { 13117 StringBuilder builder = new StringBuilder(128); 13118 builder.append("Permission Denial: "); 13119 builder.append(name); 13120 if (callerPackage != null) { 13121 builder.append(" from "); 13122 builder.append(callerPackage); 13123 } 13124 builder.append(" asks to run as user "); 13125 builder.append(userId); 13126 builder.append(" but is calling from user "); 13127 builder.append(UserHandle.getUserId(callingUid)); 13128 builder.append("; this requires "); 13129 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 13130 if (!requireFull) { 13131 builder.append(" or "); 13132 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13133 } 13134 String msg = builder.toString(); 13135 Slog.w(TAG, msg); 13136 throw new SecurityException(msg); 13137 } 13138 } 13139 } 13140 if (userId == UserHandle.USER_CURRENT 13141 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13142 // Note that we may be accessing this outside of a lock... 13143 // shouldn't be a big deal, if this is being called outside 13144 // of a locked context there is intrinsically a race with 13145 // the value the caller will receive and someone else changing it. 13146 userId = mCurrentUserId; 13147 } 13148 if (!allowAll && userId < 0) { 13149 throw new IllegalArgumentException( 13150 "Call does not support special user #" + userId); 13151 } 13152 } 13153 return userId; 13154 } 13155 13156 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13157 String className, int flags) { 13158 boolean result = false; 13159 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13160 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 13161 if (ActivityManager.checkUidPermission( 13162 android.Manifest.permission.INTERACT_ACROSS_USERS, 13163 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13164 ComponentName comp = new ComponentName(aInfo.packageName, className); 13165 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13166 + " requests FLAG_SINGLE_USER, but app does not hold " 13167 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13168 Slog.w(TAG, msg); 13169 throw new SecurityException(msg); 13170 } 13171 result = true; 13172 } 13173 } else if (componentProcessName == aInfo.packageName) { 13174 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13175 } else if ("system".equals(componentProcessName)) { 13176 result = true; 13177 } 13178 if (DEBUG_MU) { 13179 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13180 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13181 } 13182 return result; 13183 } 13184 13185 public int bindService(IApplicationThread caller, IBinder token, 13186 Intent service, String resolvedType, 13187 IServiceConnection connection, int flags, int userId) { 13188 enforceNotIsolatedCaller("bindService"); 13189 // Refuse possible leaked file descriptors 13190 if (service != null && service.hasFileDescriptors() == true) { 13191 throw new IllegalArgumentException("File descriptors passed in Intent"); 13192 } 13193 13194 synchronized(this) { 13195 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13196 connection, flags, userId); 13197 } 13198 } 13199 13200 public boolean unbindService(IServiceConnection connection) { 13201 synchronized (this) { 13202 return mServices.unbindServiceLocked(connection); 13203 } 13204 } 13205 13206 public void publishService(IBinder token, Intent intent, IBinder service) { 13207 // Refuse possible leaked file descriptors 13208 if (intent != null && intent.hasFileDescriptors() == true) { 13209 throw new IllegalArgumentException("File descriptors passed in Intent"); 13210 } 13211 13212 synchronized(this) { 13213 if (!(token instanceof ServiceRecord)) { 13214 throw new IllegalArgumentException("Invalid service token"); 13215 } 13216 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13217 } 13218 } 13219 13220 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13221 // Refuse possible leaked file descriptors 13222 if (intent != null && intent.hasFileDescriptors() == true) { 13223 throw new IllegalArgumentException("File descriptors passed in Intent"); 13224 } 13225 13226 synchronized(this) { 13227 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13228 } 13229 } 13230 13231 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13232 synchronized(this) { 13233 if (!(token instanceof ServiceRecord)) { 13234 throw new IllegalArgumentException("Invalid service token"); 13235 } 13236 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13237 } 13238 } 13239 13240 // ========================================================= 13241 // BACKUP AND RESTORE 13242 // ========================================================= 13243 13244 // Cause the target app to be launched if necessary and its backup agent 13245 // instantiated. The backup agent will invoke backupAgentCreated() on the 13246 // activity manager to announce its creation. 13247 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13248 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13249 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13250 13251 synchronized(this) { 13252 // !!! TODO: currently no check here that we're already bound 13253 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13254 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13255 synchronized (stats) { 13256 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13257 } 13258 13259 // Backup agent is now in use, its package can't be stopped. 13260 try { 13261 AppGlobals.getPackageManager().setPackageStoppedState( 13262 app.packageName, false, UserHandle.getUserId(app.uid)); 13263 } catch (RemoteException e) { 13264 } catch (IllegalArgumentException e) { 13265 Slog.w(TAG, "Failed trying to unstop package " 13266 + app.packageName + ": " + e); 13267 } 13268 13269 BackupRecord r = new BackupRecord(ss, app, backupMode); 13270 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13271 ? new ComponentName(app.packageName, app.backupAgentName) 13272 : new ComponentName("android", "FullBackupAgent"); 13273 // startProcessLocked() returns existing proc's record if it's already running 13274 ProcessRecord proc = startProcessLocked(app.processName, app, 13275 false, 0, "backup", hostingName, false, false, false); 13276 if (proc == null) { 13277 Slog.e(TAG, "Unable to start backup agent process " + r); 13278 return false; 13279 } 13280 13281 r.app = proc; 13282 mBackupTarget = r; 13283 mBackupAppName = app.packageName; 13284 13285 // Try not to kill the process during backup 13286 updateOomAdjLocked(proc); 13287 13288 // If the process is already attached, schedule the creation of the backup agent now. 13289 // If it is not yet live, this will be done when it attaches to the framework. 13290 if (proc.thread != null) { 13291 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13292 try { 13293 proc.thread.scheduleCreateBackupAgent(app, 13294 compatibilityInfoForPackageLocked(app), backupMode); 13295 } catch (RemoteException e) { 13296 // Will time out on the backup manager side 13297 } 13298 } else { 13299 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13300 } 13301 // Invariants: at this point, the target app process exists and the application 13302 // is either already running or in the process of coming up. mBackupTarget and 13303 // mBackupAppName describe the app, so that when it binds back to the AM we 13304 // know that it's scheduled for a backup-agent operation. 13305 } 13306 13307 return true; 13308 } 13309 13310 @Override 13311 public void clearPendingBackup() { 13312 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13313 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13314 13315 synchronized (this) { 13316 mBackupTarget = null; 13317 mBackupAppName = null; 13318 } 13319 } 13320 13321 // A backup agent has just come up 13322 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13323 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13324 + " = " + agent); 13325 13326 synchronized(this) { 13327 if (!agentPackageName.equals(mBackupAppName)) { 13328 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13329 return; 13330 } 13331 } 13332 13333 long oldIdent = Binder.clearCallingIdentity(); 13334 try { 13335 IBackupManager bm = IBackupManager.Stub.asInterface( 13336 ServiceManager.getService(Context.BACKUP_SERVICE)); 13337 bm.agentConnected(agentPackageName, agent); 13338 } catch (RemoteException e) { 13339 // can't happen; the backup manager service is local 13340 } catch (Exception e) { 13341 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13342 e.printStackTrace(); 13343 } finally { 13344 Binder.restoreCallingIdentity(oldIdent); 13345 } 13346 } 13347 13348 // done with this agent 13349 public void unbindBackupAgent(ApplicationInfo appInfo) { 13350 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13351 if (appInfo == null) { 13352 Slog.w(TAG, "unbind backup agent for null app"); 13353 return; 13354 } 13355 13356 synchronized(this) { 13357 try { 13358 if (mBackupAppName == null) { 13359 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13360 return; 13361 } 13362 13363 if (!mBackupAppName.equals(appInfo.packageName)) { 13364 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13365 return; 13366 } 13367 13368 // Not backing this app up any more; reset its OOM adjustment 13369 final ProcessRecord proc = mBackupTarget.app; 13370 updateOomAdjLocked(proc); 13371 13372 // If the app crashed during backup, 'thread' will be null here 13373 if (proc.thread != null) { 13374 try { 13375 proc.thread.scheduleDestroyBackupAgent(appInfo, 13376 compatibilityInfoForPackageLocked(appInfo)); 13377 } catch (Exception e) { 13378 Slog.e(TAG, "Exception when unbinding backup agent:"); 13379 e.printStackTrace(); 13380 } 13381 } 13382 } finally { 13383 mBackupTarget = null; 13384 mBackupAppName = null; 13385 } 13386 } 13387 } 13388 // ========================================================= 13389 // BROADCASTS 13390 // ========================================================= 13391 13392 private final List getStickiesLocked(String action, IntentFilter filter, 13393 List cur, int userId) { 13394 final ContentResolver resolver = mContext.getContentResolver(); 13395 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13396 if (stickies == null) { 13397 return cur; 13398 } 13399 final ArrayList<Intent> list = stickies.get(action); 13400 if (list == null) { 13401 return cur; 13402 } 13403 int N = list.size(); 13404 for (int i=0; i<N; i++) { 13405 Intent intent = list.get(i); 13406 if (filter.match(resolver, intent, true, TAG) >= 0) { 13407 if (cur == null) { 13408 cur = new ArrayList<Intent>(); 13409 } 13410 cur.add(intent); 13411 } 13412 } 13413 return cur; 13414 } 13415 13416 boolean isPendingBroadcastProcessLocked(int pid) { 13417 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13418 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13419 } 13420 13421 void skipPendingBroadcastLocked(int pid) { 13422 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13423 for (BroadcastQueue queue : mBroadcastQueues) { 13424 queue.skipPendingBroadcastLocked(pid); 13425 } 13426 } 13427 13428 // The app just attached; send any pending broadcasts that it should receive 13429 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13430 boolean didSomething = false; 13431 for (BroadcastQueue queue : mBroadcastQueues) { 13432 didSomething |= queue.sendPendingBroadcastsLocked(app); 13433 } 13434 return didSomething; 13435 } 13436 13437 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13438 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13439 enforceNotIsolatedCaller("registerReceiver"); 13440 int callingUid; 13441 int callingPid; 13442 synchronized(this) { 13443 ProcessRecord callerApp = null; 13444 if (caller != null) { 13445 callerApp = getRecordForAppLocked(caller); 13446 if (callerApp == null) { 13447 throw new SecurityException( 13448 "Unable to find app for caller " + caller 13449 + " (pid=" + Binder.getCallingPid() 13450 + ") when registering receiver " + receiver); 13451 } 13452 if (callerApp.info.uid != Process.SYSTEM_UID && 13453 !callerApp.pkgList.containsKey(callerPackage) && 13454 !"android".equals(callerPackage)) { 13455 throw new SecurityException("Given caller package " + callerPackage 13456 + " is not running in process " + callerApp); 13457 } 13458 callingUid = callerApp.info.uid; 13459 callingPid = callerApp.pid; 13460 } else { 13461 callerPackage = null; 13462 callingUid = Binder.getCallingUid(); 13463 callingPid = Binder.getCallingPid(); 13464 } 13465 13466 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13467 true, true, "registerReceiver", callerPackage); 13468 13469 List allSticky = null; 13470 13471 // Look for any matching sticky broadcasts... 13472 Iterator actions = filter.actionsIterator(); 13473 if (actions != null) { 13474 while (actions.hasNext()) { 13475 String action = (String)actions.next(); 13476 allSticky = getStickiesLocked(action, filter, allSticky, 13477 UserHandle.USER_ALL); 13478 allSticky = getStickiesLocked(action, filter, allSticky, 13479 UserHandle.getUserId(callingUid)); 13480 } 13481 } else { 13482 allSticky = getStickiesLocked(null, filter, allSticky, 13483 UserHandle.USER_ALL); 13484 allSticky = getStickiesLocked(null, filter, allSticky, 13485 UserHandle.getUserId(callingUid)); 13486 } 13487 13488 // The first sticky in the list is returned directly back to 13489 // the client. 13490 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13491 13492 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13493 + ": " + sticky); 13494 13495 if (receiver == null) { 13496 return sticky; 13497 } 13498 13499 ReceiverList rl 13500 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13501 if (rl == null) { 13502 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13503 userId, receiver); 13504 if (rl.app != null) { 13505 rl.app.receivers.add(rl); 13506 } else { 13507 try { 13508 receiver.asBinder().linkToDeath(rl, 0); 13509 } catch (RemoteException e) { 13510 return sticky; 13511 } 13512 rl.linkedToDeath = true; 13513 } 13514 mRegisteredReceivers.put(receiver.asBinder(), rl); 13515 } else if (rl.uid != callingUid) { 13516 throw new IllegalArgumentException( 13517 "Receiver requested to register for uid " + callingUid 13518 + " was previously registered for uid " + rl.uid); 13519 } else if (rl.pid != callingPid) { 13520 throw new IllegalArgumentException( 13521 "Receiver requested to register for pid " + callingPid 13522 + " was previously registered for pid " + rl.pid); 13523 } else if (rl.userId != userId) { 13524 throw new IllegalArgumentException( 13525 "Receiver requested to register for user " + userId 13526 + " was previously registered for user " + rl.userId); 13527 } 13528 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13529 permission, callingUid, userId); 13530 rl.add(bf); 13531 if (!bf.debugCheck()) { 13532 Slog.w(TAG, "==> For Dynamic broadast"); 13533 } 13534 mReceiverResolver.addFilter(bf); 13535 13536 // Enqueue broadcasts for all existing stickies that match 13537 // this filter. 13538 if (allSticky != null) { 13539 ArrayList receivers = new ArrayList(); 13540 receivers.add(bf); 13541 13542 int N = allSticky.size(); 13543 for (int i=0; i<N; i++) { 13544 Intent intent = (Intent)allSticky.get(i); 13545 BroadcastQueue queue = broadcastQueueForIntent(intent); 13546 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13547 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13548 null, null, false, true, true, -1); 13549 queue.enqueueParallelBroadcastLocked(r); 13550 queue.scheduleBroadcastsLocked(); 13551 } 13552 } 13553 13554 return sticky; 13555 } 13556 } 13557 13558 public void unregisterReceiver(IIntentReceiver receiver) { 13559 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13560 13561 final long origId = Binder.clearCallingIdentity(); 13562 try { 13563 boolean doTrim = false; 13564 13565 synchronized(this) { 13566 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13567 if (rl != null) { 13568 if (rl.curBroadcast != null) { 13569 BroadcastRecord r = rl.curBroadcast; 13570 final boolean doNext = finishReceiverLocked( 13571 receiver.asBinder(), r.resultCode, r.resultData, 13572 r.resultExtras, r.resultAbort); 13573 if (doNext) { 13574 doTrim = true; 13575 r.queue.processNextBroadcast(false); 13576 } 13577 } 13578 13579 if (rl.app != null) { 13580 rl.app.receivers.remove(rl); 13581 } 13582 removeReceiverLocked(rl); 13583 if (rl.linkedToDeath) { 13584 rl.linkedToDeath = false; 13585 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13586 } 13587 } 13588 } 13589 13590 // If we actually concluded any broadcasts, we might now be able 13591 // to trim the recipients' apps from our working set 13592 if (doTrim) { 13593 trimApplications(); 13594 return; 13595 } 13596 13597 } finally { 13598 Binder.restoreCallingIdentity(origId); 13599 } 13600 } 13601 13602 void removeReceiverLocked(ReceiverList rl) { 13603 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13604 int N = rl.size(); 13605 for (int i=0; i<N; i++) { 13606 mReceiverResolver.removeFilter(rl.get(i)); 13607 } 13608 } 13609 13610 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13611 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13612 ProcessRecord r = mLruProcesses.get(i); 13613 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13614 try { 13615 r.thread.dispatchPackageBroadcast(cmd, packages); 13616 } catch (RemoteException ex) { 13617 } 13618 } 13619 } 13620 } 13621 13622 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13623 int[] users) { 13624 List<ResolveInfo> receivers = null; 13625 try { 13626 HashSet<ComponentName> singleUserReceivers = null; 13627 boolean scannedFirstReceivers = false; 13628 for (int user : users) { 13629 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13630 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13631 if (user != 0 && newReceivers != null) { 13632 // If this is not the primary user, we need to check for 13633 // any receivers that should be filtered out. 13634 for (int i=0; i<newReceivers.size(); i++) { 13635 ResolveInfo ri = newReceivers.get(i); 13636 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13637 newReceivers.remove(i); 13638 i--; 13639 } 13640 } 13641 } 13642 if (newReceivers != null && newReceivers.size() == 0) { 13643 newReceivers = null; 13644 } 13645 if (receivers == null) { 13646 receivers = newReceivers; 13647 } else if (newReceivers != null) { 13648 // We need to concatenate the additional receivers 13649 // found with what we have do far. This would be easy, 13650 // but we also need to de-dup any receivers that are 13651 // singleUser. 13652 if (!scannedFirstReceivers) { 13653 // Collect any single user receivers we had already retrieved. 13654 scannedFirstReceivers = true; 13655 for (int i=0; i<receivers.size(); i++) { 13656 ResolveInfo ri = receivers.get(i); 13657 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13658 ComponentName cn = new ComponentName( 13659 ri.activityInfo.packageName, ri.activityInfo.name); 13660 if (singleUserReceivers == null) { 13661 singleUserReceivers = new HashSet<ComponentName>(); 13662 } 13663 singleUserReceivers.add(cn); 13664 } 13665 } 13666 } 13667 // Add the new results to the existing results, tracking 13668 // and de-dupping single user receivers. 13669 for (int i=0; i<newReceivers.size(); i++) { 13670 ResolveInfo ri = newReceivers.get(i); 13671 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13672 ComponentName cn = new ComponentName( 13673 ri.activityInfo.packageName, ri.activityInfo.name); 13674 if (singleUserReceivers == null) { 13675 singleUserReceivers = new HashSet<ComponentName>(); 13676 } 13677 if (!singleUserReceivers.contains(cn)) { 13678 singleUserReceivers.add(cn); 13679 receivers.add(ri); 13680 } 13681 } else { 13682 receivers.add(ri); 13683 } 13684 } 13685 } 13686 } 13687 } catch (RemoteException ex) { 13688 // pm is in same process, this will never happen. 13689 } 13690 return receivers; 13691 } 13692 13693 private final int broadcastIntentLocked(ProcessRecord callerApp, 13694 String callerPackage, Intent intent, String resolvedType, 13695 IIntentReceiver resultTo, int resultCode, String resultData, 13696 Bundle map, String requiredPermission, int appOp, 13697 boolean ordered, boolean sticky, int callingPid, int callingUid, 13698 int userId) { 13699 intent = new Intent(intent); 13700 13701 // By default broadcasts do not go to stopped apps. 13702 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13703 13704 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13705 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13706 + " ordered=" + ordered + " userid=" + userId); 13707 if ((resultTo != null) && !ordered) { 13708 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13709 } 13710 13711 userId = handleIncomingUser(callingPid, callingUid, userId, 13712 true, false, "broadcast", callerPackage); 13713 13714 // Make sure that the user who is receiving this broadcast is started. 13715 // If not, we will just skip it. 13716 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13717 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13718 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13719 Slog.w(TAG, "Skipping broadcast of " + intent 13720 + ": user " + userId + " is stopped"); 13721 return ActivityManager.BROADCAST_SUCCESS; 13722 } 13723 } 13724 13725 /* 13726 * Prevent non-system code (defined here to be non-persistent 13727 * processes) from sending protected broadcasts. 13728 */ 13729 int callingAppId = UserHandle.getAppId(callingUid); 13730 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13731 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13732 callingUid == 0) { 13733 // Always okay. 13734 } else if (callerApp == null || !callerApp.persistent) { 13735 try { 13736 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13737 intent.getAction())) { 13738 String msg = "Permission Denial: not allowed to send broadcast " 13739 + intent.getAction() + " from pid=" 13740 + callingPid + ", uid=" + callingUid; 13741 Slog.w(TAG, msg); 13742 throw new SecurityException(msg); 13743 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13744 // Special case for compatibility: we don't want apps to send this, 13745 // but historically it has not been protected and apps may be using it 13746 // to poke their own app widget. So, instead of making it protected, 13747 // just limit it to the caller. 13748 if (callerApp == null) { 13749 String msg = "Permission Denial: not allowed to send broadcast " 13750 + intent.getAction() + " from unknown caller."; 13751 Slog.w(TAG, msg); 13752 throw new SecurityException(msg); 13753 } else if (intent.getComponent() != null) { 13754 // They are good enough to send to an explicit component... verify 13755 // it is being sent to the calling app. 13756 if (!intent.getComponent().getPackageName().equals( 13757 callerApp.info.packageName)) { 13758 String msg = "Permission Denial: not allowed to send broadcast " 13759 + intent.getAction() + " to " 13760 + intent.getComponent().getPackageName() + " from " 13761 + callerApp.info.packageName; 13762 Slog.w(TAG, msg); 13763 throw new SecurityException(msg); 13764 } 13765 } else { 13766 // Limit broadcast to their own package. 13767 intent.setPackage(callerApp.info.packageName); 13768 } 13769 } 13770 } catch (RemoteException e) { 13771 Slog.w(TAG, "Remote exception", e); 13772 return ActivityManager.BROADCAST_SUCCESS; 13773 } 13774 } 13775 13776 // Handle special intents: if this broadcast is from the package 13777 // manager about a package being removed, we need to remove all of 13778 // its activities from the history stack. 13779 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13780 intent.getAction()); 13781 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13782 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13783 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13784 || uidRemoved) { 13785 if (checkComponentPermission( 13786 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13787 callingPid, callingUid, -1, true) 13788 == PackageManager.PERMISSION_GRANTED) { 13789 if (uidRemoved) { 13790 final Bundle intentExtras = intent.getExtras(); 13791 final int uid = intentExtras != null 13792 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13793 if (uid >= 0) { 13794 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13795 synchronized (bs) { 13796 bs.removeUidStatsLocked(uid); 13797 } 13798 mAppOpsService.uidRemoved(uid); 13799 } 13800 } else { 13801 // If resources are unavailable just force stop all 13802 // those packages and flush the attribute cache as well. 13803 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13804 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13805 if (list != null && (list.length > 0)) { 13806 for (String pkg : list) { 13807 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13808 "storage unmount"); 13809 } 13810 sendPackageBroadcastLocked( 13811 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13812 } 13813 } else { 13814 Uri data = intent.getData(); 13815 String ssp; 13816 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13817 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13818 intent.getAction()); 13819 boolean fullUninstall = removed && 13820 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13821 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13822 forceStopPackageLocked(ssp, UserHandle.getAppId( 13823 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13824 false, fullUninstall, userId, 13825 removed ? "pkg removed" : "pkg changed"); 13826 } 13827 if (removed) { 13828 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13829 new String[] {ssp}, userId); 13830 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13831 mAppOpsService.packageRemoved( 13832 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13833 13834 // Remove all permissions granted from/to this package 13835 removeUriPermissionsForPackageLocked(ssp, userId, true); 13836 } 13837 } 13838 } 13839 } 13840 } 13841 } else { 13842 String msg = "Permission Denial: " + intent.getAction() 13843 + " broadcast from " + callerPackage + " (pid=" + callingPid 13844 + ", uid=" + callingUid + ")" 13845 + " requires " 13846 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13847 Slog.w(TAG, msg); 13848 throw new SecurityException(msg); 13849 } 13850 13851 // Special case for adding a package: by default turn on compatibility 13852 // mode. 13853 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13854 Uri data = intent.getData(); 13855 String ssp; 13856 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13857 mCompatModePackages.handlePackageAddedLocked(ssp, 13858 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13859 } 13860 } 13861 13862 /* 13863 * If this is the time zone changed action, queue up a message that will reset the timezone 13864 * of all currently running processes. This message will get queued up before the broadcast 13865 * happens. 13866 */ 13867 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13868 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13869 } 13870 13871 /* 13872 * If the user set the time, let all running processes know. 13873 */ 13874 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13875 final int is24Hour = intent.getBooleanExtra( 13876 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13877 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13878 } 13879 13880 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13881 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13882 } 13883 13884 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13885 ProxyInfo proxy = intent.getParcelableExtra("proxy"); 13886 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13887 } 13888 13889 // Add to the sticky list if requested. 13890 if (sticky) { 13891 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13892 callingPid, callingUid) 13893 != PackageManager.PERMISSION_GRANTED) { 13894 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13895 + callingPid + ", uid=" + callingUid 13896 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13897 Slog.w(TAG, msg); 13898 throw new SecurityException(msg); 13899 } 13900 if (requiredPermission != null) { 13901 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13902 + " and enforce permission " + requiredPermission); 13903 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13904 } 13905 if (intent.getComponent() != null) { 13906 throw new SecurityException( 13907 "Sticky broadcasts can't target a specific component"); 13908 } 13909 // We use userId directly here, since the "all" target is maintained 13910 // as a separate set of sticky broadcasts. 13911 if (userId != UserHandle.USER_ALL) { 13912 // But first, if this is not a broadcast to all users, then 13913 // make sure it doesn't conflict with an existing broadcast to 13914 // all users. 13915 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13916 UserHandle.USER_ALL); 13917 if (stickies != null) { 13918 ArrayList<Intent> list = stickies.get(intent.getAction()); 13919 if (list != null) { 13920 int N = list.size(); 13921 int i; 13922 for (i=0; i<N; i++) { 13923 if (intent.filterEquals(list.get(i))) { 13924 throw new IllegalArgumentException( 13925 "Sticky broadcast " + intent + " for user " 13926 + userId + " conflicts with existing global broadcast"); 13927 } 13928 } 13929 } 13930 } 13931 } 13932 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13933 if (stickies == null) { 13934 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13935 mStickyBroadcasts.put(userId, stickies); 13936 } 13937 ArrayList<Intent> list = stickies.get(intent.getAction()); 13938 if (list == null) { 13939 list = new ArrayList<Intent>(); 13940 stickies.put(intent.getAction(), list); 13941 } 13942 int N = list.size(); 13943 int i; 13944 for (i=0; i<N; i++) { 13945 if (intent.filterEquals(list.get(i))) { 13946 // This sticky already exists, replace it. 13947 list.set(i, new Intent(intent)); 13948 break; 13949 } 13950 } 13951 if (i >= N) { 13952 list.add(new Intent(intent)); 13953 } 13954 } 13955 13956 int[] users; 13957 if (userId == UserHandle.USER_ALL) { 13958 // Caller wants broadcast to go to all started users. 13959 users = mStartedUserArray; 13960 } else { 13961 // Caller wants broadcast to go to one specific user. 13962 users = new int[] {userId}; 13963 } 13964 13965 // Figure out who all will receive this broadcast. 13966 List receivers = null; 13967 List<BroadcastFilter> registeredReceivers = null; 13968 // Need to resolve the intent to interested receivers... 13969 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13970 == 0) { 13971 receivers = collectReceiverComponents(intent, resolvedType, users); 13972 } 13973 if (intent.getComponent() == null) { 13974 registeredReceivers = mReceiverResolver.queryIntent(intent, 13975 resolvedType, false, userId); 13976 } 13977 13978 final boolean replacePending = 13979 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13980 13981 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13982 + " replacePending=" + replacePending); 13983 13984 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13985 if (!ordered && NR > 0) { 13986 // If we are not serializing this broadcast, then send the 13987 // registered receivers separately so they don't wait for the 13988 // components to be launched. 13989 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13990 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13991 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13992 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13993 ordered, sticky, false, userId); 13994 if (DEBUG_BROADCAST) Slog.v( 13995 TAG, "Enqueueing parallel broadcast " + r); 13996 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13997 if (!replaced) { 13998 queue.enqueueParallelBroadcastLocked(r); 13999 queue.scheduleBroadcastsLocked(); 14000 } 14001 registeredReceivers = null; 14002 NR = 0; 14003 } 14004 14005 // Merge into one list. 14006 int ir = 0; 14007 if (receivers != null) { 14008 // A special case for PACKAGE_ADDED: do not allow the package 14009 // being added to see this broadcast. This prevents them from 14010 // using this as a back door to get run as soon as they are 14011 // installed. Maybe in the future we want to have a special install 14012 // broadcast or such for apps, but we'd like to deliberately make 14013 // this decision. 14014 String skipPackages[] = null; 14015 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 14016 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 14017 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 14018 Uri data = intent.getData(); 14019 if (data != null) { 14020 String pkgName = data.getSchemeSpecificPart(); 14021 if (pkgName != null) { 14022 skipPackages = new String[] { pkgName }; 14023 } 14024 } 14025 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 14026 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14027 } 14028 if (skipPackages != null && (skipPackages.length > 0)) { 14029 for (String skipPackage : skipPackages) { 14030 if (skipPackage != null) { 14031 int NT = receivers.size(); 14032 for (int it=0; it<NT; it++) { 14033 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14034 if (curt.activityInfo.packageName.equals(skipPackage)) { 14035 receivers.remove(it); 14036 it--; 14037 NT--; 14038 } 14039 } 14040 } 14041 } 14042 } 14043 14044 int NT = receivers != null ? receivers.size() : 0; 14045 int it = 0; 14046 ResolveInfo curt = null; 14047 BroadcastFilter curr = null; 14048 while (it < NT && ir < NR) { 14049 if (curt == null) { 14050 curt = (ResolveInfo)receivers.get(it); 14051 } 14052 if (curr == null) { 14053 curr = registeredReceivers.get(ir); 14054 } 14055 if (curr.getPriority() >= curt.priority) { 14056 // Insert this broadcast record into the final list. 14057 receivers.add(it, curr); 14058 ir++; 14059 curr = null; 14060 it++; 14061 NT++; 14062 } else { 14063 // Skip to the next ResolveInfo in the final list. 14064 it++; 14065 curt = null; 14066 } 14067 } 14068 } 14069 while (ir < NR) { 14070 if (receivers == null) { 14071 receivers = new ArrayList(); 14072 } 14073 receivers.add(registeredReceivers.get(ir)); 14074 ir++; 14075 } 14076 14077 if ((receivers != null && receivers.size() > 0) 14078 || resultTo != null) { 14079 BroadcastQueue queue = broadcastQueueForIntent(intent); 14080 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14081 callerPackage, callingPid, callingUid, resolvedType, 14082 requiredPermission, appOp, receivers, resultTo, resultCode, 14083 resultData, map, ordered, sticky, false, userId); 14084 if (DEBUG_BROADCAST) Slog.v( 14085 TAG, "Enqueueing ordered broadcast " + r 14086 + ": prev had " + queue.mOrderedBroadcasts.size()); 14087 if (DEBUG_BROADCAST) { 14088 int seq = r.intent.getIntExtra("seq", -1); 14089 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14090 } 14091 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14092 if (!replaced) { 14093 queue.enqueueOrderedBroadcastLocked(r); 14094 queue.scheduleBroadcastsLocked(); 14095 } 14096 } 14097 14098 return ActivityManager.BROADCAST_SUCCESS; 14099 } 14100 14101 final Intent verifyBroadcastLocked(Intent intent) { 14102 // Refuse possible leaked file descriptors 14103 if (intent != null && intent.hasFileDescriptors() == true) { 14104 throw new IllegalArgumentException("File descriptors passed in Intent"); 14105 } 14106 14107 int flags = intent.getFlags(); 14108 14109 if (!mProcessesReady) { 14110 // if the caller really truly claims to know what they're doing, go 14111 // ahead and allow the broadcast without launching any receivers 14112 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14113 intent = new Intent(intent); 14114 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14115 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14116 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14117 + " before boot completion"); 14118 throw new IllegalStateException("Cannot broadcast before boot completed"); 14119 } 14120 } 14121 14122 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14123 throw new IllegalArgumentException( 14124 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14125 } 14126 14127 return intent; 14128 } 14129 14130 public final int broadcastIntent(IApplicationThread caller, 14131 Intent intent, String resolvedType, IIntentReceiver resultTo, 14132 int resultCode, String resultData, Bundle map, 14133 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14134 enforceNotIsolatedCaller("broadcastIntent"); 14135 synchronized(this) { 14136 intent = verifyBroadcastLocked(intent); 14137 14138 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14139 final int callingPid = Binder.getCallingPid(); 14140 final int callingUid = Binder.getCallingUid(); 14141 final long origId = Binder.clearCallingIdentity(); 14142 int res = broadcastIntentLocked(callerApp, 14143 callerApp != null ? callerApp.info.packageName : null, 14144 intent, resolvedType, resultTo, 14145 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14146 callingPid, callingUid, userId); 14147 Binder.restoreCallingIdentity(origId); 14148 return res; 14149 } 14150 } 14151 14152 int broadcastIntentInPackage(String packageName, int uid, 14153 Intent intent, String resolvedType, IIntentReceiver resultTo, 14154 int resultCode, String resultData, Bundle map, 14155 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14156 synchronized(this) { 14157 intent = verifyBroadcastLocked(intent); 14158 14159 final long origId = Binder.clearCallingIdentity(); 14160 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14161 resultTo, resultCode, resultData, map, requiredPermission, 14162 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14163 Binder.restoreCallingIdentity(origId); 14164 return res; 14165 } 14166 } 14167 14168 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14169 // Refuse possible leaked file descriptors 14170 if (intent != null && intent.hasFileDescriptors() == true) { 14171 throw new IllegalArgumentException("File descriptors passed in Intent"); 14172 } 14173 14174 userId = handleIncomingUser(Binder.getCallingPid(), 14175 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14176 14177 synchronized(this) { 14178 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14179 != PackageManager.PERMISSION_GRANTED) { 14180 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14181 + Binder.getCallingPid() 14182 + ", uid=" + Binder.getCallingUid() 14183 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14184 Slog.w(TAG, msg); 14185 throw new SecurityException(msg); 14186 } 14187 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14188 if (stickies != null) { 14189 ArrayList<Intent> list = stickies.get(intent.getAction()); 14190 if (list != null) { 14191 int N = list.size(); 14192 int i; 14193 for (i=0; i<N; i++) { 14194 if (intent.filterEquals(list.get(i))) { 14195 list.remove(i); 14196 break; 14197 } 14198 } 14199 if (list.size() <= 0) { 14200 stickies.remove(intent.getAction()); 14201 } 14202 } 14203 if (stickies.size() <= 0) { 14204 mStickyBroadcasts.remove(userId); 14205 } 14206 } 14207 } 14208 } 14209 14210 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14211 String resultData, Bundle resultExtras, boolean resultAbort) { 14212 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14213 if (r == null) { 14214 Slog.w(TAG, "finishReceiver called but not found on queue"); 14215 return false; 14216 } 14217 14218 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14219 } 14220 14221 void backgroundServicesFinishedLocked(int userId) { 14222 for (BroadcastQueue queue : mBroadcastQueues) { 14223 queue.backgroundServicesFinishedLocked(userId); 14224 } 14225 } 14226 14227 public void finishReceiver(IBinder who, int resultCode, String resultData, 14228 Bundle resultExtras, boolean resultAbort) { 14229 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14230 14231 // Refuse possible leaked file descriptors 14232 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14233 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14234 } 14235 14236 final long origId = Binder.clearCallingIdentity(); 14237 try { 14238 boolean doNext = false; 14239 BroadcastRecord r; 14240 14241 synchronized(this) { 14242 r = broadcastRecordForReceiverLocked(who); 14243 if (r != null) { 14244 doNext = r.queue.finishReceiverLocked(r, resultCode, 14245 resultData, resultExtras, resultAbort, true); 14246 } 14247 } 14248 14249 if (doNext) { 14250 r.queue.processNextBroadcast(false); 14251 } 14252 trimApplications(); 14253 } finally { 14254 Binder.restoreCallingIdentity(origId); 14255 } 14256 } 14257 14258 // ========================================================= 14259 // INSTRUMENTATION 14260 // ========================================================= 14261 14262 public boolean startInstrumentation(ComponentName className, 14263 String profileFile, int flags, Bundle arguments, 14264 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14265 int userId) { 14266 enforceNotIsolatedCaller("startInstrumentation"); 14267 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14268 userId, false, true, "startInstrumentation", null); 14269 // Refuse possible leaked file descriptors 14270 if (arguments != null && arguments.hasFileDescriptors()) { 14271 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14272 } 14273 14274 synchronized(this) { 14275 InstrumentationInfo ii = null; 14276 ApplicationInfo ai = null; 14277 try { 14278 ii = mContext.getPackageManager().getInstrumentationInfo( 14279 className, STOCK_PM_FLAGS); 14280 ai = AppGlobals.getPackageManager().getApplicationInfo( 14281 ii.targetPackage, STOCK_PM_FLAGS, userId); 14282 } catch (PackageManager.NameNotFoundException e) { 14283 } catch (RemoteException e) { 14284 } 14285 if (ii == null) { 14286 reportStartInstrumentationFailure(watcher, className, 14287 "Unable to find instrumentation info for: " + className); 14288 return false; 14289 } 14290 if (ai == null) { 14291 reportStartInstrumentationFailure(watcher, className, 14292 "Unable to find instrumentation target package: " + ii.targetPackage); 14293 return false; 14294 } 14295 14296 int match = mContext.getPackageManager().checkSignatures( 14297 ii.targetPackage, ii.packageName); 14298 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14299 String msg = "Permission Denial: starting instrumentation " 14300 + className + " from pid=" 14301 + Binder.getCallingPid() 14302 + ", uid=" + Binder.getCallingPid() 14303 + " not allowed because package " + ii.packageName 14304 + " does not have a signature matching the target " 14305 + ii.targetPackage; 14306 reportStartInstrumentationFailure(watcher, className, msg); 14307 throw new SecurityException(msg); 14308 } 14309 14310 final long origId = Binder.clearCallingIdentity(); 14311 // Instrumentation can kill and relaunch even persistent processes 14312 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14313 "start instr"); 14314 ProcessRecord app = addAppLocked(ai, false); 14315 app.instrumentationClass = className; 14316 app.instrumentationInfo = ai; 14317 app.instrumentationProfileFile = profileFile; 14318 app.instrumentationArguments = arguments; 14319 app.instrumentationWatcher = watcher; 14320 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14321 app.instrumentationResultClass = className; 14322 Binder.restoreCallingIdentity(origId); 14323 } 14324 14325 return true; 14326 } 14327 14328 /** 14329 * Report errors that occur while attempting to start Instrumentation. Always writes the 14330 * error to the logs, but if somebody is watching, send the report there too. This enables 14331 * the "am" command to report errors with more information. 14332 * 14333 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14334 * @param cn The component name of the instrumentation. 14335 * @param report The error report. 14336 */ 14337 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14338 ComponentName cn, String report) { 14339 Slog.w(TAG, report); 14340 try { 14341 if (watcher != null) { 14342 Bundle results = new Bundle(); 14343 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14344 results.putString("Error", report); 14345 watcher.instrumentationStatus(cn, -1, results); 14346 } 14347 } catch (RemoteException e) { 14348 Slog.w(TAG, e); 14349 } 14350 } 14351 14352 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14353 if (app.instrumentationWatcher != null) { 14354 try { 14355 // NOTE: IInstrumentationWatcher *must* be oneway here 14356 app.instrumentationWatcher.instrumentationFinished( 14357 app.instrumentationClass, 14358 resultCode, 14359 results); 14360 } catch (RemoteException e) { 14361 } 14362 } 14363 if (app.instrumentationUiAutomationConnection != null) { 14364 try { 14365 app.instrumentationUiAutomationConnection.shutdown(); 14366 } catch (RemoteException re) { 14367 /* ignore */ 14368 } 14369 // Only a UiAutomation can set this flag and now that 14370 // it is finished we make sure it is reset to its default. 14371 mUserIsMonkey = false; 14372 } 14373 app.instrumentationWatcher = null; 14374 app.instrumentationUiAutomationConnection = null; 14375 app.instrumentationClass = null; 14376 app.instrumentationInfo = null; 14377 app.instrumentationProfileFile = null; 14378 app.instrumentationArguments = null; 14379 14380 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14381 "finished inst"); 14382 } 14383 14384 public void finishInstrumentation(IApplicationThread target, 14385 int resultCode, Bundle results) { 14386 int userId = UserHandle.getCallingUserId(); 14387 // Refuse possible leaked file descriptors 14388 if (results != null && results.hasFileDescriptors()) { 14389 throw new IllegalArgumentException("File descriptors passed in Intent"); 14390 } 14391 14392 synchronized(this) { 14393 ProcessRecord app = getRecordForAppLocked(target); 14394 if (app == null) { 14395 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14396 return; 14397 } 14398 final long origId = Binder.clearCallingIdentity(); 14399 finishInstrumentationLocked(app, resultCode, results); 14400 Binder.restoreCallingIdentity(origId); 14401 } 14402 } 14403 14404 // ========================================================= 14405 // CONFIGURATION 14406 // ========================================================= 14407 14408 public ConfigurationInfo getDeviceConfigurationInfo() { 14409 ConfigurationInfo config = new ConfigurationInfo(); 14410 synchronized (this) { 14411 config.reqTouchScreen = mConfiguration.touchscreen; 14412 config.reqKeyboardType = mConfiguration.keyboard; 14413 config.reqNavigation = mConfiguration.navigation; 14414 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14415 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14416 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14417 } 14418 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14419 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14420 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14421 } 14422 config.reqGlEsVersion = GL_ES_VERSION; 14423 } 14424 return config; 14425 } 14426 14427 ActivityStack getFocusedStack() { 14428 return mStackSupervisor.getFocusedStack(); 14429 } 14430 14431 public Configuration getConfiguration() { 14432 Configuration ci; 14433 synchronized(this) { 14434 ci = new Configuration(mConfiguration); 14435 } 14436 return ci; 14437 } 14438 14439 public void updatePersistentConfiguration(Configuration values) { 14440 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14441 "updateConfiguration()"); 14442 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14443 "updateConfiguration()"); 14444 if (values == null) { 14445 throw new NullPointerException("Configuration must not be null"); 14446 } 14447 14448 synchronized(this) { 14449 final long origId = Binder.clearCallingIdentity(); 14450 updateConfigurationLocked(values, null, true, false); 14451 Binder.restoreCallingIdentity(origId); 14452 } 14453 } 14454 14455 public void updateConfiguration(Configuration values) { 14456 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14457 "updateConfiguration()"); 14458 14459 synchronized(this) { 14460 if (values == null && mWindowManager != null) { 14461 // sentinel: fetch the current configuration from the window manager 14462 values = mWindowManager.computeNewConfiguration(); 14463 } 14464 14465 if (mWindowManager != null) { 14466 mProcessList.applyDisplaySize(mWindowManager); 14467 } 14468 14469 final long origId = Binder.clearCallingIdentity(); 14470 if (values != null) { 14471 Settings.System.clearConfiguration(values); 14472 } 14473 updateConfigurationLocked(values, null, false, false); 14474 Binder.restoreCallingIdentity(origId); 14475 } 14476 } 14477 14478 /** 14479 * Do either or both things: (1) change the current configuration, and (2) 14480 * make sure the given activity is running with the (now) current 14481 * configuration. Returns true if the activity has been left running, or 14482 * false if <var>starting</var> is being destroyed to match the new 14483 * configuration. 14484 * @param persistent TODO 14485 */ 14486 boolean updateConfigurationLocked(Configuration values, 14487 ActivityRecord starting, boolean persistent, boolean initLocale) { 14488 int changes = 0; 14489 14490 if (values != null) { 14491 Configuration newConfig = new Configuration(mConfiguration); 14492 changes = newConfig.updateFrom(values); 14493 if (changes != 0) { 14494 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14495 Slog.i(TAG, "Updating configuration to: " + values); 14496 } 14497 14498 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14499 14500 if (values.locale != null && !initLocale) { 14501 saveLocaleLocked(values.locale, 14502 !values.locale.equals(mConfiguration.locale), 14503 values.userSetLocale); 14504 } 14505 14506 mConfigurationSeq++; 14507 if (mConfigurationSeq <= 0) { 14508 mConfigurationSeq = 1; 14509 } 14510 newConfig.seq = mConfigurationSeq; 14511 mConfiguration = newConfig; 14512 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14513 mUsageStatsService.noteStartConfig(newConfig); 14514 14515 final Configuration configCopy = new Configuration(mConfiguration); 14516 14517 // TODO: If our config changes, should we auto dismiss any currently 14518 // showing dialogs? 14519 mShowDialogs = shouldShowDialogs(newConfig); 14520 14521 AttributeCache ac = AttributeCache.instance(); 14522 if (ac != null) { 14523 ac.updateConfiguration(configCopy); 14524 } 14525 14526 // Make sure all resources in our process are updated 14527 // right now, so that anyone who is going to retrieve 14528 // resource values after we return will be sure to get 14529 // the new ones. This is especially important during 14530 // boot, where the first config change needs to guarantee 14531 // all resources have that config before following boot 14532 // code is executed. 14533 mSystemThread.applyConfigurationToResources(configCopy); 14534 14535 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14536 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14537 msg.obj = new Configuration(configCopy); 14538 mHandler.sendMessage(msg); 14539 } 14540 14541 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14542 ProcessRecord app = mLruProcesses.get(i); 14543 try { 14544 if (app.thread != null) { 14545 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14546 + app.processName + " new config " + mConfiguration); 14547 app.thread.scheduleConfigurationChanged(configCopy); 14548 } 14549 } catch (Exception e) { 14550 } 14551 } 14552 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14553 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14554 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14555 | Intent.FLAG_RECEIVER_FOREGROUND); 14556 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14557 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14558 Process.SYSTEM_UID, UserHandle.USER_ALL); 14559 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14560 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14561 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14562 broadcastIntentLocked(null, null, intent, 14563 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14564 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14565 } 14566 } 14567 } 14568 14569 boolean kept = true; 14570 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14571 // mainStack is null during startup. 14572 if (mainStack != null) { 14573 if (changes != 0 && starting == null) { 14574 // If the configuration changed, and the caller is not already 14575 // in the process of starting an activity, then find the top 14576 // activity to check if its configuration needs to change. 14577 starting = mainStack.topRunningActivityLocked(null); 14578 } 14579 14580 if (starting != null) { 14581 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14582 // And we need to make sure at this point that all other activities 14583 // are made visible with the correct configuration. 14584 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14585 } 14586 } 14587 14588 if (values != null && mWindowManager != null) { 14589 mWindowManager.setNewConfiguration(mConfiguration); 14590 } 14591 14592 return kept; 14593 } 14594 14595 /** 14596 * Decide based on the configuration whether we should shouw the ANR, 14597 * crash, etc dialogs. The idea is that if there is no affordnace to 14598 * press the on-screen buttons, we shouldn't show the dialog. 14599 * 14600 * A thought: SystemUI might also want to get told about this, the Power 14601 * dialog / global actions also might want different behaviors. 14602 */ 14603 private static final boolean shouldShowDialogs(Configuration config) { 14604 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14605 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14606 } 14607 14608 /** 14609 * Save the locale. You must be inside a synchronized (this) block. 14610 */ 14611 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14612 if(isDiff) { 14613 SystemProperties.set("user.language", l.getLanguage()); 14614 SystemProperties.set("user.region", l.getCountry()); 14615 } 14616 14617 if(isPersist) { 14618 SystemProperties.set("persist.sys.language", l.getLanguage()); 14619 SystemProperties.set("persist.sys.country", l.getCountry()); 14620 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14621 } 14622 } 14623 14624 @Override 14625 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14626 ActivityRecord srec = ActivityRecord.forToken(token); 14627 return srec != null && srec.task.affinity != null && 14628 srec.task.affinity.equals(destAffinity); 14629 } 14630 14631 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14632 Intent resultData) { 14633 14634 synchronized (this) { 14635 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14636 if (stack != null) { 14637 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14638 } 14639 return false; 14640 } 14641 } 14642 14643 public int getLaunchedFromUid(IBinder activityToken) { 14644 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14645 if (srec == null) { 14646 return -1; 14647 } 14648 return srec.launchedFromUid; 14649 } 14650 14651 public String getLaunchedFromPackage(IBinder activityToken) { 14652 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14653 if (srec == null) { 14654 return null; 14655 } 14656 return srec.launchedFromPackage; 14657 } 14658 14659 // ========================================================= 14660 // LIFETIME MANAGEMENT 14661 // ========================================================= 14662 14663 // Returns which broadcast queue the app is the current [or imminent] receiver 14664 // on, or 'null' if the app is not an active broadcast recipient. 14665 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14666 BroadcastRecord r = app.curReceiver; 14667 if (r != null) { 14668 return r.queue; 14669 } 14670 14671 // It's not the current receiver, but it might be starting up to become one 14672 synchronized (this) { 14673 for (BroadcastQueue queue : mBroadcastQueues) { 14674 r = queue.mPendingBroadcast; 14675 if (r != null && r.curApp == app) { 14676 // found it; report which queue it's in 14677 return queue; 14678 } 14679 } 14680 } 14681 14682 return null; 14683 } 14684 14685 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14686 boolean doingAll, long now) { 14687 if (mAdjSeq == app.adjSeq) { 14688 // This adjustment has already been computed. 14689 return app.curRawAdj; 14690 } 14691 14692 if (app.thread == null) { 14693 app.adjSeq = mAdjSeq; 14694 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14695 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14696 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14697 } 14698 14699 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14700 app.adjSource = null; 14701 app.adjTarget = null; 14702 app.empty = false; 14703 app.cached = false; 14704 14705 final int activitiesSize = app.activities.size(); 14706 14707 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14708 // The max adjustment doesn't allow this app to be anything 14709 // below foreground, so it is not worth doing work for it. 14710 app.adjType = "fixed"; 14711 app.adjSeq = mAdjSeq; 14712 app.curRawAdj = app.maxAdj; 14713 app.foregroundActivities = false; 14714 app.keeping = true; 14715 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14716 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14717 // System processes can do UI, and when they do we want to have 14718 // them trim their memory after the user leaves the UI. To 14719 // facilitate this, here we need to determine whether or not it 14720 // is currently showing UI. 14721 app.systemNoUi = true; 14722 if (app == TOP_APP) { 14723 app.systemNoUi = false; 14724 } else if (activitiesSize > 0) { 14725 for (int j = 0; j < activitiesSize; j++) { 14726 final ActivityRecord r = app.activities.get(j); 14727 if (r.visible) { 14728 app.systemNoUi = false; 14729 } 14730 } 14731 } 14732 if (!app.systemNoUi) { 14733 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14734 } 14735 return (app.curAdj=app.maxAdj); 14736 } 14737 14738 app.keeping = false; 14739 app.systemNoUi = false; 14740 14741 // Determine the importance of the process, starting with most 14742 // important to least, and assign an appropriate OOM adjustment. 14743 int adj; 14744 int schedGroup; 14745 int procState; 14746 boolean foregroundActivities = false; 14747 boolean interesting = false; 14748 BroadcastQueue queue; 14749 if (app == TOP_APP) { 14750 // The last app on the list is the foreground app. 14751 adj = ProcessList.FOREGROUND_APP_ADJ; 14752 schedGroup = Process.THREAD_GROUP_DEFAULT; 14753 app.adjType = "top-activity"; 14754 foregroundActivities = true; 14755 interesting = true; 14756 procState = ActivityManager.PROCESS_STATE_TOP; 14757 } else if (app.instrumentationClass != null) { 14758 // Don't want to kill running instrumentation. 14759 adj = ProcessList.FOREGROUND_APP_ADJ; 14760 schedGroup = Process.THREAD_GROUP_DEFAULT; 14761 app.adjType = "instrumentation"; 14762 interesting = true; 14763 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14764 } else if ((queue = isReceivingBroadcast(app)) != null) { 14765 // An app that is currently receiving a broadcast also 14766 // counts as being in the foreground for OOM killer purposes. 14767 // It's placed in a sched group based on the nature of the 14768 // broadcast as reflected by which queue it's active in. 14769 adj = ProcessList.FOREGROUND_APP_ADJ; 14770 schedGroup = (queue == mFgBroadcastQueue) 14771 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14772 app.adjType = "broadcast"; 14773 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14774 } else if (app.executingServices.size() > 0) { 14775 // An app that is currently executing a service callback also 14776 // counts as being in the foreground. 14777 adj = ProcessList.FOREGROUND_APP_ADJ; 14778 schedGroup = app.execServicesFg ? 14779 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14780 app.adjType = "exec-service"; 14781 procState = ActivityManager.PROCESS_STATE_SERVICE; 14782 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14783 } else { 14784 // As far as we know the process is empty. We may change our mind later. 14785 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14786 // At this point we don't actually know the adjustment. Use the cached adj 14787 // value that the caller wants us to. 14788 adj = cachedAdj; 14789 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14790 app.cached = true; 14791 app.empty = true; 14792 app.adjType = "cch-empty"; 14793 } 14794 14795 // Examine all activities if not already foreground. 14796 if (!foregroundActivities && activitiesSize > 0) { 14797 for (int j = 0; j < activitiesSize; j++) { 14798 final ActivityRecord r = app.activities.get(j); 14799 if (r.app != app) { 14800 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14801 + app + "?!?"); 14802 continue; 14803 } 14804 if (r.visible) { 14805 // App has a visible activity; only upgrade adjustment. 14806 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14807 adj = ProcessList.VISIBLE_APP_ADJ; 14808 app.adjType = "visible"; 14809 } 14810 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14811 procState = ActivityManager.PROCESS_STATE_TOP; 14812 } 14813 schedGroup = Process.THREAD_GROUP_DEFAULT; 14814 app.cached = false; 14815 app.empty = false; 14816 foregroundActivities = true; 14817 break; 14818 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14819 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14820 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14821 app.adjType = "pausing"; 14822 } 14823 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14824 procState = ActivityManager.PROCESS_STATE_TOP; 14825 } 14826 schedGroup = Process.THREAD_GROUP_DEFAULT; 14827 app.cached = false; 14828 app.empty = false; 14829 foregroundActivities = true; 14830 } else if (r.state == ActivityState.STOPPING) { 14831 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14832 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14833 app.adjType = "stopping"; 14834 } 14835 // For the process state, we will at this point consider the 14836 // process to be cached. It will be cached either as an activity 14837 // or empty depending on whether the activity is finishing. We do 14838 // this so that we can treat the process as cached for purposes of 14839 // memory trimming (determing current memory level, trim command to 14840 // send to process) since there can be an arbitrary number of stopping 14841 // processes and they should soon all go into the cached state. 14842 if (!r.finishing) { 14843 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14844 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14845 } 14846 } 14847 app.cached = false; 14848 app.empty = false; 14849 foregroundActivities = true; 14850 } else { 14851 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14852 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14853 app.adjType = "cch-act"; 14854 } 14855 } 14856 } 14857 } 14858 14859 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14860 if (app.foregroundServices) { 14861 // The user is aware of this app, so make it visible. 14862 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14863 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14864 app.cached = false; 14865 app.adjType = "fg-service"; 14866 schedGroup = Process.THREAD_GROUP_DEFAULT; 14867 } else if (app.forcingToForeground != null) { 14868 // The user is aware of this app, so make it visible. 14869 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14870 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14871 app.cached = false; 14872 app.adjType = "force-fg"; 14873 app.adjSource = app.forcingToForeground; 14874 schedGroup = Process.THREAD_GROUP_DEFAULT; 14875 } 14876 } 14877 14878 if (app.foregroundServices) { 14879 interesting = true; 14880 } 14881 14882 if (app == mHeavyWeightProcess) { 14883 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14884 // We don't want to kill the current heavy-weight process. 14885 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14886 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14887 app.cached = false; 14888 app.adjType = "heavy"; 14889 } 14890 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14891 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14892 } 14893 } 14894 14895 if (app == mHomeProcess) { 14896 if (adj > ProcessList.HOME_APP_ADJ) { 14897 // This process is hosting what we currently consider to be the 14898 // home app, so we don't want to let it go into the background. 14899 adj = ProcessList.HOME_APP_ADJ; 14900 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14901 app.cached = false; 14902 app.adjType = "home"; 14903 } 14904 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14905 procState = ActivityManager.PROCESS_STATE_HOME; 14906 } 14907 } 14908 14909 if (app == mPreviousProcess && app.activities.size() > 0) { 14910 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14911 // This was the previous process that showed UI to the user. 14912 // We want to try to keep it around more aggressively, to give 14913 // a good experience around switching between two apps. 14914 adj = ProcessList.PREVIOUS_APP_ADJ; 14915 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14916 app.cached = false; 14917 app.adjType = "previous"; 14918 } 14919 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14920 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14921 } 14922 } 14923 14924 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14925 + " reason=" + app.adjType); 14926 14927 // By default, we use the computed adjustment. It may be changed if 14928 // there are applications dependent on our services or providers, but 14929 // this gives us a baseline and makes sure we don't get into an 14930 // infinite recursion. 14931 app.adjSeq = mAdjSeq; 14932 app.curRawAdj = adj; 14933 app.hasStartedServices = false; 14934 14935 if (mBackupTarget != null && app == mBackupTarget.app) { 14936 // If possible we want to avoid killing apps while they're being backed up 14937 if (adj > ProcessList.BACKUP_APP_ADJ) { 14938 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14939 adj = ProcessList.BACKUP_APP_ADJ; 14940 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14941 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14942 } 14943 app.adjType = "backup"; 14944 app.cached = false; 14945 } 14946 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14947 procState = ActivityManager.PROCESS_STATE_BACKUP; 14948 } 14949 } 14950 14951 boolean mayBeTop = false; 14952 14953 for (int is = app.services.size()-1; 14954 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14955 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14956 || procState > ActivityManager.PROCESS_STATE_TOP); 14957 is--) { 14958 ServiceRecord s = app.services.valueAt(is); 14959 if (s.startRequested) { 14960 app.hasStartedServices = true; 14961 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14962 procState = ActivityManager.PROCESS_STATE_SERVICE; 14963 } 14964 if (app.hasShownUi && app != mHomeProcess) { 14965 // If this process has shown some UI, let it immediately 14966 // go to the LRU list because it may be pretty heavy with 14967 // UI stuff. We'll tag it with a label just to help 14968 // debug and understand what is going on. 14969 if (adj > ProcessList.SERVICE_ADJ) { 14970 app.adjType = "cch-started-ui-services"; 14971 } 14972 } else { 14973 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14974 // This service has seen some activity within 14975 // recent memory, so we will keep its process ahead 14976 // of the background processes. 14977 if (adj > ProcessList.SERVICE_ADJ) { 14978 adj = ProcessList.SERVICE_ADJ; 14979 app.adjType = "started-services"; 14980 app.cached = false; 14981 } 14982 } 14983 // If we have let the service slide into the background 14984 // state, still have some text describing what it is doing 14985 // even though the service no longer has an impact. 14986 if (adj > ProcessList.SERVICE_ADJ) { 14987 app.adjType = "cch-started-services"; 14988 } 14989 } 14990 // Don't kill this process because it is doing work; it 14991 // has said it is doing work. 14992 app.keeping = true; 14993 } 14994 for (int conni = s.connections.size()-1; 14995 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14996 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14997 || procState > ActivityManager.PROCESS_STATE_TOP); 14998 conni--) { 14999 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 15000 for (int i = 0; 15001 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 15002 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15003 || procState > ActivityManager.PROCESS_STATE_TOP); 15004 i++) { 15005 // XXX should compute this based on the max of 15006 // all connected clients. 15007 ConnectionRecord cr = clist.get(i); 15008 if (cr.binding.client == app) { 15009 // Binding to ourself is not interesting. 15010 continue; 15011 } 15012 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 15013 ProcessRecord client = cr.binding.client; 15014 int clientAdj = computeOomAdjLocked(client, cachedAdj, 15015 TOP_APP, doingAll, now); 15016 int clientProcState = client.curProcState; 15017 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15018 // If the other app is cached for any reason, for purposes here 15019 // we are going to consider it empty. The specific cached state 15020 // doesn't propagate except under certain conditions. 15021 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15022 } 15023 String adjType = null; 15024 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 15025 // Not doing bind OOM management, so treat 15026 // this guy more like a started service. 15027 if (app.hasShownUi && app != mHomeProcess) { 15028 // If this process has shown some UI, let it immediately 15029 // go to the LRU list because it may be pretty heavy with 15030 // UI stuff. We'll tag it with a label just to help 15031 // debug and understand what is going on. 15032 if (adj > clientAdj) { 15033 adjType = "cch-bound-ui-services"; 15034 } 15035 app.cached = false; 15036 clientAdj = adj; 15037 clientProcState = procState; 15038 } else { 15039 if (now >= (s.lastActivity 15040 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15041 // This service has not seen activity within 15042 // recent memory, so allow it to drop to the 15043 // LRU list if there is no other reason to keep 15044 // it around. We'll also tag it with a label just 15045 // to help debug and undertand what is going on. 15046 if (adj > clientAdj) { 15047 adjType = "cch-bound-services"; 15048 } 15049 clientAdj = adj; 15050 } 15051 } 15052 } 15053 if (adj > clientAdj) { 15054 // If this process has recently shown UI, and 15055 // the process that is binding to it is less 15056 // important than being visible, then we don't 15057 // care about the binding as much as we care 15058 // about letting this process get into the LRU 15059 // list to be killed and restarted if needed for 15060 // memory. 15061 if (app.hasShownUi && app != mHomeProcess 15062 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15063 adjType = "cch-bound-ui-services"; 15064 } else { 15065 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15066 |Context.BIND_IMPORTANT)) != 0) { 15067 adj = clientAdj; 15068 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15069 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15070 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15071 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15072 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15073 adj = clientAdj; 15074 } else { 15075 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15076 adj = ProcessList.VISIBLE_APP_ADJ; 15077 } 15078 } 15079 if (!client.cached) { 15080 app.cached = false; 15081 } 15082 if (client.keeping) { 15083 app.keeping = true; 15084 } 15085 adjType = "service"; 15086 } 15087 } 15088 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15089 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15090 schedGroup = Process.THREAD_GROUP_DEFAULT; 15091 } 15092 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15093 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15094 // Special handling of clients who are in the top state. 15095 // We *may* want to consider this process to be in the 15096 // top state as well, but only if there is not another 15097 // reason for it to be running. Being on the top is a 15098 // special state, meaning you are specifically running 15099 // for the current top app. If the process is already 15100 // running in the background for some other reason, it 15101 // is more important to continue considering it to be 15102 // in the background state. 15103 mayBeTop = true; 15104 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15105 } else { 15106 // Special handling for above-top states (persistent 15107 // processes). These should not bring the current process 15108 // into the top state, since they are not on top. Instead 15109 // give them the best state after that. 15110 clientProcState = 15111 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15112 } 15113 } 15114 } else { 15115 if (clientProcState < 15116 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15117 clientProcState = 15118 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15119 } 15120 } 15121 if (procState > clientProcState) { 15122 procState = clientProcState; 15123 } 15124 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15125 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15126 app.pendingUiClean = true; 15127 } 15128 if (adjType != null) { 15129 app.adjType = adjType; 15130 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15131 .REASON_SERVICE_IN_USE; 15132 app.adjSource = cr.binding.client; 15133 app.adjSourceOom = clientAdj; 15134 app.adjTarget = s.name; 15135 } 15136 } 15137 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15138 app.treatLikeActivity = true; 15139 } 15140 final ActivityRecord a = cr.activity; 15141 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15142 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15143 (a.visible || a.state == ActivityState.RESUMED 15144 || a.state == ActivityState.PAUSING)) { 15145 adj = ProcessList.FOREGROUND_APP_ADJ; 15146 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15147 schedGroup = Process.THREAD_GROUP_DEFAULT; 15148 } 15149 app.cached = false; 15150 app.adjType = "service"; 15151 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15152 .REASON_SERVICE_IN_USE; 15153 app.adjSource = a; 15154 app.adjSourceOom = adj; 15155 app.adjTarget = s.name; 15156 } 15157 } 15158 } 15159 } 15160 } 15161 15162 for (int provi = app.pubProviders.size()-1; 15163 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15164 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15165 || procState > ActivityManager.PROCESS_STATE_TOP); 15166 provi--) { 15167 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15168 for (int i = cpr.connections.size()-1; 15169 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15170 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15171 || procState > ActivityManager.PROCESS_STATE_TOP); 15172 i--) { 15173 ContentProviderConnection conn = cpr.connections.get(i); 15174 ProcessRecord client = conn.client; 15175 if (client == app) { 15176 // Being our own client is not interesting. 15177 continue; 15178 } 15179 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15180 int clientProcState = client.curProcState; 15181 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15182 // If the other app is cached for any reason, for purposes here 15183 // we are going to consider it empty. 15184 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15185 } 15186 if (adj > clientAdj) { 15187 if (app.hasShownUi && app != mHomeProcess 15188 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15189 app.adjType = "cch-ui-provider"; 15190 } else { 15191 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15192 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15193 app.adjType = "provider"; 15194 } 15195 app.cached &= client.cached; 15196 app.keeping |= client.keeping; 15197 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15198 .REASON_PROVIDER_IN_USE; 15199 app.adjSource = client; 15200 app.adjSourceOom = clientAdj; 15201 app.adjTarget = cpr.name; 15202 } 15203 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15204 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15205 // Special handling of clients who are in the top state. 15206 // We *may* want to consider this process to be in the 15207 // top state as well, but only if there is not another 15208 // reason for it to be running. Being on the top is a 15209 // special state, meaning you are specifically running 15210 // for the current top app. If the process is already 15211 // running in the background for some other reason, it 15212 // is more important to continue considering it to be 15213 // in the background state. 15214 mayBeTop = true; 15215 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15216 } else { 15217 // Special handling for above-top states (persistent 15218 // processes). These should not bring the current process 15219 // into the top state, since they are not on top. Instead 15220 // give them the best state after that. 15221 clientProcState = 15222 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15223 } 15224 } 15225 if (procState > clientProcState) { 15226 procState = clientProcState; 15227 } 15228 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15229 schedGroup = Process.THREAD_GROUP_DEFAULT; 15230 } 15231 } 15232 // If the provider has external (non-framework) process 15233 // dependencies, ensure that its adjustment is at least 15234 // FOREGROUND_APP_ADJ. 15235 if (cpr.hasExternalProcessHandles()) { 15236 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15237 adj = ProcessList.FOREGROUND_APP_ADJ; 15238 schedGroup = Process.THREAD_GROUP_DEFAULT; 15239 app.cached = false; 15240 app.keeping = true; 15241 app.adjType = "provider"; 15242 app.adjTarget = cpr.name; 15243 } 15244 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15245 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15246 } 15247 } 15248 } 15249 15250 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15251 // A client of one of our services or providers is in the top state. We 15252 // *may* want to be in the top state, but not if we are already running in 15253 // the background for some other reason. For the decision here, we are going 15254 // to pick out a few specific states that we want to remain in when a client 15255 // is top (states that tend to be longer-term) and otherwise allow it to go 15256 // to the top state. 15257 switch (procState) { 15258 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15259 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15260 case ActivityManager.PROCESS_STATE_SERVICE: 15261 // These all are longer-term states, so pull them up to the top 15262 // of the background states, but not all the way to the top state. 15263 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15264 break; 15265 default: 15266 // Otherwise, top is a better choice, so take it. 15267 procState = ActivityManager.PROCESS_STATE_TOP; 15268 break; 15269 } 15270 } 15271 15272 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15273 if (app.hasClientActivities) { 15274 // This is a cached process, but with client activities. Mark it so. 15275 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15276 app.adjType = "cch-client-act"; 15277 } else if (app.treatLikeActivity) { 15278 // This is a cached process, but somebody wants us to treat it like it has 15279 // an activity, okay! 15280 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15281 app.adjType = "cch-as-act"; 15282 } 15283 } 15284 15285 if (adj == ProcessList.SERVICE_ADJ) { 15286 if (doingAll) { 15287 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15288 mNewNumServiceProcs++; 15289 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15290 if (!app.serviceb) { 15291 // This service isn't far enough down on the LRU list to 15292 // normally be a B service, but if we are low on RAM and it 15293 // is large we want to force it down since we would prefer to 15294 // keep launcher over it. 15295 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15296 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15297 app.serviceHighRam = true; 15298 app.serviceb = true; 15299 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15300 } else { 15301 mNewNumAServiceProcs++; 15302 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15303 } 15304 } else { 15305 app.serviceHighRam = false; 15306 } 15307 } 15308 if (app.serviceb) { 15309 adj = ProcessList.SERVICE_B_ADJ; 15310 } 15311 } 15312 15313 app.curRawAdj = adj; 15314 15315 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15316 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15317 if (adj > app.maxAdj) { 15318 adj = app.maxAdj; 15319 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15320 schedGroup = Process.THREAD_GROUP_DEFAULT; 15321 } 15322 } 15323 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15324 app.keeping = true; 15325 } 15326 15327 // Do final modification to adj. Everything we do between here and applying 15328 // the final setAdj must be done in this function, because we will also use 15329 // it when computing the final cached adj later. Note that we don't need to 15330 // worry about this for max adj above, since max adj will always be used to 15331 // keep it out of the cached vaues. 15332 app.curAdj = app.modifyRawOomAdj(adj); 15333 app.curSchedGroup = schedGroup; 15334 app.curProcState = procState; 15335 app.foregroundActivities = foregroundActivities; 15336 15337 return app.curRawAdj; 15338 } 15339 15340 /** 15341 * Schedule PSS collection of a process. 15342 */ 15343 void requestPssLocked(ProcessRecord proc, int procState) { 15344 if (mPendingPssProcesses.contains(proc)) { 15345 return; 15346 } 15347 if (mPendingPssProcesses.size() == 0) { 15348 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15349 } 15350 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15351 proc.pssProcState = procState; 15352 mPendingPssProcesses.add(proc); 15353 } 15354 15355 /** 15356 * Schedule PSS collection of all processes. 15357 */ 15358 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15359 if (!always) { 15360 if (now < (mLastFullPssTime + 15361 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15362 return; 15363 } 15364 } 15365 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15366 mLastFullPssTime = now; 15367 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15368 mPendingPssProcesses.clear(); 15369 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15370 ProcessRecord app = mLruProcesses.get(i); 15371 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15372 app.pssProcState = app.setProcState; 15373 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15374 isSleeping(), now); 15375 mPendingPssProcesses.add(app); 15376 } 15377 } 15378 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15379 } 15380 15381 /** 15382 * Ask a given process to GC right now. 15383 */ 15384 final void performAppGcLocked(ProcessRecord app) { 15385 try { 15386 app.lastRequestedGc = SystemClock.uptimeMillis(); 15387 if (app.thread != null) { 15388 if (app.reportLowMemory) { 15389 app.reportLowMemory = false; 15390 app.thread.scheduleLowMemory(); 15391 } else { 15392 app.thread.processInBackground(); 15393 } 15394 } 15395 } catch (Exception e) { 15396 // whatever. 15397 } 15398 } 15399 15400 /** 15401 * Returns true if things are idle enough to perform GCs. 15402 */ 15403 private final boolean canGcNowLocked() { 15404 boolean processingBroadcasts = false; 15405 for (BroadcastQueue q : mBroadcastQueues) { 15406 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15407 processingBroadcasts = true; 15408 } 15409 } 15410 return !processingBroadcasts 15411 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15412 } 15413 15414 /** 15415 * Perform GCs on all processes that are waiting for it, but only 15416 * if things are idle. 15417 */ 15418 final void performAppGcsLocked() { 15419 final int N = mProcessesToGc.size(); 15420 if (N <= 0) { 15421 return; 15422 } 15423 if (canGcNowLocked()) { 15424 while (mProcessesToGc.size() > 0) { 15425 ProcessRecord proc = mProcessesToGc.remove(0); 15426 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15427 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15428 <= SystemClock.uptimeMillis()) { 15429 // To avoid spamming the system, we will GC processes one 15430 // at a time, waiting a few seconds between each. 15431 performAppGcLocked(proc); 15432 scheduleAppGcsLocked(); 15433 return; 15434 } else { 15435 // It hasn't been long enough since we last GCed this 15436 // process... put it in the list to wait for its time. 15437 addProcessToGcListLocked(proc); 15438 break; 15439 } 15440 } 15441 } 15442 15443 scheduleAppGcsLocked(); 15444 } 15445 } 15446 15447 /** 15448 * If all looks good, perform GCs on all processes waiting for them. 15449 */ 15450 final void performAppGcsIfAppropriateLocked() { 15451 if (canGcNowLocked()) { 15452 performAppGcsLocked(); 15453 return; 15454 } 15455 // Still not idle, wait some more. 15456 scheduleAppGcsLocked(); 15457 } 15458 15459 /** 15460 * Schedule the execution of all pending app GCs. 15461 */ 15462 final void scheduleAppGcsLocked() { 15463 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15464 15465 if (mProcessesToGc.size() > 0) { 15466 // Schedule a GC for the time to the next process. 15467 ProcessRecord proc = mProcessesToGc.get(0); 15468 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15469 15470 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15471 long now = SystemClock.uptimeMillis(); 15472 if (when < (now+GC_TIMEOUT)) { 15473 when = now + GC_TIMEOUT; 15474 } 15475 mHandler.sendMessageAtTime(msg, when); 15476 } 15477 } 15478 15479 /** 15480 * Add a process to the array of processes waiting to be GCed. Keeps the 15481 * list in sorted order by the last GC time. The process can't already be 15482 * on the list. 15483 */ 15484 final void addProcessToGcListLocked(ProcessRecord proc) { 15485 boolean added = false; 15486 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15487 if (mProcessesToGc.get(i).lastRequestedGc < 15488 proc.lastRequestedGc) { 15489 added = true; 15490 mProcessesToGc.add(i+1, proc); 15491 break; 15492 } 15493 } 15494 if (!added) { 15495 mProcessesToGc.add(0, proc); 15496 } 15497 } 15498 15499 /** 15500 * Set up to ask a process to GC itself. This will either do it 15501 * immediately, or put it on the list of processes to gc the next 15502 * time things are idle. 15503 */ 15504 final void scheduleAppGcLocked(ProcessRecord app) { 15505 long now = SystemClock.uptimeMillis(); 15506 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15507 return; 15508 } 15509 if (!mProcessesToGc.contains(app)) { 15510 addProcessToGcListLocked(app); 15511 scheduleAppGcsLocked(); 15512 } 15513 } 15514 15515 final void checkExcessivePowerUsageLocked(boolean doKills) { 15516 updateCpuStatsNow(); 15517 15518 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15519 boolean doWakeKills = doKills; 15520 boolean doCpuKills = doKills; 15521 if (mLastPowerCheckRealtime == 0) { 15522 doWakeKills = false; 15523 } 15524 if (mLastPowerCheckUptime == 0) { 15525 doCpuKills = false; 15526 } 15527 if (stats.isScreenOn()) { 15528 doWakeKills = false; 15529 } 15530 final long curRealtime = SystemClock.elapsedRealtime(); 15531 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15532 final long curUptime = SystemClock.uptimeMillis(); 15533 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15534 mLastPowerCheckRealtime = curRealtime; 15535 mLastPowerCheckUptime = curUptime; 15536 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15537 doWakeKills = false; 15538 } 15539 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15540 doCpuKills = false; 15541 } 15542 int i = mLruProcesses.size(); 15543 while (i > 0) { 15544 i--; 15545 ProcessRecord app = mLruProcesses.get(i); 15546 if (!app.keeping) { 15547 long wtime; 15548 synchronized (stats) { 15549 wtime = stats.getProcessWakeTime(app.info.uid, 15550 app.pid, curRealtime); 15551 } 15552 long wtimeUsed = wtime - app.lastWakeTime; 15553 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15554 if (DEBUG_POWER) { 15555 StringBuilder sb = new StringBuilder(128); 15556 sb.append("Wake for "); 15557 app.toShortString(sb); 15558 sb.append(": over "); 15559 TimeUtils.formatDuration(realtimeSince, sb); 15560 sb.append(" used "); 15561 TimeUtils.formatDuration(wtimeUsed, sb); 15562 sb.append(" ("); 15563 sb.append((wtimeUsed*100)/realtimeSince); 15564 sb.append("%)"); 15565 Slog.i(TAG, sb.toString()); 15566 sb.setLength(0); 15567 sb.append("CPU for "); 15568 app.toShortString(sb); 15569 sb.append(": over "); 15570 TimeUtils.formatDuration(uptimeSince, sb); 15571 sb.append(" used "); 15572 TimeUtils.formatDuration(cputimeUsed, sb); 15573 sb.append(" ("); 15574 sb.append((cputimeUsed*100)/uptimeSince); 15575 sb.append("%)"); 15576 Slog.i(TAG, sb.toString()); 15577 } 15578 // If a process has held a wake lock for more 15579 // than 50% of the time during this period, 15580 // that sounds bad. Kill! 15581 if (doWakeKills && realtimeSince > 0 15582 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15583 synchronized (stats) { 15584 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15585 realtimeSince, wtimeUsed); 15586 } 15587 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15588 + " during " + realtimeSince); 15589 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15590 } else if (doCpuKills && uptimeSince > 0 15591 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15592 synchronized (stats) { 15593 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15594 uptimeSince, cputimeUsed); 15595 } 15596 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15597 + " during " + uptimeSince); 15598 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15599 } else { 15600 app.lastWakeTime = wtime; 15601 app.lastCpuTime = app.curCpuTime; 15602 } 15603 } 15604 } 15605 } 15606 15607 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15608 ProcessRecord TOP_APP, boolean doingAll, long now) { 15609 boolean success = true; 15610 15611 if (app.curRawAdj != app.setRawAdj) { 15612 if (wasKeeping && !app.keeping) { 15613 // This app is no longer something we want to keep. Note 15614 // its current wake lock time to later know to kill it if 15615 // it is not behaving well. 15616 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15617 synchronized (stats) { 15618 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15619 app.pid, SystemClock.elapsedRealtime()); 15620 } 15621 app.lastCpuTime = app.curCpuTime; 15622 } 15623 15624 app.setRawAdj = app.curRawAdj; 15625 } 15626 15627 int changes = 0; 15628 15629 if (app.curAdj != app.setAdj) { 15630 ProcessList.setOomAdj(app.pid, app.curAdj); 15631 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15632 TAG, "Set " + app.pid + " " + app.processName + 15633 " adj " + app.curAdj + ": " + app.adjType); 15634 app.setAdj = app.curAdj; 15635 } 15636 15637 if (app.setSchedGroup != app.curSchedGroup) { 15638 app.setSchedGroup = app.curSchedGroup; 15639 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15640 "Setting process group of " + app.processName 15641 + " to " + app.curSchedGroup); 15642 if (app.waitingToKill != null && 15643 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15644 killUnneededProcessLocked(app, app.waitingToKill); 15645 success = false; 15646 } else { 15647 if (true) { 15648 long oldId = Binder.clearCallingIdentity(); 15649 try { 15650 Process.setProcessGroup(app.pid, app.curSchedGroup); 15651 } catch (Exception e) { 15652 Slog.w(TAG, "Failed setting process group of " + app.pid 15653 + " to " + app.curSchedGroup); 15654 e.printStackTrace(); 15655 } finally { 15656 Binder.restoreCallingIdentity(oldId); 15657 } 15658 } else { 15659 if (app.thread != null) { 15660 try { 15661 app.thread.setSchedulingGroup(app.curSchedGroup); 15662 } catch (RemoteException e) { 15663 } 15664 } 15665 } 15666 Process.setSwappiness(app.pid, 15667 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15668 } 15669 } 15670 if (app.repForegroundActivities != app.foregroundActivities) { 15671 app.repForegroundActivities = app.foregroundActivities; 15672 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15673 } 15674 if (app.repProcState != app.curProcState) { 15675 app.repProcState = app.curProcState; 15676 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15677 if (app.thread != null) { 15678 try { 15679 if (false) { 15680 //RuntimeException h = new RuntimeException("here"); 15681 Slog.i(TAG, "Sending new process state " + app.repProcState 15682 + " to " + app /*, h*/); 15683 } 15684 app.thread.setProcessState(app.repProcState); 15685 } catch (RemoteException e) { 15686 } 15687 } 15688 } 15689 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15690 app.setProcState)) { 15691 app.lastStateTime = now; 15692 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15693 isSleeping(), now); 15694 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15695 + ProcessList.makeProcStateString(app.setProcState) + " to " 15696 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15697 + (app.nextPssTime-now) + ": " + app); 15698 } else { 15699 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15700 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15701 requestPssLocked(app, app.setProcState); 15702 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15703 isSleeping(), now); 15704 } else if (false && DEBUG_PSS) { 15705 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15706 } 15707 } 15708 if (app.setProcState != app.curProcState) { 15709 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15710 "Proc state change of " + app.processName 15711 + " to " + app.curProcState); 15712 app.setProcState = app.curProcState; 15713 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15714 app.notCachedSinceIdle = false; 15715 } 15716 if (!doingAll) { 15717 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15718 } else { 15719 app.procStateChanged = true; 15720 } 15721 } 15722 15723 if (changes != 0) { 15724 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15725 int i = mPendingProcessChanges.size()-1; 15726 ProcessChangeItem item = null; 15727 while (i >= 0) { 15728 item = mPendingProcessChanges.get(i); 15729 if (item.pid == app.pid) { 15730 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15731 break; 15732 } 15733 i--; 15734 } 15735 if (i < 0) { 15736 // No existing item in pending changes; need a new one. 15737 final int NA = mAvailProcessChanges.size(); 15738 if (NA > 0) { 15739 item = mAvailProcessChanges.remove(NA-1); 15740 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15741 } else { 15742 item = new ProcessChangeItem(); 15743 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15744 } 15745 item.changes = 0; 15746 item.pid = app.pid; 15747 item.uid = app.info.uid; 15748 if (mPendingProcessChanges.size() == 0) { 15749 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15750 "*** Enqueueing dispatch processes changed!"); 15751 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15752 } 15753 mPendingProcessChanges.add(item); 15754 } 15755 item.changes |= changes; 15756 item.processState = app.repProcState; 15757 item.foregroundActivities = app.repForegroundActivities; 15758 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15759 + Integer.toHexString(System.identityHashCode(item)) 15760 + " " + app.toShortString() + ": changes=" + item.changes 15761 + " procState=" + item.processState 15762 + " foreground=" + item.foregroundActivities 15763 + " type=" + app.adjType + " source=" + app.adjSource 15764 + " target=" + app.adjTarget); 15765 } 15766 15767 return success; 15768 } 15769 15770 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15771 if (proc.thread != null && proc.baseProcessTracker != null) { 15772 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15773 } 15774 } 15775 15776 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15777 ProcessRecord TOP_APP, boolean doingAll, long now) { 15778 if (app.thread == null) { 15779 return false; 15780 } 15781 15782 final boolean wasKeeping = app.keeping; 15783 15784 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15785 15786 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 15787 } 15788 15789 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15790 boolean oomAdj) { 15791 if (isForeground != proc.foregroundServices) { 15792 proc.foregroundServices = isForeground; 15793 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15794 proc.info.uid); 15795 if (isForeground) { 15796 if (curProcs == null) { 15797 curProcs = new ArrayList<ProcessRecord>(); 15798 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15799 } 15800 if (!curProcs.contains(proc)) { 15801 curProcs.add(proc); 15802 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15803 proc.info.packageName, proc.info.uid); 15804 } 15805 } else { 15806 if (curProcs != null) { 15807 if (curProcs.remove(proc)) { 15808 mBatteryStatsService.noteEvent( 15809 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15810 proc.info.packageName, proc.info.uid); 15811 if (curProcs.size() <= 0) { 15812 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15813 } 15814 } 15815 } 15816 } 15817 if (oomAdj) { 15818 updateOomAdjLocked(); 15819 } 15820 } 15821 } 15822 15823 private final ActivityRecord resumedAppLocked() { 15824 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15825 String pkg; 15826 int uid; 15827 if (act != null && !act.sleeping) { 15828 pkg = act.packageName; 15829 uid = act.info.applicationInfo.uid; 15830 } else { 15831 pkg = null; 15832 uid = -1; 15833 } 15834 // Has the UID or resumed package name changed? 15835 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15836 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15837 if (mCurResumedPackage != null) { 15838 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15839 mCurResumedPackage, mCurResumedUid); 15840 } 15841 mCurResumedPackage = pkg; 15842 mCurResumedUid = uid; 15843 if (mCurResumedPackage != null) { 15844 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15845 mCurResumedPackage, mCurResumedUid); 15846 } 15847 } 15848 return act; 15849 } 15850 15851 final boolean updateOomAdjLocked(ProcessRecord app) { 15852 final ActivityRecord TOP_ACT = resumedAppLocked(); 15853 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15854 final boolean wasCached = app.cached; 15855 15856 mAdjSeq++; 15857 15858 // This is the desired cached adjusment we want to tell it to use. 15859 // If our app is currently cached, we know it, and that is it. Otherwise, 15860 // we don't know it yet, and it needs to now be cached we will then 15861 // need to do a complete oom adj. 15862 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15863 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15864 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 15865 SystemClock.uptimeMillis()); 15866 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15867 // Changed to/from cached state, so apps after it in the LRU 15868 // list may also be changed. 15869 updateOomAdjLocked(); 15870 } 15871 return success; 15872 } 15873 15874 final void updateOomAdjLocked() { 15875 final ActivityRecord TOP_ACT = resumedAppLocked(); 15876 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15877 final long now = SystemClock.uptimeMillis(); 15878 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15879 final int N = mLruProcesses.size(); 15880 15881 if (false) { 15882 RuntimeException e = new RuntimeException(); 15883 e.fillInStackTrace(); 15884 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15885 } 15886 15887 mAdjSeq++; 15888 mNewNumServiceProcs = 0; 15889 mNewNumAServiceProcs = 0; 15890 15891 final int emptyProcessLimit; 15892 final int cachedProcessLimit; 15893 if (mProcessLimit <= 0) { 15894 emptyProcessLimit = cachedProcessLimit = 0; 15895 } else if (mProcessLimit == 1) { 15896 emptyProcessLimit = 1; 15897 cachedProcessLimit = 0; 15898 } else { 15899 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15900 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15901 } 15902 15903 // Let's determine how many processes we have running vs. 15904 // how many slots we have for background processes; we may want 15905 // to put multiple processes in a slot of there are enough of 15906 // them. 15907 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15908 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15909 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15910 if (numEmptyProcs > cachedProcessLimit) { 15911 // If there are more empty processes than our limit on cached 15912 // processes, then use the cached process limit for the factor. 15913 // This ensures that the really old empty processes get pushed 15914 // down to the bottom, so if we are running low on memory we will 15915 // have a better chance at keeping around more cached processes 15916 // instead of a gazillion empty processes. 15917 numEmptyProcs = cachedProcessLimit; 15918 } 15919 int emptyFactor = numEmptyProcs/numSlots; 15920 if (emptyFactor < 1) emptyFactor = 1; 15921 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15922 if (cachedFactor < 1) cachedFactor = 1; 15923 int stepCached = 0; 15924 int stepEmpty = 0; 15925 int numCached = 0; 15926 int numEmpty = 0; 15927 int numTrimming = 0; 15928 15929 mNumNonCachedProcs = 0; 15930 mNumCachedHiddenProcs = 0; 15931 15932 // First update the OOM adjustment for each of the 15933 // application processes based on their current state. 15934 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15935 int nextCachedAdj = curCachedAdj+1; 15936 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15937 int nextEmptyAdj = curEmptyAdj+2; 15938 for (int i=N-1; i>=0; i--) { 15939 ProcessRecord app = mLruProcesses.get(i); 15940 if (!app.killedByAm && app.thread != null) { 15941 app.procStateChanged = false; 15942 final boolean wasKeeping = app.keeping; 15943 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15944 15945 // If we haven't yet assigned the final cached adj 15946 // to the process, do that now. 15947 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15948 switch (app.curProcState) { 15949 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15950 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15951 // This process is a cached process holding activities... 15952 // assign it the next cached value for that type, and then 15953 // step that cached level. 15954 app.curRawAdj = curCachedAdj; 15955 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15956 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15957 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15958 + ")"); 15959 if (curCachedAdj != nextCachedAdj) { 15960 stepCached++; 15961 if (stepCached >= cachedFactor) { 15962 stepCached = 0; 15963 curCachedAdj = nextCachedAdj; 15964 nextCachedAdj += 2; 15965 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15966 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15967 } 15968 } 15969 } 15970 break; 15971 default: 15972 // For everything else, assign next empty cached process 15973 // level and bump that up. Note that this means that 15974 // long-running services that have dropped down to the 15975 // cached level will be treated as empty (since their process 15976 // state is still as a service), which is what we want. 15977 app.curRawAdj = curEmptyAdj; 15978 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15979 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15980 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15981 + ")"); 15982 if (curEmptyAdj != nextEmptyAdj) { 15983 stepEmpty++; 15984 if (stepEmpty >= emptyFactor) { 15985 stepEmpty = 0; 15986 curEmptyAdj = nextEmptyAdj; 15987 nextEmptyAdj += 2; 15988 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15989 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15990 } 15991 } 15992 } 15993 break; 15994 } 15995 } 15996 15997 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 15998 15999 // Count the number of process types. 16000 switch (app.curProcState) { 16001 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16002 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16003 mNumCachedHiddenProcs++; 16004 numCached++; 16005 if (numCached > cachedProcessLimit) { 16006 killUnneededProcessLocked(app, "cached #" + numCached); 16007 } 16008 break; 16009 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 16010 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 16011 && app.lastActivityTime < oldTime) { 16012 killUnneededProcessLocked(app, "empty for " 16013 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 16014 / 1000) + "s"); 16015 } else { 16016 numEmpty++; 16017 if (numEmpty > emptyProcessLimit) { 16018 killUnneededProcessLocked(app, "empty #" + numEmpty); 16019 } 16020 } 16021 break; 16022 default: 16023 mNumNonCachedProcs++; 16024 break; 16025 } 16026 16027 if (app.isolated && app.services.size() <= 0) { 16028 // If this is an isolated process, and there are no 16029 // services running in it, then the process is no longer 16030 // needed. We agressively kill these because we can by 16031 // definition not re-use the same process again, and it is 16032 // good to avoid having whatever code was running in them 16033 // left sitting around after no longer needed. 16034 killUnneededProcessLocked(app, "isolated not needed"); 16035 } 16036 16037 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16038 && !app.killedByAm) { 16039 numTrimming++; 16040 } 16041 } 16042 } 16043 16044 mNumServiceProcs = mNewNumServiceProcs; 16045 16046 // Now determine the memory trimming level of background processes. 16047 // Unfortunately we need to start at the back of the list to do this 16048 // properly. We only do this if the number of background apps we 16049 // are managing to keep around is less than half the maximum we desire; 16050 // if we are keeping a good number around, we'll let them use whatever 16051 // memory they want. 16052 final int numCachedAndEmpty = numCached + numEmpty; 16053 int memFactor; 16054 if (numCached <= ProcessList.TRIM_CACHED_APPS 16055 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16056 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16057 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16058 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16059 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16060 } else { 16061 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16062 } 16063 } else { 16064 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16065 } 16066 // We always allow the memory level to go up (better). We only allow it to go 16067 // down if we are in a state where that is allowed, *and* the total number of processes 16068 // has gone down since last time. 16069 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16070 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16071 + " last=" + mLastNumProcesses); 16072 if (memFactor > mLastMemoryLevel) { 16073 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16074 memFactor = mLastMemoryLevel; 16075 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16076 } 16077 } 16078 mLastMemoryLevel = memFactor; 16079 mLastNumProcesses = mLruProcesses.size(); 16080 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16081 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16082 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16083 if (mLowRamStartTime == 0) { 16084 mLowRamStartTime = now; 16085 } 16086 int step = 0; 16087 int fgTrimLevel; 16088 switch (memFactor) { 16089 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16090 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16091 break; 16092 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16093 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16094 break; 16095 default: 16096 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16097 break; 16098 } 16099 int factor = numTrimming/3; 16100 int minFactor = 2; 16101 if (mHomeProcess != null) minFactor++; 16102 if (mPreviousProcess != null) minFactor++; 16103 if (factor < minFactor) factor = minFactor; 16104 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16105 for (int i=N-1; i>=0; i--) { 16106 ProcessRecord app = mLruProcesses.get(i); 16107 if (allChanged || app.procStateChanged) { 16108 setProcessTrackerState(app, trackerMemFactor, now); 16109 app.procStateChanged = false; 16110 } 16111 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16112 && !app.killedByAm) { 16113 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16114 try { 16115 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16116 "Trimming memory of " + app.processName 16117 + " to " + curLevel); 16118 app.thread.scheduleTrimMemory(curLevel); 16119 } catch (RemoteException e) { 16120 } 16121 if (false) { 16122 // For now we won't do this; our memory trimming seems 16123 // to be good enough at this point that destroying 16124 // activities causes more harm than good. 16125 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16126 && app != mHomeProcess && app != mPreviousProcess) { 16127 // Need to do this on its own message because the stack may not 16128 // be in a consistent state at this point. 16129 // For these apps we will also finish their activities 16130 // to help them free memory. 16131 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16132 } 16133 } 16134 } 16135 app.trimMemoryLevel = curLevel; 16136 step++; 16137 if (step >= factor) { 16138 step = 0; 16139 switch (curLevel) { 16140 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16141 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16142 break; 16143 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16144 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16145 break; 16146 } 16147 } 16148 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16149 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16150 && app.thread != null) { 16151 try { 16152 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16153 "Trimming memory of heavy-weight " + app.processName 16154 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16155 app.thread.scheduleTrimMemory( 16156 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16157 } catch (RemoteException e) { 16158 } 16159 } 16160 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16161 } else { 16162 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16163 || app.systemNoUi) && app.pendingUiClean) { 16164 // If this application is now in the background and it 16165 // had done UI, then give it the special trim level to 16166 // have it free UI resources. 16167 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16168 if (app.trimMemoryLevel < level && app.thread != null) { 16169 try { 16170 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16171 "Trimming memory of bg-ui " + app.processName 16172 + " to " + level); 16173 app.thread.scheduleTrimMemory(level); 16174 } catch (RemoteException e) { 16175 } 16176 } 16177 app.pendingUiClean = false; 16178 } 16179 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16180 try { 16181 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16182 "Trimming memory of fg " + app.processName 16183 + " to " + fgTrimLevel); 16184 app.thread.scheduleTrimMemory(fgTrimLevel); 16185 } catch (RemoteException e) { 16186 } 16187 } 16188 app.trimMemoryLevel = fgTrimLevel; 16189 } 16190 } 16191 } else { 16192 if (mLowRamStartTime != 0) { 16193 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16194 mLowRamStartTime = 0; 16195 } 16196 for (int i=N-1; i>=0; i--) { 16197 ProcessRecord app = mLruProcesses.get(i); 16198 if (allChanged || app.procStateChanged) { 16199 setProcessTrackerState(app, trackerMemFactor, now); 16200 app.procStateChanged = false; 16201 } 16202 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16203 || app.systemNoUi) && app.pendingUiClean) { 16204 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16205 && app.thread != null) { 16206 try { 16207 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16208 "Trimming memory of ui hidden " + app.processName 16209 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16210 app.thread.scheduleTrimMemory( 16211 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16212 } catch (RemoteException e) { 16213 } 16214 } 16215 app.pendingUiClean = false; 16216 } 16217 app.trimMemoryLevel = 0; 16218 } 16219 } 16220 16221 if (mAlwaysFinishActivities) { 16222 // Need to do this on its own message because the stack may not 16223 // be in a consistent state at this point. 16224 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16225 } 16226 16227 if (allChanged) { 16228 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16229 } 16230 16231 if (mProcessStats.shouldWriteNowLocked(now)) { 16232 mHandler.post(new Runnable() { 16233 @Override public void run() { 16234 synchronized (ActivityManagerService.this) { 16235 mProcessStats.writeStateAsyncLocked(); 16236 } 16237 } 16238 }); 16239 } 16240 16241 if (DEBUG_OOM_ADJ) { 16242 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16243 } 16244 } 16245 16246 final void trimApplications() { 16247 synchronized (this) { 16248 int i; 16249 16250 // First remove any unused application processes whose package 16251 // has been removed. 16252 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16253 final ProcessRecord app = mRemovedProcesses.get(i); 16254 if (app.activities.size() == 0 16255 && app.curReceiver == null && app.services.size() == 0) { 16256 Slog.i( 16257 TAG, "Exiting empty application process " 16258 + app.processName + " (" 16259 + (app.thread != null ? app.thread.asBinder() : null) 16260 + ")\n"); 16261 if (app.pid > 0 && app.pid != MY_PID) { 16262 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16263 app.processName, app.setAdj, "empty"); 16264 app.killedByAm = true; 16265 Process.killProcessQuiet(app.pid); 16266 } else { 16267 try { 16268 app.thread.scheduleExit(); 16269 } catch (Exception e) { 16270 // Ignore exceptions. 16271 } 16272 } 16273 cleanUpApplicationRecordLocked(app, false, true, -1); 16274 mRemovedProcesses.remove(i); 16275 16276 if (app.persistent) { 16277 if (app.persistent) { 16278 addAppLocked(app.info, false); 16279 } 16280 } 16281 } 16282 } 16283 16284 // Now update the oom adj for all processes. 16285 updateOomAdjLocked(); 16286 } 16287 } 16288 16289 /** This method sends the specified signal to each of the persistent apps */ 16290 public void signalPersistentProcesses(int sig) throws RemoteException { 16291 if (sig != Process.SIGNAL_USR1) { 16292 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16293 } 16294 16295 synchronized (this) { 16296 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16297 != PackageManager.PERMISSION_GRANTED) { 16298 throw new SecurityException("Requires permission " 16299 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16300 } 16301 16302 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16303 ProcessRecord r = mLruProcesses.get(i); 16304 if (r.thread != null && r.persistent) { 16305 Process.sendSignal(r.pid, sig); 16306 } 16307 } 16308 } 16309 } 16310 16311 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16312 if (proc == null || proc == mProfileProc) { 16313 proc = mProfileProc; 16314 path = mProfileFile; 16315 profileType = mProfileType; 16316 clearProfilerLocked(); 16317 } 16318 if (proc == null) { 16319 return; 16320 } 16321 try { 16322 proc.thread.profilerControl(false, path, null, profileType); 16323 } catch (RemoteException e) { 16324 throw new IllegalStateException("Process disappeared"); 16325 } 16326 } 16327 16328 private void clearProfilerLocked() { 16329 if (mProfileFd != null) { 16330 try { 16331 mProfileFd.close(); 16332 } catch (IOException e) { 16333 } 16334 } 16335 mProfileApp = null; 16336 mProfileProc = null; 16337 mProfileFile = null; 16338 mProfileType = 0; 16339 mAutoStopProfiler = false; 16340 } 16341 16342 public boolean profileControl(String process, int userId, boolean start, 16343 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16344 16345 try { 16346 synchronized (this) { 16347 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16348 // its own permission. 16349 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16350 != PackageManager.PERMISSION_GRANTED) { 16351 throw new SecurityException("Requires permission " 16352 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16353 } 16354 16355 if (start && fd == null) { 16356 throw new IllegalArgumentException("null fd"); 16357 } 16358 16359 ProcessRecord proc = null; 16360 if (process != null) { 16361 proc = findProcessLocked(process, userId, "profileControl"); 16362 } 16363 16364 if (start && (proc == null || proc.thread == null)) { 16365 throw new IllegalArgumentException("Unknown process: " + process); 16366 } 16367 16368 if (start) { 16369 stopProfilerLocked(null, null, 0); 16370 setProfileApp(proc.info, proc.processName, path, fd, false); 16371 mProfileProc = proc; 16372 mProfileType = profileType; 16373 try { 16374 fd = fd.dup(); 16375 } catch (IOException e) { 16376 fd = null; 16377 } 16378 proc.thread.profilerControl(start, path, fd, profileType); 16379 fd = null; 16380 mProfileFd = null; 16381 } else { 16382 stopProfilerLocked(proc, path, profileType); 16383 if (fd != null) { 16384 try { 16385 fd.close(); 16386 } catch (IOException e) { 16387 } 16388 } 16389 } 16390 16391 return true; 16392 } 16393 } catch (RemoteException e) { 16394 throw new IllegalStateException("Process disappeared"); 16395 } finally { 16396 if (fd != null) { 16397 try { 16398 fd.close(); 16399 } catch (IOException e) { 16400 } 16401 } 16402 } 16403 } 16404 16405 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16406 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16407 userId, true, true, callName, null); 16408 ProcessRecord proc = null; 16409 try { 16410 int pid = Integer.parseInt(process); 16411 synchronized (mPidsSelfLocked) { 16412 proc = mPidsSelfLocked.get(pid); 16413 } 16414 } catch (NumberFormatException e) { 16415 } 16416 16417 if (proc == null) { 16418 ArrayMap<String, SparseArray<ProcessRecord>> all 16419 = mProcessNames.getMap(); 16420 SparseArray<ProcessRecord> procs = all.get(process); 16421 if (procs != null && procs.size() > 0) { 16422 proc = procs.valueAt(0); 16423 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16424 for (int i=1; i<procs.size(); i++) { 16425 ProcessRecord thisProc = procs.valueAt(i); 16426 if (thisProc.userId == userId) { 16427 proc = thisProc; 16428 break; 16429 } 16430 } 16431 } 16432 } 16433 } 16434 16435 return proc; 16436 } 16437 16438 public boolean dumpHeap(String process, int userId, boolean managed, 16439 String path, ParcelFileDescriptor fd) throws RemoteException { 16440 16441 try { 16442 synchronized (this) { 16443 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16444 // its own permission (same as profileControl). 16445 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16446 != PackageManager.PERMISSION_GRANTED) { 16447 throw new SecurityException("Requires permission " 16448 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16449 } 16450 16451 if (fd == null) { 16452 throw new IllegalArgumentException("null fd"); 16453 } 16454 16455 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16456 if (proc == null || proc.thread == null) { 16457 throw new IllegalArgumentException("Unknown process: " + process); 16458 } 16459 16460 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16461 if (!isDebuggable) { 16462 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16463 throw new SecurityException("Process not debuggable: " + proc); 16464 } 16465 } 16466 16467 proc.thread.dumpHeap(managed, path, fd); 16468 fd = null; 16469 return true; 16470 } 16471 } catch (RemoteException e) { 16472 throw new IllegalStateException("Process disappeared"); 16473 } finally { 16474 if (fd != null) { 16475 try { 16476 fd.close(); 16477 } catch (IOException e) { 16478 } 16479 } 16480 } 16481 } 16482 16483 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16484 public void monitor() { 16485 synchronized (this) { } 16486 } 16487 16488 void onCoreSettingsChange(Bundle settings) { 16489 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16490 ProcessRecord processRecord = mLruProcesses.get(i); 16491 try { 16492 if (processRecord.thread != null) { 16493 processRecord.thread.setCoreSettings(settings); 16494 } 16495 } catch (RemoteException re) { 16496 /* ignore */ 16497 } 16498 } 16499 } 16500 16501 // Multi-user methods 16502 16503 /** 16504 * Start user, if its not already running, but don't bring it to foreground. 16505 */ 16506 @Override 16507 public boolean startUserInBackground(final int userId) { 16508 return startUser(userId, /* foreground */ false); 16509 } 16510 16511 /** 16512 * Refreshes the list of users related to the current user when either a 16513 * user switch happens or when a new related user is started in the 16514 * background. 16515 */ 16516 private void updateCurrentProfileIdsLocked() { 16517 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16518 mCurrentUserId, false /* enabledOnly */); 16519 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16520 for (int i = 0; i < currentProfileIds.length; i++) { 16521 currentProfileIds[i] = profiles.get(i).id; 16522 } 16523 mCurrentProfileIds = currentProfileIds; 16524 } 16525 16526 private Set getProfileIdsLocked(int userId) { 16527 Set userIds = new HashSet<Integer>(); 16528 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16529 userId, false /* enabledOnly */); 16530 for (UserInfo user : profiles) { 16531 userIds.add(Integer.valueOf(user.id)); 16532 } 16533 return userIds; 16534 } 16535 16536 @Override 16537 public boolean switchUser(final int userId) { 16538 return startUser(userId, /* foregound */ true); 16539 } 16540 16541 private boolean startUser(final int userId, boolean foreground) { 16542 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16543 != PackageManager.PERMISSION_GRANTED) { 16544 String msg = "Permission Denial: switchUser() from pid=" 16545 + Binder.getCallingPid() 16546 + ", uid=" + Binder.getCallingUid() 16547 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16548 Slog.w(TAG, msg); 16549 throw new SecurityException(msg); 16550 } 16551 16552 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16553 16554 final long ident = Binder.clearCallingIdentity(); 16555 try { 16556 synchronized (this) { 16557 final int oldUserId = mCurrentUserId; 16558 if (oldUserId == userId) { 16559 return true; 16560 } 16561 16562 mStackSupervisor.setLockTaskModeLocked(null); 16563 16564 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16565 if (userInfo == null) { 16566 Slog.w(TAG, "No user info for user #" + userId); 16567 return false; 16568 } 16569 16570 if (foreground) { 16571 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16572 R.anim.screen_user_enter); 16573 } 16574 16575 boolean needStart = false; 16576 16577 // If the user we are switching to is not currently started, then 16578 // we need to start it now. 16579 if (mStartedUsers.get(userId) == null) { 16580 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16581 updateStartedUserArrayLocked(); 16582 needStart = true; 16583 } 16584 16585 final Integer userIdInt = Integer.valueOf(userId); 16586 mUserLru.remove(userIdInt); 16587 mUserLru.add(userIdInt); 16588 16589 if (foreground) { 16590 mCurrentUserId = userId; 16591 updateCurrentProfileIdsLocked(); 16592 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16593 // Once the internal notion of the active user has switched, we lock the device 16594 // with the option to show the user switcher on the keyguard. 16595 mWindowManager.lockNow(null); 16596 } else { 16597 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16598 updateCurrentProfileIdsLocked(); 16599 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16600 mUserLru.remove(currentUserIdInt); 16601 mUserLru.add(currentUserIdInt); 16602 } 16603 16604 final UserStartedState uss = mStartedUsers.get(userId); 16605 16606 // Make sure user is in the started state. If it is currently 16607 // stopping, we need to knock that off. 16608 if (uss.mState == UserStartedState.STATE_STOPPING) { 16609 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16610 // so we can just fairly silently bring the user back from 16611 // the almost-dead. 16612 uss.mState = UserStartedState.STATE_RUNNING; 16613 updateStartedUserArrayLocked(); 16614 needStart = true; 16615 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16616 // This means ACTION_SHUTDOWN has been sent, so we will 16617 // need to treat this as a new boot of the user. 16618 uss.mState = UserStartedState.STATE_BOOTING; 16619 updateStartedUserArrayLocked(); 16620 needStart = true; 16621 } 16622 16623 if (uss.mState == UserStartedState.STATE_BOOTING) { 16624 // Booting up a new user, need to tell system services about it. 16625 // Note that this is on the same handler as scheduling of broadcasts, 16626 // which is important because it needs to go first. 16627 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16628 } 16629 16630 if (foreground) { 16631 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16632 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16633 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16634 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16635 oldUserId, userId, uss)); 16636 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16637 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16638 } 16639 16640 if (needStart) { 16641 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16642 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16643 | Intent.FLAG_RECEIVER_FOREGROUND); 16644 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16645 broadcastIntentLocked(null, null, intent, 16646 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16647 false, false, MY_PID, Process.SYSTEM_UID, userId); 16648 } 16649 16650 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16651 if (userId != UserHandle.USER_OWNER) { 16652 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16653 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16654 broadcastIntentLocked(null, null, intent, null, 16655 new IIntentReceiver.Stub() { 16656 public void performReceive(Intent intent, int resultCode, 16657 String data, Bundle extras, boolean ordered, 16658 boolean sticky, int sendingUser) { 16659 userInitialized(uss, userId); 16660 } 16661 }, 0, null, null, null, AppOpsManager.OP_NONE, 16662 true, false, MY_PID, Process.SYSTEM_UID, 16663 userId); 16664 uss.initializing = true; 16665 } else { 16666 getUserManagerLocked().makeInitialized(userInfo.id); 16667 } 16668 } 16669 16670 if (foreground) { 16671 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16672 if (homeInFront) { 16673 startHomeActivityLocked(userId); 16674 } else { 16675 mStackSupervisor.resumeTopActivitiesLocked(); 16676 } 16677 EventLogTags.writeAmSwitchUser(userId); 16678 getUserManagerLocked().userForeground(userId); 16679 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16680 } else { 16681 mStackSupervisor.startBackgroundUserLocked(userId, uss); 16682 } 16683 16684 if (needStart) { 16685 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16686 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16687 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16688 broadcastIntentLocked(null, null, intent, 16689 null, new IIntentReceiver.Stub() { 16690 @Override 16691 public void performReceive(Intent intent, int resultCode, String data, 16692 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16693 throws RemoteException { 16694 } 16695 }, 0, null, null, 16696 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16697 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16698 } 16699 } 16700 } finally { 16701 Binder.restoreCallingIdentity(ident); 16702 } 16703 16704 return true; 16705 } 16706 16707 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16708 long ident = Binder.clearCallingIdentity(); 16709 try { 16710 Intent intent; 16711 if (oldUserId >= 0) { 16712 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16713 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16714 | Intent.FLAG_RECEIVER_FOREGROUND); 16715 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16716 broadcastIntentLocked(null, null, intent, 16717 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16718 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16719 } 16720 if (newUserId >= 0) { 16721 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16722 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16723 | Intent.FLAG_RECEIVER_FOREGROUND); 16724 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16725 broadcastIntentLocked(null, null, intent, 16726 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16727 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16728 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16729 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16730 | Intent.FLAG_RECEIVER_FOREGROUND); 16731 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16732 broadcastIntentLocked(null, null, intent, 16733 null, null, 0, null, null, 16734 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16735 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16736 } 16737 } finally { 16738 Binder.restoreCallingIdentity(ident); 16739 } 16740 } 16741 16742 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16743 final int newUserId) { 16744 final int N = mUserSwitchObservers.beginBroadcast(); 16745 if (N > 0) { 16746 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16747 int mCount = 0; 16748 @Override 16749 public void sendResult(Bundle data) throws RemoteException { 16750 synchronized (ActivityManagerService.this) { 16751 if (mCurUserSwitchCallback == this) { 16752 mCount++; 16753 if (mCount == N) { 16754 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16755 } 16756 } 16757 } 16758 } 16759 }; 16760 synchronized (this) { 16761 uss.switching = true; 16762 mCurUserSwitchCallback = callback; 16763 } 16764 for (int i=0; i<N; i++) { 16765 try { 16766 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16767 newUserId, callback); 16768 } catch (RemoteException e) { 16769 } 16770 } 16771 } else { 16772 synchronized (this) { 16773 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16774 } 16775 } 16776 mUserSwitchObservers.finishBroadcast(); 16777 } 16778 16779 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16780 synchronized (this) { 16781 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16782 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16783 } 16784 } 16785 16786 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16787 mCurUserSwitchCallback = null; 16788 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16789 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16790 oldUserId, newUserId, uss)); 16791 } 16792 16793 void userInitialized(UserStartedState uss, int newUserId) { 16794 completeSwitchAndInitalize(uss, newUserId, true, false); 16795 } 16796 16797 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16798 completeSwitchAndInitalize(uss, newUserId, false, true); 16799 } 16800 16801 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16802 boolean clearInitializing, boolean clearSwitching) { 16803 boolean unfrozen = false; 16804 synchronized (this) { 16805 if (clearInitializing) { 16806 uss.initializing = false; 16807 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16808 } 16809 if (clearSwitching) { 16810 uss.switching = false; 16811 } 16812 if (!uss.switching && !uss.initializing) { 16813 mWindowManager.stopFreezingScreen(); 16814 unfrozen = true; 16815 } 16816 } 16817 if (unfrozen) { 16818 final int N = mUserSwitchObservers.beginBroadcast(); 16819 for (int i=0; i<N; i++) { 16820 try { 16821 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16822 } catch (RemoteException e) { 16823 } 16824 } 16825 mUserSwitchObservers.finishBroadcast(); 16826 } 16827 } 16828 16829 void scheduleStartProfilesLocked() { 16830 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16831 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16832 DateUtils.SECOND_IN_MILLIS); 16833 } 16834 } 16835 16836 void startProfilesLocked() { 16837 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16838 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16839 mCurrentUserId, false /* enabledOnly */); 16840 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16841 for (UserInfo user : profiles) { 16842 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16843 && user.id != mCurrentUserId) { 16844 toStart.add(user); 16845 } 16846 } 16847 final int n = toStart.size(); 16848 int i = 0; 16849 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16850 startUserInBackground(toStart.get(i).id); 16851 } 16852 if (i < n) { 16853 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16854 } 16855 } 16856 16857 void finishUserBoot(UserStartedState uss) { 16858 synchronized (this) { 16859 if (uss.mState == UserStartedState.STATE_BOOTING 16860 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16861 uss.mState = UserStartedState.STATE_RUNNING; 16862 final int userId = uss.mHandle.getIdentifier(); 16863 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16864 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16865 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16866 broadcastIntentLocked(null, null, intent, 16867 null, null, 0, null, null, 16868 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16869 true, false, MY_PID, Process.SYSTEM_UID, userId); 16870 } 16871 } 16872 } 16873 16874 void finishUserSwitch(UserStartedState uss) { 16875 synchronized (this) { 16876 finishUserBoot(uss); 16877 16878 startProfilesLocked(); 16879 16880 int num = mUserLru.size(); 16881 int i = 0; 16882 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16883 Integer oldUserId = mUserLru.get(i); 16884 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16885 if (oldUss == null) { 16886 // Shouldn't happen, but be sane if it does. 16887 mUserLru.remove(i); 16888 num--; 16889 continue; 16890 } 16891 if (oldUss.mState == UserStartedState.STATE_STOPPING 16892 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16893 // This user is already stopping, doesn't count. 16894 num--; 16895 i++; 16896 continue; 16897 } 16898 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16899 // Owner and current can't be stopped, but count as running. 16900 i++; 16901 continue; 16902 } 16903 // This is a user to be stopped. 16904 stopUserLocked(oldUserId, null); 16905 num--; 16906 i++; 16907 } 16908 } 16909 } 16910 16911 @Override 16912 public int stopUser(final int userId, final IStopUserCallback callback) { 16913 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16914 != PackageManager.PERMISSION_GRANTED) { 16915 String msg = "Permission Denial: switchUser() from pid=" 16916 + Binder.getCallingPid() 16917 + ", uid=" + Binder.getCallingUid() 16918 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16919 Slog.w(TAG, msg); 16920 throw new SecurityException(msg); 16921 } 16922 if (userId <= 0) { 16923 throw new IllegalArgumentException("Can't stop primary user " + userId); 16924 } 16925 synchronized (this) { 16926 return stopUserLocked(userId, callback); 16927 } 16928 } 16929 16930 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16931 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16932 if (mCurrentUserId == userId) { 16933 return ActivityManager.USER_OP_IS_CURRENT; 16934 } 16935 16936 final UserStartedState uss = mStartedUsers.get(userId); 16937 if (uss == null) { 16938 // User is not started, nothing to do... but we do need to 16939 // callback if requested. 16940 if (callback != null) { 16941 mHandler.post(new Runnable() { 16942 @Override 16943 public void run() { 16944 try { 16945 callback.userStopped(userId); 16946 } catch (RemoteException e) { 16947 } 16948 } 16949 }); 16950 } 16951 return ActivityManager.USER_OP_SUCCESS; 16952 } 16953 16954 if (callback != null) { 16955 uss.mStopCallbacks.add(callback); 16956 } 16957 16958 if (uss.mState != UserStartedState.STATE_STOPPING 16959 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16960 uss.mState = UserStartedState.STATE_STOPPING; 16961 updateStartedUserArrayLocked(); 16962 16963 long ident = Binder.clearCallingIdentity(); 16964 try { 16965 // We are going to broadcast ACTION_USER_STOPPING and then 16966 // once that is done send a final ACTION_SHUTDOWN and then 16967 // stop the user. 16968 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16969 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16970 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16971 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16972 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16973 // This is the result receiver for the final shutdown broadcast. 16974 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16975 @Override 16976 public void performReceive(Intent intent, int resultCode, String data, 16977 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16978 finishUserStop(uss); 16979 } 16980 }; 16981 // This is the result receiver for the initial stopping broadcast. 16982 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16983 @Override 16984 public void performReceive(Intent intent, int resultCode, String data, 16985 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16986 // On to the next. 16987 synchronized (ActivityManagerService.this) { 16988 if (uss.mState != UserStartedState.STATE_STOPPING) { 16989 // Whoops, we are being started back up. Abort, abort! 16990 return; 16991 } 16992 uss.mState = UserStartedState.STATE_SHUTDOWN; 16993 } 16994 mSystemServiceManager.stopUser(userId); 16995 broadcastIntentLocked(null, null, shutdownIntent, 16996 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16997 true, false, MY_PID, Process.SYSTEM_UID, userId); 16998 } 16999 }; 17000 // Kick things off. 17001 broadcastIntentLocked(null, null, stoppingIntent, 17002 null, stoppingReceiver, 0, null, null, 17003 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17004 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17005 } finally { 17006 Binder.restoreCallingIdentity(ident); 17007 } 17008 } 17009 17010 return ActivityManager.USER_OP_SUCCESS; 17011 } 17012 17013 void finishUserStop(UserStartedState uss) { 17014 final int userId = uss.mHandle.getIdentifier(); 17015 boolean stopped; 17016 ArrayList<IStopUserCallback> callbacks; 17017 synchronized (this) { 17018 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 17019 if (mStartedUsers.get(userId) != uss) { 17020 stopped = false; 17021 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 17022 stopped = false; 17023 } else { 17024 stopped = true; 17025 // User can no longer run. 17026 mStartedUsers.remove(userId); 17027 mUserLru.remove(Integer.valueOf(userId)); 17028 updateStartedUserArrayLocked(); 17029 17030 // Clean up all state and processes associated with the user. 17031 // Kill all the processes for the user. 17032 forceStopUserLocked(userId, "finish user"); 17033 } 17034 } 17035 17036 for (int i=0; i<callbacks.size(); i++) { 17037 try { 17038 if (stopped) callbacks.get(i).userStopped(userId); 17039 else callbacks.get(i).userStopAborted(userId); 17040 } catch (RemoteException e) { 17041 } 17042 } 17043 17044 if (stopped) { 17045 mSystemServiceManager.cleanupUser(userId); 17046 synchronized (this) { 17047 mStackSupervisor.removeUserLocked(userId); 17048 } 17049 } 17050 } 17051 17052 @Override 17053 public UserInfo getCurrentUser() { 17054 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17055 != PackageManager.PERMISSION_GRANTED) && ( 17056 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17057 != PackageManager.PERMISSION_GRANTED)) { 17058 String msg = "Permission Denial: getCurrentUser() from pid=" 17059 + Binder.getCallingPid() 17060 + ", uid=" + Binder.getCallingUid() 17061 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17062 Slog.w(TAG, msg); 17063 throw new SecurityException(msg); 17064 } 17065 synchronized (this) { 17066 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17067 } 17068 } 17069 17070 int getCurrentUserIdLocked() { 17071 return mCurrentUserId; 17072 } 17073 17074 @Override 17075 public boolean isUserRunning(int userId, boolean orStopped) { 17076 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17077 != PackageManager.PERMISSION_GRANTED) { 17078 String msg = "Permission Denial: isUserRunning() from pid=" 17079 + Binder.getCallingPid() 17080 + ", uid=" + Binder.getCallingUid() 17081 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17082 Slog.w(TAG, msg); 17083 throw new SecurityException(msg); 17084 } 17085 synchronized (this) { 17086 return isUserRunningLocked(userId, orStopped); 17087 } 17088 } 17089 17090 boolean isUserRunningLocked(int userId, boolean orStopped) { 17091 UserStartedState state = mStartedUsers.get(userId); 17092 if (state == null) { 17093 return false; 17094 } 17095 if (orStopped) { 17096 return true; 17097 } 17098 return state.mState != UserStartedState.STATE_STOPPING 17099 && state.mState != UserStartedState.STATE_SHUTDOWN; 17100 } 17101 17102 @Override 17103 public int[] getRunningUserIds() { 17104 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17105 != PackageManager.PERMISSION_GRANTED) { 17106 String msg = "Permission Denial: isUserRunning() from pid=" 17107 + Binder.getCallingPid() 17108 + ", uid=" + Binder.getCallingUid() 17109 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17110 Slog.w(TAG, msg); 17111 throw new SecurityException(msg); 17112 } 17113 synchronized (this) { 17114 return mStartedUserArray; 17115 } 17116 } 17117 17118 private void updateStartedUserArrayLocked() { 17119 int num = 0; 17120 for (int i=0; i<mStartedUsers.size(); i++) { 17121 UserStartedState uss = mStartedUsers.valueAt(i); 17122 // This list does not include stopping users. 17123 if (uss.mState != UserStartedState.STATE_STOPPING 17124 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17125 num++; 17126 } 17127 } 17128 mStartedUserArray = new int[num]; 17129 num = 0; 17130 for (int i=0; i<mStartedUsers.size(); i++) { 17131 UserStartedState uss = mStartedUsers.valueAt(i); 17132 if (uss.mState != UserStartedState.STATE_STOPPING 17133 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17134 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17135 num++; 17136 } 17137 } 17138 } 17139 17140 @Override 17141 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17142 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17143 != PackageManager.PERMISSION_GRANTED) { 17144 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17145 + Binder.getCallingPid() 17146 + ", uid=" + Binder.getCallingUid() 17147 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 17148 Slog.w(TAG, msg); 17149 throw new SecurityException(msg); 17150 } 17151 17152 mUserSwitchObservers.register(observer); 17153 } 17154 17155 @Override 17156 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17157 mUserSwitchObservers.unregister(observer); 17158 } 17159 17160 private boolean userExists(int userId) { 17161 if (userId == 0) { 17162 return true; 17163 } 17164 UserManagerService ums = getUserManagerLocked(); 17165 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17166 } 17167 17168 int[] getUsersLocked() { 17169 UserManagerService ums = getUserManagerLocked(); 17170 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17171 } 17172 17173 UserManagerService getUserManagerLocked() { 17174 if (mUserManager == null) { 17175 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17176 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17177 } 17178 return mUserManager; 17179 } 17180 17181 private int applyUserId(int uid, int userId) { 17182 return UserHandle.getUid(userId, uid); 17183 } 17184 17185 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17186 if (info == null) return null; 17187 ApplicationInfo newInfo = new ApplicationInfo(info); 17188 newInfo.uid = applyUserId(info.uid, userId); 17189 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17190 + info.packageName; 17191 return newInfo; 17192 } 17193 17194 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17195 if (aInfo == null 17196 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17197 return aInfo; 17198 } 17199 17200 ActivityInfo info = new ActivityInfo(aInfo); 17201 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17202 return info; 17203 } 17204 17205 private final class LocalService extends ActivityManagerInternal { 17206 @Override 17207 public void goingToSleep() { 17208 ActivityManagerService.this.goingToSleep(); 17209 } 17210 17211 @Override 17212 public void wakingUp() { 17213 ActivityManagerService.this.wakingUp(); 17214 } 17215 } 17216 17217 /** 17218 * An implementation of IAppTask, that allows an app to manage its own tasks via 17219 * {@link android.app.ActivityManager#AppTask}. We keep track of the callingUid to ensure that 17220 * only the process that calls getAppTasks() can call the AppTask methods. 17221 */ 17222 class AppTaskImpl extends IAppTask.Stub { 17223 private int mTaskId; 17224 private int mCallingUid; 17225 17226 public AppTaskImpl(int taskId, int callingUid) { 17227 mTaskId = taskId; 17228 mCallingUid = callingUid; 17229 } 17230 17231 @Override 17232 public void finishAndRemoveTask() { 17233 // Ensure that we are called from the same process that created this AppTask 17234 if (mCallingUid != Binder.getCallingUid()) { 17235 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17236 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17237 return; 17238 } 17239 17240 synchronized (ActivityManagerService.this) { 17241 long origId = Binder.clearCallingIdentity(); 17242 try { 17243 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17244 if (tr != null) { 17245 // Only kill the process if we are not a new document 17246 int flags = tr.getBaseIntent().getFlags(); 17247 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 17248 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 17249 removeTaskByIdLocked(mTaskId, 17250 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 17251 } 17252 } finally { 17253 Binder.restoreCallingIdentity(origId); 17254 } 17255 } 17256 } 17257 17258 @Override 17259 public ActivityManager.RecentTaskInfo getTaskInfo() { 17260 // Ensure that we are called from the same process that created this AppTask 17261 if (mCallingUid != Binder.getCallingUid()) { 17262 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17263 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17264 return null; 17265 } 17266 17267 synchronized (ActivityManagerService.this) { 17268 long origId = Binder.clearCallingIdentity(); 17269 try { 17270 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17271 if (tr != null) { 17272 return createRecentTaskInfoFromTaskRecord(tr); 17273 } 17274 } finally { 17275 Binder.restoreCallingIdentity(origId); 17276 } 17277 return null; 17278 } 17279 } 17280 } 17281} 17282