ActivityManagerService.java revision ef73ee1dd98acfc4a19561367cfc3e4d8bbe06ea
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 ArrayList<TaskRecord> mRecentTasks; 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 * Save recent tasks information across reboots. 825 */ 826 final TaskPersister mTaskPersister; 827 828 /** 829 * Current configuration information. HistoryRecord objects are given 830 * a reference to this object to indicate which configuration they are 831 * currently running in, so this object must be kept immutable. 832 */ 833 Configuration mConfiguration = new Configuration(); 834 835 /** 836 * Current sequencing integer of the configuration, for skipping old 837 * configurations. 838 */ 839 int mConfigurationSeq = 0; 840 841 /** 842 * Hardware-reported OpenGLES version. 843 */ 844 final int GL_ES_VERSION; 845 846 /** 847 * List of initialization arguments to pass to all processes when binding applications to them. 848 * For example, references to the commonly used services. 849 */ 850 HashMap<String, IBinder> mAppBindArgs; 851 852 /** 853 * Temporary to avoid allocations. Protected by main lock. 854 */ 855 final StringBuilder mStringBuilder = new StringBuilder(256); 856 857 /** 858 * Used to control how we initialize the service. 859 */ 860 ComponentName mTopComponent; 861 String mTopAction = Intent.ACTION_MAIN; 862 String mTopData; 863 boolean mProcessesReady = false; 864 boolean mSystemReady = false; 865 boolean mBooting = false; 866 boolean mWaitingUpdate = false; 867 boolean mDidUpdate = false; 868 boolean mOnBattery = false; 869 boolean mLaunchWarningShown = false; 870 871 Context mContext; 872 873 int mFactoryTest; 874 875 boolean mCheckedForSetup; 876 877 /** 878 * The time at which we will allow normal application switches again, 879 * after a call to {@link #stopAppSwitches()}. 880 */ 881 long mAppSwitchesAllowedTime; 882 883 /** 884 * This is set to true after the first switch after mAppSwitchesAllowedTime 885 * is set; any switches after that will clear the time. 886 */ 887 boolean mDidAppSwitch; 888 889 /** 890 * Last time (in realtime) at which we checked for power usage. 891 */ 892 long mLastPowerCheckRealtime; 893 894 /** 895 * Last time (in uptime) at which we checked for power usage. 896 */ 897 long mLastPowerCheckUptime; 898 899 /** 900 * Set while we are wanting to sleep, to prevent any 901 * activities from being started/resumed. 902 */ 903 private boolean mSleeping = false; 904 905 /** 906 * Set while we are running a voice interaction. This overrides 907 * sleeping while it is active. 908 */ 909 private boolean mRunningVoice = false; 910 911 /** 912 * State of external calls telling us if the device is asleep. 913 */ 914 private boolean mWentToSleep = false; 915 916 /** 917 * State of external call telling us if the lock screen is shown. 918 */ 919 private boolean mLockScreenShown = false; 920 921 /** 922 * Set if we are shutting down the system, similar to sleeping. 923 */ 924 boolean mShuttingDown = false; 925 926 /** 927 * Current sequence id for oom_adj computation traversal. 928 */ 929 int mAdjSeq = 0; 930 931 /** 932 * Current sequence id for process LRU updating. 933 */ 934 int mLruSeq = 0; 935 936 /** 937 * Keep track of the non-cached/empty process we last found, to help 938 * determine how to distribute cached/empty processes next time. 939 */ 940 int mNumNonCachedProcs = 0; 941 942 /** 943 * Keep track of the number of cached hidden procs, to balance oom adj 944 * distribution between those and empty procs. 945 */ 946 int mNumCachedHiddenProcs = 0; 947 948 /** 949 * Keep track of the number of service processes we last found, to 950 * determine on the next iteration which should be B services. 951 */ 952 int mNumServiceProcs = 0; 953 int mNewNumAServiceProcs = 0; 954 int mNewNumServiceProcs = 0; 955 956 /** 957 * Allow the current computed overall memory level of the system to go down? 958 * This is set to false when we are killing processes for reasons other than 959 * memory management, so that the now smaller process list will not be taken as 960 * an indication that memory is tighter. 961 */ 962 boolean mAllowLowerMemLevel = false; 963 964 /** 965 * The last computed memory level, for holding when we are in a state that 966 * processes are going away for other reasons. 967 */ 968 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 969 970 /** 971 * The last total number of process we have, to determine if changes actually look 972 * like a shrinking number of process due to lower RAM. 973 */ 974 int mLastNumProcesses; 975 976 /** 977 * The uptime of the last time we performed idle maintenance. 978 */ 979 long mLastIdleTime = SystemClock.uptimeMillis(); 980 981 /** 982 * Total time spent with RAM that has been added in the past since the last idle time. 983 */ 984 long mLowRamTimeSinceLastIdle = 0; 985 986 /** 987 * If RAM is currently low, when that horrible situation started. 988 */ 989 long mLowRamStartTime = 0; 990 991 /** 992 * For reporting to battery stats the current top application. 993 */ 994 private String mCurResumedPackage = null; 995 private int mCurResumedUid = -1; 996 997 /** 998 * For reporting to battery stats the apps currently running foreground 999 * service. The ProcessMap is package/uid tuples; each of these contain 1000 * an array of the currently foreground processes. 1001 */ 1002 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1003 = new ProcessMap<ArrayList<ProcessRecord>>(); 1004 1005 /** 1006 * This is set if we had to do a delayed dexopt of an app before launching 1007 * it, to increase the ANR timeouts in that case. 1008 */ 1009 boolean mDidDexOpt; 1010 1011 /** 1012 * Set if the systemServer made a call to enterSafeMode. 1013 */ 1014 boolean mSafeMode; 1015 1016 String mDebugApp = null; 1017 boolean mWaitForDebugger = false; 1018 boolean mDebugTransient = false; 1019 String mOrigDebugApp = null; 1020 boolean mOrigWaitForDebugger = false; 1021 boolean mAlwaysFinishActivities = false; 1022 IActivityController mController = null; 1023 String mProfileApp = null; 1024 ProcessRecord mProfileProc = null; 1025 String mProfileFile; 1026 ParcelFileDescriptor mProfileFd; 1027 int mProfileType = 0; 1028 boolean mAutoStopProfiler = false; 1029 String mOpenGlTraceApp = null; 1030 1031 static class ProcessChangeItem { 1032 static final int CHANGE_ACTIVITIES = 1<<0; 1033 static final int CHANGE_PROCESS_STATE = 1<<1; 1034 int changes; 1035 int uid; 1036 int pid; 1037 int processState; 1038 boolean foregroundActivities; 1039 } 1040 1041 final RemoteCallbackList<IProcessObserver> mProcessObservers 1042 = new RemoteCallbackList<IProcessObserver>(); 1043 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1044 1045 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1046 = new ArrayList<ProcessChangeItem>(); 1047 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1048 = new ArrayList<ProcessChangeItem>(); 1049 1050 /** 1051 * Runtime CPU use collection thread. This object's lock is used to 1052 * protect all related state. 1053 */ 1054 final Thread mProcessCpuThread; 1055 1056 /** 1057 * Used to collect process stats when showing not responding dialog. 1058 * Protected by mProcessCpuThread. 1059 */ 1060 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1061 MONITOR_THREAD_CPU_USAGE); 1062 final AtomicLong mLastCpuTime = new AtomicLong(0); 1063 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1064 1065 long mLastWriteTime = 0; 1066 1067 /** 1068 * Used to retain an update lock when the foreground activity is in 1069 * immersive mode. 1070 */ 1071 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1072 1073 /** 1074 * Set to true after the system has finished booting. 1075 */ 1076 boolean mBooted = false; 1077 1078 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1079 int mProcessLimitOverride = -1; 1080 1081 WindowManagerService mWindowManager; 1082 1083 final ActivityThread mSystemThread; 1084 1085 int mCurrentUserId = 0; 1086 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1087 private UserManagerService mUserManager; 1088 1089 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1090 final ProcessRecord mApp; 1091 final int mPid; 1092 final IApplicationThread mAppThread; 1093 1094 AppDeathRecipient(ProcessRecord app, int pid, 1095 IApplicationThread thread) { 1096 if (localLOGV) Slog.v( 1097 TAG, "New death recipient " + this 1098 + " for thread " + thread.asBinder()); 1099 mApp = app; 1100 mPid = pid; 1101 mAppThread = thread; 1102 } 1103 1104 @Override 1105 public void binderDied() { 1106 if (localLOGV) Slog.v( 1107 TAG, "Death received in " + this 1108 + " for thread " + mAppThread.asBinder()); 1109 synchronized(ActivityManagerService.this) { 1110 appDiedLocked(mApp, mPid, mAppThread); 1111 } 1112 } 1113 } 1114 1115 static final int SHOW_ERROR_MSG = 1; 1116 static final int SHOW_NOT_RESPONDING_MSG = 2; 1117 static final int SHOW_FACTORY_ERROR_MSG = 3; 1118 static final int UPDATE_CONFIGURATION_MSG = 4; 1119 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1120 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1121 static final int SERVICE_TIMEOUT_MSG = 12; 1122 static final int UPDATE_TIME_ZONE = 13; 1123 static final int SHOW_UID_ERROR_MSG = 14; 1124 static final int IM_FEELING_LUCKY_MSG = 15; 1125 static final int PROC_START_TIMEOUT_MSG = 20; 1126 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1127 static final int KILL_APPLICATION_MSG = 22; 1128 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1129 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1130 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1131 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1132 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1133 static final int CLEAR_DNS_CACHE_MSG = 28; 1134 static final int UPDATE_HTTP_PROXY_MSG = 29; 1135 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1136 static final int DISPATCH_PROCESSES_CHANGED = 31; 1137 static final int DISPATCH_PROCESS_DIED = 32; 1138 static final int REPORT_MEM_USAGE_MSG = 33; 1139 static final int REPORT_USER_SWITCH_MSG = 34; 1140 static final int CONTINUE_USER_SWITCH_MSG = 35; 1141 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1142 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1143 static final int PERSIST_URI_GRANTS_MSG = 38; 1144 static final int REQUEST_ALL_PSS_MSG = 39; 1145 static final int START_PROFILES_MSG = 40; 1146 static final int UPDATE_TIME = 41; 1147 static final int SYSTEM_USER_START_MSG = 42; 1148 static final int SYSTEM_USER_CURRENT_MSG = 43; 1149 1150 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1151 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1152 static final int FIRST_COMPAT_MODE_MSG = 300; 1153 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1154 1155 AlertDialog mUidAlert; 1156 CompatModeDialog mCompatModeDialog; 1157 long mLastMemUsageReportTime = 0; 1158 1159 /** 1160 * Flag whether the current user is a "monkey", i.e. whether 1161 * the UI is driven by a UI automation tool. 1162 */ 1163 private boolean mUserIsMonkey; 1164 1165 final ServiceThread mHandlerThread; 1166 final MainHandler mHandler; 1167 1168 final class MainHandler extends Handler { 1169 public MainHandler(Looper looper) { 1170 super(looper, null, true); 1171 } 1172 1173 @Override 1174 public void handleMessage(Message msg) { 1175 switch (msg.what) { 1176 case SHOW_ERROR_MSG: { 1177 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1178 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1179 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1180 synchronized (ActivityManagerService.this) { 1181 ProcessRecord proc = (ProcessRecord)data.get("app"); 1182 AppErrorResult res = (AppErrorResult) data.get("result"); 1183 if (proc != null && proc.crashDialog != null) { 1184 Slog.e(TAG, "App already has crash dialog: " + proc); 1185 if (res != null) { 1186 res.set(0); 1187 } 1188 return; 1189 } 1190 if (!showBackground && UserHandle.getAppId(proc.uid) 1191 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1192 && proc.pid != MY_PID) { 1193 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1194 if (res != null) { 1195 res.set(0); 1196 } 1197 return; 1198 } 1199 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1200 Dialog d = new AppErrorDialog(mContext, 1201 ActivityManagerService.this, res, proc); 1202 d.show(); 1203 proc.crashDialog = d; 1204 } else { 1205 // The device is asleep, so just pretend that the user 1206 // saw a crash dialog and hit "force quit". 1207 if (res != null) { 1208 res.set(0); 1209 } 1210 } 1211 } 1212 1213 ensureBootCompleted(); 1214 } break; 1215 case SHOW_NOT_RESPONDING_MSG: { 1216 synchronized (ActivityManagerService.this) { 1217 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1218 ProcessRecord proc = (ProcessRecord)data.get("app"); 1219 if (proc != null && proc.anrDialog != null) { 1220 Slog.e(TAG, "App already has anr dialog: " + proc); 1221 return; 1222 } 1223 1224 Intent intent = new Intent("android.intent.action.ANR"); 1225 if (!mProcessesReady) { 1226 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1227 | Intent.FLAG_RECEIVER_FOREGROUND); 1228 } 1229 broadcastIntentLocked(null, null, intent, 1230 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1231 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1232 1233 if (mShowDialogs) { 1234 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1235 mContext, proc, (ActivityRecord)data.get("activity"), 1236 msg.arg1 != 0); 1237 d.show(); 1238 proc.anrDialog = d; 1239 } else { 1240 // Just kill the app if there is no dialog to be shown. 1241 killAppAtUsersRequest(proc, null); 1242 } 1243 } 1244 1245 ensureBootCompleted(); 1246 } break; 1247 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1248 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1249 synchronized (ActivityManagerService.this) { 1250 ProcessRecord proc = (ProcessRecord) data.get("app"); 1251 if (proc == null) { 1252 Slog.e(TAG, "App not found when showing strict mode dialog."); 1253 break; 1254 } 1255 if (proc.crashDialog != null) { 1256 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1257 return; 1258 } 1259 AppErrorResult res = (AppErrorResult) data.get("result"); 1260 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1261 Dialog d = new StrictModeViolationDialog(mContext, 1262 ActivityManagerService.this, res, proc); 1263 d.show(); 1264 proc.crashDialog = d; 1265 } else { 1266 // The device is asleep, so just pretend that the user 1267 // saw a crash dialog and hit "force quit". 1268 res.set(0); 1269 } 1270 } 1271 ensureBootCompleted(); 1272 } break; 1273 case SHOW_FACTORY_ERROR_MSG: { 1274 Dialog d = new FactoryErrorDialog( 1275 mContext, msg.getData().getCharSequence("msg")); 1276 d.show(); 1277 ensureBootCompleted(); 1278 } break; 1279 case UPDATE_CONFIGURATION_MSG: { 1280 final ContentResolver resolver = mContext.getContentResolver(); 1281 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1282 } break; 1283 case GC_BACKGROUND_PROCESSES_MSG: { 1284 synchronized (ActivityManagerService.this) { 1285 performAppGcsIfAppropriateLocked(); 1286 } 1287 } break; 1288 case WAIT_FOR_DEBUGGER_MSG: { 1289 synchronized (ActivityManagerService.this) { 1290 ProcessRecord app = (ProcessRecord)msg.obj; 1291 if (msg.arg1 != 0) { 1292 if (!app.waitedForDebugger) { 1293 Dialog d = new AppWaitingForDebuggerDialog( 1294 ActivityManagerService.this, 1295 mContext, app); 1296 app.waitDialog = d; 1297 app.waitedForDebugger = true; 1298 d.show(); 1299 } 1300 } else { 1301 if (app.waitDialog != null) { 1302 app.waitDialog.dismiss(); 1303 app.waitDialog = null; 1304 } 1305 } 1306 } 1307 } break; 1308 case SERVICE_TIMEOUT_MSG: { 1309 if (mDidDexOpt) { 1310 mDidDexOpt = false; 1311 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1312 nmsg.obj = msg.obj; 1313 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1314 return; 1315 } 1316 mServices.serviceTimeout((ProcessRecord)msg.obj); 1317 } break; 1318 case UPDATE_TIME_ZONE: { 1319 synchronized (ActivityManagerService.this) { 1320 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1321 ProcessRecord r = mLruProcesses.get(i); 1322 if (r.thread != null) { 1323 try { 1324 r.thread.updateTimeZone(); 1325 } catch (RemoteException ex) { 1326 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1327 } 1328 } 1329 } 1330 } 1331 } break; 1332 case CLEAR_DNS_CACHE_MSG: { 1333 synchronized (ActivityManagerService.this) { 1334 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1335 ProcessRecord r = mLruProcesses.get(i); 1336 if (r.thread != null) { 1337 try { 1338 r.thread.clearDnsCache(); 1339 } catch (RemoteException ex) { 1340 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1341 } 1342 } 1343 } 1344 } 1345 } break; 1346 case UPDATE_HTTP_PROXY_MSG: { 1347 ProxyInfo proxy = (ProxyInfo)msg.obj; 1348 String host = ""; 1349 String port = ""; 1350 String exclList = ""; 1351 Uri pacFileUrl = Uri.EMPTY; 1352 if (proxy != null) { 1353 host = proxy.getHost(); 1354 port = Integer.toString(proxy.getPort()); 1355 exclList = proxy.getExclusionListAsString(); 1356 pacFileUrl = proxy.getPacFileUrl(); 1357 } 1358 synchronized (ActivityManagerService.this) { 1359 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1360 ProcessRecord r = mLruProcesses.get(i); 1361 if (r.thread != null) { 1362 try { 1363 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1364 } catch (RemoteException ex) { 1365 Slog.w(TAG, "Failed to update http proxy for: " + 1366 r.info.processName); 1367 } 1368 } 1369 } 1370 } 1371 } break; 1372 case SHOW_UID_ERROR_MSG: { 1373 String title = "System UIDs Inconsistent"; 1374 String text = "UIDs on the system are inconsistent, you need to wipe your" 1375 + " data partition or your device will be unstable."; 1376 Log.e(TAG, title + ": " + text); 1377 if (mShowDialogs) { 1378 // XXX This is a temporary dialog, no need to localize. 1379 AlertDialog d = new BaseErrorDialog(mContext); 1380 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1381 d.setCancelable(false); 1382 d.setTitle(title); 1383 d.setMessage(text); 1384 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1385 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1386 mUidAlert = d; 1387 d.show(); 1388 } 1389 } break; 1390 case IM_FEELING_LUCKY_MSG: { 1391 if (mUidAlert != null) { 1392 mUidAlert.dismiss(); 1393 mUidAlert = null; 1394 } 1395 } break; 1396 case PROC_START_TIMEOUT_MSG: { 1397 if (mDidDexOpt) { 1398 mDidDexOpt = false; 1399 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1400 nmsg.obj = msg.obj; 1401 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1402 return; 1403 } 1404 ProcessRecord app = (ProcessRecord)msg.obj; 1405 synchronized (ActivityManagerService.this) { 1406 processStartTimedOutLocked(app); 1407 } 1408 } break; 1409 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1410 synchronized (ActivityManagerService.this) { 1411 doPendingActivityLaunchesLocked(true); 1412 } 1413 } break; 1414 case KILL_APPLICATION_MSG: { 1415 synchronized (ActivityManagerService.this) { 1416 int appid = msg.arg1; 1417 boolean restart = (msg.arg2 == 1); 1418 Bundle bundle = (Bundle)msg.obj; 1419 String pkg = bundle.getString("pkg"); 1420 String reason = bundle.getString("reason"); 1421 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1422 false, UserHandle.USER_ALL, reason); 1423 } 1424 } break; 1425 case FINALIZE_PENDING_INTENT_MSG: { 1426 ((PendingIntentRecord)msg.obj).completeFinalize(); 1427 } break; 1428 case POST_HEAVY_NOTIFICATION_MSG: { 1429 INotificationManager inm = NotificationManager.getService(); 1430 if (inm == null) { 1431 return; 1432 } 1433 1434 ActivityRecord root = (ActivityRecord)msg.obj; 1435 ProcessRecord process = root.app; 1436 if (process == null) { 1437 return; 1438 } 1439 1440 try { 1441 Context context = mContext.createPackageContext(process.info.packageName, 0); 1442 String text = mContext.getString(R.string.heavy_weight_notification, 1443 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1444 Notification notification = new Notification(); 1445 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1446 notification.when = 0; 1447 notification.flags = Notification.FLAG_ONGOING_EVENT; 1448 notification.tickerText = text; 1449 notification.defaults = 0; // please be quiet 1450 notification.sound = null; 1451 notification.vibrate = null; 1452 notification.setLatestEventInfo(context, text, 1453 mContext.getText(R.string.heavy_weight_notification_detail), 1454 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1455 PendingIntent.FLAG_CANCEL_CURRENT, null, 1456 new UserHandle(root.userId))); 1457 1458 try { 1459 int[] outId = new int[1]; 1460 inm.enqueueNotificationWithTag("android", "android", null, 1461 R.string.heavy_weight_notification, 1462 notification, outId, root.userId); 1463 } catch (RuntimeException e) { 1464 Slog.w(ActivityManagerService.TAG, 1465 "Error showing notification for heavy-weight app", e); 1466 } catch (RemoteException e) { 1467 } 1468 } catch (NameNotFoundException e) { 1469 Slog.w(TAG, "Unable to create context for heavy notification", e); 1470 } 1471 } break; 1472 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1473 INotificationManager inm = NotificationManager.getService(); 1474 if (inm == null) { 1475 return; 1476 } 1477 try { 1478 inm.cancelNotificationWithTag("android", null, 1479 R.string.heavy_weight_notification, msg.arg1); 1480 } catch (RuntimeException e) { 1481 Slog.w(ActivityManagerService.TAG, 1482 "Error canceling notification for service", e); 1483 } catch (RemoteException e) { 1484 } 1485 } break; 1486 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1487 synchronized (ActivityManagerService.this) { 1488 checkExcessivePowerUsageLocked(true); 1489 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1490 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1491 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1492 } 1493 } break; 1494 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1495 synchronized (ActivityManagerService.this) { 1496 ActivityRecord ar = (ActivityRecord)msg.obj; 1497 if (mCompatModeDialog != null) { 1498 if (mCompatModeDialog.mAppInfo.packageName.equals( 1499 ar.info.applicationInfo.packageName)) { 1500 return; 1501 } 1502 mCompatModeDialog.dismiss(); 1503 mCompatModeDialog = null; 1504 } 1505 if (ar != null && false) { 1506 if (mCompatModePackages.getPackageAskCompatModeLocked( 1507 ar.packageName)) { 1508 int mode = mCompatModePackages.computeCompatModeLocked( 1509 ar.info.applicationInfo); 1510 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1511 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1512 mCompatModeDialog = new CompatModeDialog( 1513 ActivityManagerService.this, mContext, 1514 ar.info.applicationInfo); 1515 mCompatModeDialog.show(); 1516 } 1517 } 1518 } 1519 } 1520 break; 1521 } 1522 case DISPATCH_PROCESSES_CHANGED: { 1523 dispatchProcessesChanged(); 1524 break; 1525 } 1526 case DISPATCH_PROCESS_DIED: { 1527 final int pid = msg.arg1; 1528 final int uid = msg.arg2; 1529 dispatchProcessDied(pid, uid); 1530 break; 1531 } 1532 case REPORT_MEM_USAGE_MSG: { 1533 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1534 Thread thread = new Thread() { 1535 @Override public void run() { 1536 final SparseArray<ProcessMemInfo> infoMap 1537 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1538 for (int i=0, N=memInfos.size(); i<N; i++) { 1539 ProcessMemInfo mi = memInfos.get(i); 1540 infoMap.put(mi.pid, mi); 1541 } 1542 updateCpuStatsNow(); 1543 synchronized (mProcessCpuThread) { 1544 final int N = mProcessCpuTracker.countStats(); 1545 for (int i=0; i<N; i++) { 1546 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1547 if (st.vsize > 0) { 1548 long pss = Debug.getPss(st.pid, null); 1549 if (pss > 0) { 1550 if (infoMap.indexOfKey(st.pid) < 0) { 1551 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1552 ProcessList.NATIVE_ADJ, -1, "native", null); 1553 mi.pss = pss; 1554 memInfos.add(mi); 1555 } 1556 } 1557 } 1558 } 1559 } 1560 1561 long totalPss = 0; 1562 for (int i=0, N=memInfos.size(); i<N; i++) { 1563 ProcessMemInfo mi = memInfos.get(i); 1564 if (mi.pss == 0) { 1565 mi.pss = Debug.getPss(mi.pid, null); 1566 } 1567 totalPss += mi.pss; 1568 } 1569 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1570 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1571 if (lhs.oomAdj != rhs.oomAdj) { 1572 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1573 } 1574 if (lhs.pss != rhs.pss) { 1575 return lhs.pss < rhs.pss ? 1 : -1; 1576 } 1577 return 0; 1578 } 1579 }); 1580 1581 StringBuilder tag = new StringBuilder(128); 1582 StringBuilder stack = new StringBuilder(128); 1583 tag.append("Low on memory -- "); 1584 appendMemBucket(tag, totalPss, "total", false); 1585 appendMemBucket(stack, totalPss, "total", true); 1586 1587 StringBuilder logBuilder = new StringBuilder(1024); 1588 logBuilder.append("Low on memory:\n"); 1589 1590 boolean firstLine = true; 1591 int lastOomAdj = Integer.MIN_VALUE; 1592 for (int i=0, N=memInfos.size(); i<N; i++) { 1593 ProcessMemInfo mi = memInfos.get(i); 1594 1595 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1596 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1597 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1598 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1599 if (lastOomAdj != mi.oomAdj) { 1600 lastOomAdj = mi.oomAdj; 1601 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1602 tag.append(" / "); 1603 } 1604 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1605 if (firstLine) { 1606 stack.append(":"); 1607 firstLine = false; 1608 } 1609 stack.append("\n\t at "); 1610 } else { 1611 stack.append("$"); 1612 } 1613 } else { 1614 tag.append(" "); 1615 stack.append("$"); 1616 } 1617 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1618 appendMemBucket(tag, mi.pss, mi.name, false); 1619 } 1620 appendMemBucket(stack, mi.pss, mi.name, true); 1621 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1622 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1623 stack.append("("); 1624 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1625 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1626 stack.append(DUMP_MEM_OOM_LABEL[k]); 1627 stack.append(":"); 1628 stack.append(DUMP_MEM_OOM_ADJ[k]); 1629 } 1630 } 1631 stack.append(")"); 1632 } 1633 } 1634 1635 logBuilder.append(" "); 1636 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1637 logBuilder.append(' '); 1638 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1639 logBuilder.append(' '); 1640 ProcessList.appendRamKb(logBuilder, mi.pss); 1641 logBuilder.append(" kB: "); 1642 logBuilder.append(mi.name); 1643 logBuilder.append(" ("); 1644 logBuilder.append(mi.pid); 1645 logBuilder.append(") "); 1646 logBuilder.append(mi.adjType); 1647 logBuilder.append('\n'); 1648 if (mi.adjReason != null) { 1649 logBuilder.append(" "); 1650 logBuilder.append(mi.adjReason); 1651 logBuilder.append('\n'); 1652 } 1653 } 1654 1655 logBuilder.append(" "); 1656 ProcessList.appendRamKb(logBuilder, totalPss); 1657 logBuilder.append(" kB: TOTAL\n"); 1658 1659 long[] infos = new long[Debug.MEMINFO_COUNT]; 1660 Debug.getMemInfo(infos); 1661 logBuilder.append(" MemInfo: "); 1662 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1663 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1664 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1665 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1666 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1667 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1668 logBuilder.append(" ZRAM: "); 1669 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1670 logBuilder.append(" kB RAM, "); 1671 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1672 logBuilder.append(" kB swap total, "); 1673 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1674 logBuilder.append(" kB swap free\n"); 1675 } 1676 Slog.i(TAG, logBuilder.toString()); 1677 1678 StringBuilder dropBuilder = new StringBuilder(1024); 1679 /* 1680 StringWriter oomSw = new StringWriter(); 1681 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1682 StringWriter catSw = new StringWriter(); 1683 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1684 String[] emptyArgs = new String[] { }; 1685 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1686 oomPw.flush(); 1687 String oomString = oomSw.toString(); 1688 */ 1689 dropBuilder.append(stack); 1690 dropBuilder.append('\n'); 1691 dropBuilder.append('\n'); 1692 dropBuilder.append(logBuilder); 1693 dropBuilder.append('\n'); 1694 /* 1695 dropBuilder.append(oomString); 1696 dropBuilder.append('\n'); 1697 */ 1698 StringWriter catSw = new StringWriter(); 1699 synchronized (ActivityManagerService.this) { 1700 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1701 String[] emptyArgs = new String[] { }; 1702 catPw.println(); 1703 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1704 catPw.println(); 1705 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1706 false, false, null); 1707 catPw.println(); 1708 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1709 catPw.flush(); 1710 } 1711 dropBuilder.append(catSw.toString()); 1712 addErrorToDropBox("lowmem", null, "system_server", null, 1713 null, tag.toString(), dropBuilder.toString(), null, null); 1714 //Slog.i(TAG, "Sent to dropbox:"); 1715 //Slog.i(TAG, dropBuilder.toString()); 1716 synchronized (ActivityManagerService.this) { 1717 long now = SystemClock.uptimeMillis(); 1718 if (mLastMemUsageReportTime < now) { 1719 mLastMemUsageReportTime = now; 1720 } 1721 } 1722 } 1723 }; 1724 thread.start(); 1725 break; 1726 } 1727 case REPORT_USER_SWITCH_MSG: { 1728 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1729 break; 1730 } 1731 case CONTINUE_USER_SWITCH_MSG: { 1732 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1733 break; 1734 } 1735 case USER_SWITCH_TIMEOUT_MSG: { 1736 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1737 break; 1738 } 1739 case IMMERSIVE_MODE_LOCK_MSG: { 1740 final boolean nextState = (msg.arg1 != 0); 1741 if (mUpdateLock.isHeld() != nextState) { 1742 if (DEBUG_IMMERSIVE) { 1743 final ActivityRecord r = (ActivityRecord) msg.obj; 1744 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1745 } 1746 if (nextState) { 1747 mUpdateLock.acquire(); 1748 } else { 1749 mUpdateLock.release(); 1750 } 1751 } 1752 break; 1753 } 1754 case PERSIST_URI_GRANTS_MSG: { 1755 writeGrantedUriPermissions(); 1756 break; 1757 } 1758 case REQUEST_ALL_PSS_MSG: { 1759 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1760 break; 1761 } 1762 case START_PROFILES_MSG: { 1763 synchronized (ActivityManagerService.this) { 1764 startProfilesLocked(); 1765 } 1766 break; 1767 } 1768 case UPDATE_TIME: { 1769 synchronized (ActivityManagerService.this) { 1770 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1771 ProcessRecord r = mLruProcesses.get(i); 1772 if (r.thread != null) { 1773 try { 1774 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1775 } catch (RemoteException ex) { 1776 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1777 } 1778 } 1779 } 1780 } 1781 break; 1782 } 1783 case SYSTEM_USER_START_MSG: { 1784 mSystemServiceManager.startUser(msg.arg1); 1785 break; 1786 } 1787 case SYSTEM_USER_CURRENT_MSG: { 1788 mSystemServiceManager.switchUser(msg.arg1); 1789 break; 1790 } 1791 } 1792 } 1793 }; 1794 1795 static final int COLLECT_PSS_BG_MSG = 1; 1796 1797 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1798 @Override 1799 public void handleMessage(Message msg) { 1800 switch (msg.what) { 1801 case COLLECT_PSS_BG_MSG: { 1802 int i=0, num=0; 1803 long start = SystemClock.uptimeMillis(); 1804 long[] tmp = new long[1]; 1805 do { 1806 ProcessRecord proc; 1807 int procState; 1808 int pid; 1809 synchronized (ActivityManagerService.this) { 1810 if (i >= mPendingPssProcesses.size()) { 1811 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1812 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1813 mPendingPssProcesses.clear(); 1814 return; 1815 } 1816 proc = mPendingPssProcesses.get(i); 1817 procState = proc.pssProcState; 1818 if (proc.thread != null && procState == proc.setProcState) { 1819 pid = proc.pid; 1820 } else { 1821 proc = null; 1822 pid = 0; 1823 } 1824 i++; 1825 } 1826 if (proc != null) { 1827 long pss = Debug.getPss(pid, tmp); 1828 synchronized (ActivityManagerService.this) { 1829 if (proc.thread != null && proc.setProcState == procState 1830 && proc.pid == pid) { 1831 num++; 1832 proc.lastPssTime = SystemClock.uptimeMillis(); 1833 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1834 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1835 + ": " + pss + " lastPss=" + proc.lastPss 1836 + " state=" + ProcessList.makeProcStateString(procState)); 1837 if (proc.initialIdlePss == 0) { 1838 proc.initialIdlePss = pss; 1839 } 1840 proc.lastPss = pss; 1841 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1842 proc.lastCachedPss = pss; 1843 } 1844 } 1845 } 1846 } 1847 } while (true); 1848 } 1849 } 1850 } 1851 }; 1852 1853 /** 1854 * Monitor for package changes and update our internal state. 1855 */ 1856 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1857 @Override 1858 public void onPackageRemoved(String packageName, int uid) { 1859 // Remove all tasks with activities in the specified package from the list of recent tasks 1860 synchronized (ActivityManagerService.this) { 1861 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1862 TaskRecord tr = mRecentTasks.get(i); 1863 ComponentName cn = tr.intent.getComponent(); 1864 if (cn != null && cn.getPackageName().equals(packageName)) { 1865 // If the package name matches, remove the task and kill the process 1866 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1867 } 1868 } 1869 } 1870 } 1871 1872 @Override 1873 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1874 onPackageModified(packageName); 1875 return true; 1876 } 1877 1878 @Override 1879 public void onPackageModified(String packageName) { 1880 final PackageManager pm = mContext.getPackageManager(); 1881 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1882 new ArrayList<Pair<Intent, Integer>>(); 1883 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1884 // Copy the list of recent tasks so that we don't hold onto the lock on 1885 // ActivityManagerService for long periods while checking if components exist. 1886 synchronized (ActivityManagerService.this) { 1887 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1888 TaskRecord tr = mRecentTasks.get(i); 1889 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1890 } 1891 } 1892 // Check the recent tasks and filter out all tasks with components that no longer exist. 1893 Intent tmpI = new Intent(); 1894 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1895 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1896 ComponentName cn = p.first.getComponent(); 1897 if (cn != null && cn.getPackageName().equals(packageName)) { 1898 try { 1899 // Add the task to the list to remove if the component no longer exists 1900 tmpI.setComponent(cn); 1901 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1902 tasksToRemove.add(p.second); 1903 } 1904 } catch (Exception e) {} 1905 } 1906 } 1907 // Prune all the tasks with removed components from the list of recent tasks 1908 synchronized (ActivityManagerService.this) { 1909 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1910 // Remove the task but don't kill the process (since other components in that 1911 // package may still be running and in the background) 1912 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1913 } 1914 } 1915 } 1916 1917 @Override 1918 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1919 // Force stop the specified packages 1920 if (packages != null) { 1921 for (String pkg : packages) { 1922 synchronized (ActivityManagerService.this) { 1923 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1924 "finished booting")) { 1925 return true; 1926 } 1927 } 1928 } 1929 } 1930 return false; 1931 } 1932 }; 1933 1934 public void setSystemProcess() { 1935 try { 1936 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1937 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1938 ServiceManager.addService("meminfo", new MemBinder(this)); 1939 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1940 ServiceManager.addService("dbinfo", new DbBinder(this)); 1941 if (MONITOR_CPU_USAGE) { 1942 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1943 } 1944 ServiceManager.addService("permission", new PermissionController(this)); 1945 1946 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1947 "android", STOCK_PM_FLAGS); 1948 mSystemThread.installSystemApplicationInfo(info); 1949 1950 synchronized (this) { 1951 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1952 app.persistent = true; 1953 app.pid = MY_PID; 1954 app.maxAdj = ProcessList.SYSTEM_ADJ; 1955 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1956 mProcessNames.put(app.processName, app.uid, app); 1957 synchronized (mPidsSelfLocked) { 1958 mPidsSelfLocked.put(app.pid, app); 1959 } 1960 updateLruProcessLocked(app, false, null); 1961 updateOomAdjLocked(); 1962 } 1963 } catch (PackageManager.NameNotFoundException e) { 1964 throw new RuntimeException( 1965 "Unable to find android system package", e); 1966 } 1967 } 1968 1969 public void setWindowManager(WindowManagerService wm) { 1970 mWindowManager = wm; 1971 mStackSupervisor.setWindowManager(wm); 1972 } 1973 1974 public void startObservingNativeCrashes() { 1975 final NativeCrashListener ncl = new NativeCrashListener(this); 1976 ncl.start(); 1977 } 1978 1979 public IAppOpsService getAppOpsService() { 1980 return mAppOpsService; 1981 } 1982 1983 static class MemBinder extends Binder { 1984 ActivityManagerService mActivityManagerService; 1985 MemBinder(ActivityManagerService activityManagerService) { 1986 mActivityManagerService = activityManagerService; 1987 } 1988 1989 @Override 1990 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1991 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1992 != PackageManager.PERMISSION_GRANTED) { 1993 pw.println("Permission Denial: can't dump meminfo from from pid=" 1994 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1995 + " without permission " + android.Manifest.permission.DUMP); 1996 return; 1997 } 1998 1999 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2000 } 2001 } 2002 2003 static class GraphicsBinder extends Binder { 2004 ActivityManagerService mActivityManagerService; 2005 GraphicsBinder(ActivityManagerService activityManagerService) { 2006 mActivityManagerService = activityManagerService; 2007 } 2008 2009 @Override 2010 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2011 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2012 != PackageManager.PERMISSION_GRANTED) { 2013 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2014 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2015 + " without permission " + android.Manifest.permission.DUMP); 2016 return; 2017 } 2018 2019 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2020 } 2021 } 2022 2023 static class DbBinder extends Binder { 2024 ActivityManagerService mActivityManagerService; 2025 DbBinder(ActivityManagerService activityManagerService) { 2026 mActivityManagerService = activityManagerService; 2027 } 2028 2029 @Override 2030 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2031 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2032 != PackageManager.PERMISSION_GRANTED) { 2033 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2034 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2035 + " without permission " + android.Manifest.permission.DUMP); 2036 return; 2037 } 2038 2039 mActivityManagerService.dumpDbInfo(fd, pw, args); 2040 } 2041 } 2042 2043 static class CpuBinder extends Binder { 2044 ActivityManagerService mActivityManagerService; 2045 CpuBinder(ActivityManagerService activityManagerService) { 2046 mActivityManagerService = activityManagerService; 2047 } 2048 2049 @Override 2050 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2051 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2052 != PackageManager.PERMISSION_GRANTED) { 2053 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2054 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2055 + " without permission " + android.Manifest.permission.DUMP); 2056 return; 2057 } 2058 2059 synchronized (mActivityManagerService.mProcessCpuThread) { 2060 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2061 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2062 SystemClock.uptimeMillis())); 2063 } 2064 } 2065 } 2066 2067 public static final class Lifecycle extends SystemService { 2068 private final ActivityManagerService mService; 2069 2070 public Lifecycle(Context context) { 2071 super(context); 2072 mService = new ActivityManagerService(context); 2073 } 2074 2075 @Override 2076 public void onStart() { 2077 mService.start(); 2078 } 2079 2080 public ActivityManagerService getService() { 2081 return mService; 2082 } 2083 } 2084 2085 // Note: This method is invoked on the main thread but may need to attach various 2086 // handlers to other threads. So take care to be explicit about the looper. 2087 public ActivityManagerService(Context systemContext) { 2088 mContext = systemContext; 2089 mFactoryTest = FactoryTest.getMode(); 2090 mSystemThread = ActivityThread.currentActivityThread(); 2091 2092 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2093 2094 mHandlerThread = new ServiceThread(TAG, 2095 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2096 mHandlerThread.start(); 2097 mHandler = new MainHandler(mHandlerThread.getLooper()); 2098 2099 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2100 "foreground", BROADCAST_FG_TIMEOUT, false); 2101 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2102 "background", BROADCAST_BG_TIMEOUT, true); 2103 mBroadcastQueues[0] = mFgBroadcastQueue; 2104 mBroadcastQueues[1] = mBgBroadcastQueue; 2105 2106 mServices = new ActiveServices(this); 2107 mProviderMap = new ProviderMap(this); 2108 2109 // TODO: Move creation of battery stats service outside of activity manager service. 2110 File dataDir = Environment.getDataDirectory(); 2111 File systemDir = new File(dataDir, "system"); 2112 systemDir.mkdirs(); 2113 mBatteryStatsService = new BatteryStatsService(new File( 2114 systemDir, "batterystats.bin").toString(), mHandler); 2115 mBatteryStatsService.getActiveStatistics().readLocked(); 2116 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2117 mOnBattery = DEBUG_POWER ? true 2118 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2119 mBatteryStatsService.getActiveStatistics().setCallback(this); 2120 2121 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2122 2123 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2124 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2125 2126 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2127 2128 // User 0 is the first and only user that runs at boot. 2129 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2130 mUserLru.add(Integer.valueOf(0)); 2131 updateStartedUserArrayLocked(); 2132 2133 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2134 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2135 2136 mConfiguration.setToDefaults(); 2137 mConfiguration.setLocale(Locale.getDefault()); 2138 2139 mConfigurationSeq = mConfiguration.seq = 1; 2140 mProcessCpuTracker.init(); 2141 2142 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2143 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2144 mStackSupervisor = new ActivityStackSupervisor(this); 2145 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2146 2147 mProcessCpuThread = new Thread("CpuTracker") { 2148 @Override 2149 public void run() { 2150 while (true) { 2151 try { 2152 try { 2153 synchronized(this) { 2154 final long now = SystemClock.uptimeMillis(); 2155 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2156 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2157 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2158 // + ", write delay=" + nextWriteDelay); 2159 if (nextWriteDelay < nextCpuDelay) { 2160 nextCpuDelay = nextWriteDelay; 2161 } 2162 if (nextCpuDelay > 0) { 2163 mProcessCpuMutexFree.set(true); 2164 this.wait(nextCpuDelay); 2165 } 2166 } 2167 } catch (InterruptedException e) { 2168 } 2169 updateCpuStatsNow(); 2170 } catch (Exception e) { 2171 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2172 } 2173 } 2174 } 2175 }; 2176 2177 Watchdog.getInstance().addMonitor(this); 2178 Watchdog.getInstance().addThread(mHandler); 2179 } 2180 2181 public void setSystemServiceManager(SystemServiceManager mgr) { 2182 mSystemServiceManager = mgr; 2183 } 2184 2185 private void start() { 2186 mProcessCpuThread.start(); 2187 2188 mBatteryStatsService.publish(mContext); 2189 mUsageStatsService.publish(mContext); 2190 mAppOpsService.publish(mContext); 2191 2192 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2193 } 2194 2195 @Override 2196 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2197 throws RemoteException { 2198 if (code == SYSPROPS_TRANSACTION) { 2199 // We need to tell all apps about the system property change. 2200 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2201 synchronized(this) { 2202 final int NP = mProcessNames.getMap().size(); 2203 for (int ip=0; ip<NP; ip++) { 2204 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2205 final int NA = apps.size(); 2206 for (int ia=0; ia<NA; ia++) { 2207 ProcessRecord app = apps.valueAt(ia); 2208 if (app.thread != null) { 2209 procs.add(app.thread.asBinder()); 2210 } 2211 } 2212 } 2213 } 2214 2215 int N = procs.size(); 2216 for (int i=0; i<N; i++) { 2217 Parcel data2 = Parcel.obtain(); 2218 try { 2219 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2220 } catch (RemoteException e) { 2221 } 2222 data2.recycle(); 2223 } 2224 } 2225 try { 2226 return super.onTransact(code, data, reply, flags); 2227 } catch (RuntimeException e) { 2228 // The activity manager only throws security exceptions, so let's 2229 // log all others. 2230 if (!(e instanceof SecurityException)) { 2231 Slog.wtf(TAG, "Activity Manager Crash", e); 2232 } 2233 throw e; 2234 } 2235 } 2236 2237 void updateCpuStats() { 2238 final long now = SystemClock.uptimeMillis(); 2239 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2240 return; 2241 } 2242 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2243 synchronized (mProcessCpuThread) { 2244 mProcessCpuThread.notify(); 2245 } 2246 } 2247 } 2248 2249 void updateCpuStatsNow() { 2250 synchronized (mProcessCpuThread) { 2251 mProcessCpuMutexFree.set(false); 2252 final long now = SystemClock.uptimeMillis(); 2253 boolean haveNewCpuStats = false; 2254 2255 if (MONITOR_CPU_USAGE && 2256 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2257 mLastCpuTime.set(now); 2258 haveNewCpuStats = true; 2259 mProcessCpuTracker.update(); 2260 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2261 //Slog.i(TAG, "Total CPU usage: " 2262 // + mProcessCpu.getTotalCpuPercent() + "%"); 2263 2264 // Slog the cpu usage if the property is set. 2265 if ("true".equals(SystemProperties.get("events.cpu"))) { 2266 int user = mProcessCpuTracker.getLastUserTime(); 2267 int system = mProcessCpuTracker.getLastSystemTime(); 2268 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2269 int irq = mProcessCpuTracker.getLastIrqTime(); 2270 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2271 int idle = mProcessCpuTracker.getLastIdleTime(); 2272 2273 int total = user + system + iowait + irq + softIrq + idle; 2274 if (total == 0) total = 1; 2275 2276 EventLog.writeEvent(EventLogTags.CPU, 2277 ((user+system+iowait+irq+softIrq) * 100) / total, 2278 (user * 100) / total, 2279 (system * 100) / total, 2280 (iowait * 100) / total, 2281 (irq * 100) / total, 2282 (softIrq * 100) / total); 2283 } 2284 } 2285 2286 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2287 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2288 synchronized(bstats) { 2289 synchronized(mPidsSelfLocked) { 2290 if (haveNewCpuStats) { 2291 if (mOnBattery) { 2292 int perc = bstats.startAddingCpuLocked(); 2293 int totalUTime = 0; 2294 int totalSTime = 0; 2295 final int N = mProcessCpuTracker.countStats(); 2296 for (int i=0; i<N; i++) { 2297 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2298 if (!st.working) { 2299 continue; 2300 } 2301 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2302 int otherUTime = (st.rel_utime*perc)/100; 2303 int otherSTime = (st.rel_stime*perc)/100; 2304 totalUTime += otherUTime; 2305 totalSTime += otherSTime; 2306 if (pr != null) { 2307 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2308 if (ps == null || !ps.isActive()) { 2309 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2310 pr.info.uid, pr.processName); 2311 } 2312 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2313 st.rel_stime-otherSTime); 2314 ps.addSpeedStepTimes(cpuSpeedTimes); 2315 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2316 } else { 2317 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2318 if (ps == null || !ps.isActive()) { 2319 st.batteryStats = ps = bstats.getProcessStatsLocked( 2320 bstats.mapUid(st.uid), st.name); 2321 } 2322 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2323 st.rel_stime-otherSTime); 2324 ps.addSpeedStepTimes(cpuSpeedTimes); 2325 } 2326 } 2327 bstats.finishAddingCpuLocked(perc, totalUTime, 2328 totalSTime, cpuSpeedTimes); 2329 } 2330 } 2331 } 2332 2333 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2334 mLastWriteTime = now; 2335 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2336 } 2337 } 2338 } 2339 } 2340 2341 @Override 2342 public void batteryNeedsCpuUpdate() { 2343 updateCpuStatsNow(); 2344 } 2345 2346 @Override 2347 public void batteryPowerChanged(boolean onBattery) { 2348 // When plugging in, update the CPU stats first before changing 2349 // the plug state. 2350 updateCpuStatsNow(); 2351 synchronized (this) { 2352 synchronized(mPidsSelfLocked) { 2353 mOnBattery = DEBUG_POWER ? true : onBattery; 2354 } 2355 } 2356 } 2357 2358 /** 2359 * Initialize the application bind args. These are passed to each 2360 * process when the bindApplication() IPC is sent to the process. They're 2361 * lazily setup to make sure the services are running when they're asked for. 2362 */ 2363 private HashMap<String, IBinder> getCommonServicesLocked() { 2364 if (mAppBindArgs == null) { 2365 mAppBindArgs = new HashMap<String, IBinder>(); 2366 2367 // Setup the application init args 2368 mAppBindArgs.put("package", ServiceManager.getService("package")); 2369 mAppBindArgs.put("window", ServiceManager.getService("window")); 2370 mAppBindArgs.put(Context.ALARM_SERVICE, 2371 ServiceManager.getService(Context.ALARM_SERVICE)); 2372 } 2373 return mAppBindArgs; 2374 } 2375 2376 final void setFocusedActivityLocked(ActivityRecord r) { 2377 if (mFocusedActivity != r) { 2378 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2379 mFocusedActivity = r; 2380 if (r.task != null && r.task.voiceInteractor != null) { 2381 startRunningVoiceLocked(); 2382 } else { 2383 finishRunningVoiceLocked(); 2384 } 2385 mStackSupervisor.setFocusedStack(r); 2386 if (r != null) { 2387 mWindowManager.setFocusedApp(r.appToken, true); 2388 } 2389 applyUpdateLockStateLocked(r); 2390 } 2391 } 2392 2393 final void clearFocusedActivity(ActivityRecord r) { 2394 if (mFocusedActivity == r) { 2395 mFocusedActivity = null; 2396 } 2397 } 2398 2399 @Override 2400 public void setFocusedStack(int stackId) { 2401 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2402 synchronized (ActivityManagerService.this) { 2403 ActivityStack stack = mStackSupervisor.getStack(stackId); 2404 if (stack != null) { 2405 ActivityRecord r = stack.topRunningActivityLocked(null); 2406 if (r != null) { 2407 setFocusedActivityLocked(r); 2408 } 2409 } 2410 } 2411 } 2412 2413 @Override 2414 public void notifyActivityDrawn(IBinder token) { 2415 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2416 synchronized (this) { 2417 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2418 if (r != null) { 2419 r.task.stack.notifyActivityDrawnLocked(r); 2420 } 2421 } 2422 } 2423 2424 final void applyUpdateLockStateLocked(ActivityRecord r) { 2425 // Modifications to the UpdateLock state are done on our handler, outside 2426 // the activity manager's locks. The new state is determined based on the 2427 // state *now* of the relevant activity record. The object is passed to 2428 // the handler solely for logging detail, not to be consulted/modified. 2429 final boolean nextState = r != null && r.immersive; 2430 mHandler.sendMessage( 2431 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2432 } 2433 2434 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2435 Message msg = Message.obtain(); 2436 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2437 msg.obj = r.task.askedCompatMode ? null : r; 2438 mHandler.sendMessage(msg); 2439 } 2440 2441 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2442 String what, Object obj, ProcessRecord srcApp) { 2443 app.lastActivityTime = now; 2444 2445 if (app.activities.size() > 0) { 2446 // Don't want to touch dependent processes that are hosting activities. 2447 return index; 2448 } 2449 2450 int lrui = mLruProcesses.lastIndexOf(app); 2451 if (lrui < 0) { 2452 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2453 + what + " " + obj + " from " + srcApp); 2454 return index; 2455 } 2456 2457 if (lrui >= index) { 2458 // Don't want to cause this to move dependent processes *back* in the 2459 // list as if they were less frequently used. 2460 return index; 2461 } 2462 2463 if (lrui >= mLruProcessActivityStart) { 2464 // Don't want to touch dependent processes that are hosting activities. 2465 return index; 2466 } 2467 2468 mLruProcesses.remove(lrui); 2469 if (index > 0) { 2470 index--; 2471 } 2472 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2473 + " in LRU list: " + app); 2474 mLruProcesses.add(index, app); 2475 return index; 2476 } 2477 2478 final void removeLruProcessLocked(ProcessRecord app) { 2479 int lrui = mLruProcesses.lastIndexOf(app); 2480 if (lrui >= 0) { 2481 if (lrui <= mLruProcessActivityStart) { 2482 mLruProcessActivityStart--; 2483 } 2484 if (lrui <= mLruProcessServiceStart) { 2485 mLruProcessServiceStart--; 2486 } 2487 mLruProcesses.remove(lrui); 2488 } 2489 } 2490 2491 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2492 ProcessRecord client) { 2493 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2494 || app.treatLikeActivity; 2495 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2496 if (!activityChange && hasActivity) { 2497 // The process has activities, so we are only allowing activity-based adjustments 2498 // to move it. It should be kept in the front of the list with other 2499 // processes that have activities, and we don't want those to change their 2500 // order except due to activity operations. 2501 return; 2502 } 2503 2504 mLruSeq++; 2505 final long now = SystemClock.uptimeMillis(); 2506 app.lastActivityTime = now; 2507 2508 // First a quick reject: if the app is already at the position we will 2509 // put it, then there is nothing to do. 2510 if (hasActivity) { 2511 final int N = mLruProcesses.size(); 2512 if (N > 0 && mLruProcesses.get(N-1) == app) { 2513 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2514 return; 2515 } 2516 } else { 2517 if (mLruProcessServiceStart > 0 2518 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2519 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2520 return; 2521 } 2522 } 2523 2524 int lrui = mLruProcesses.lastIndexOf(app); 2525 2526 if (app.persistent && lrui >= 0) { 2527 // We don't care about the position of persistent processes, as long as 2528 // they are in the list. 2529 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2530 return; 2531 } 2532 2533 /* In progress: compute new position first, so we can avoid doing work 2534 if the process is not actually going to move. Not yet working. 2535 int addIndex; 2536 int nextIndex; 2537 boolean inActivity = false, inService = false; 2538 if (hasActivity) { 2539 // Process has activities, put it at the very tipsy-top. 2540 addIndex = mLruProcesses.size(); 2541 nextIndex = mLruProcessServiceStart; 2542 inActivity = true; 2543 } else if (hasService) { 2544 // Process has services, put it at the top of the service list. 2545 addIndex = mLruProcessActivityStart; 2546 nextIndex = mLruProcessServiceStart; 2547 inActivity = true; 2548 inService = true; 2549 } else { 2550 // Process not otherwise of interest, it goes to the top of the non-service area. 2551 addIndex = mLruProcessServiceStart; 2552 if (client != null) { 2553 int clientIndex = mLruProcesses.lastIndexOf(client); 2554 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2555 + app); 2556 if (clientIndex >= 0 && addIndex > clientIndex) { 2557 addIndex = clientIndex; 2558 } 2559 } 2560 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2561 } 2562 2563 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2564 + mLruProcessActivityStart + "): " + app); 2565 */ 2566 2567 if (lrui >= 0) { 2568 if (lrui < mLruProcessActivityStart) { 2569 mLruProcessActivityStart--; 2570 } 2571 if (lrui < mLruProcessServiceStart) { 2572 mLruProcessServiceStart--; 2573 } 2574 /* 2575 if (addIndex > lrui) { 2576 addIndex--; 2577 } 2578 if (nextIndex > lrui) { 2579 nextIndex--; 2580 } 2581 */ 2582 mLruProcesses.remove(lrui); 2583 } 2584 2585 /* 2586 mLruProcesses.add(addIndex, app); 2587 if (inActivity) { 2588 mLruProcessActivityStart++; 2589 } 2590 if (inService) { 2591 mLruProcessActivityStart++; 2592 } 2593 */ 2594 2595 int nextIndex; 2596 if (hasActivity) { 2597 final int N = mLruProcesses.size(); 2598 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2599 // Process doesn't have activities, but has clients with 2600 // activities... move it up, but one below the top (the top 2601 // should always have a real activity). 2602 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2603 mLruProcesses.add(N-1, app); 2604 // To keep it from spamming the LRU list (by making a bunch of clients), 2605 // we will push down any other entries owned by the app. 2606 final int uid = app.info.uid; 2607 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2608 ProcessRecord subProc = mLruProcesses.get(i); 2609 if (subProc.info.uid == uid) { 2610 // We want to push this one down the list. If the process after 2611 // it is for the same uid, however, don't do so, because we don't 2612 // want them internally to be re-ordered. 2613 if (mLruProcesses.get(i-1).info.uid != uid) { 2614 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2615 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2616 ProcessRecord tmp = mLruProcesses.get(i); 2617 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2618 mLruProcesses.set(i-1, tmp); 2619 i--; 2620 } 2621 } else { 2622 // A gap, we can stop here. 2623 break; 2624 } 2625 } 2626 } else { 2627 // Process has activities, put it at the very tipsy-top. 2628 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2629 mLruProcesses.add(app); 2630 } 2631 nextIndex = mLruProcessServiceStart; 2632 } else if (hasService) { 2633 // Process has services, put it at the top of the service list. 2634 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2635 mLruProcesses.add(mLruProcessActivityStart, app); 2636 nextIndex = mLruProcessServiceStart; 2637 mLruProcessActivityStart++; 2638 } else { 2639 // Process not otherwise of interest, it goes to the top of the non-service area. 2640 int index = mLruProcessServiceStart; 2641 if (client != null) { 2642 // If there is a client, don't allow the process to be moved up higher 2643 // in the list than that client. 2644 int clientIndex = mLruProcesses.lastIndexOf(client); 2645 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2646 + " when updating " + app); 2647 if (clientIndex <= lrui) { 2648 // Don't allow the client index restriction to push it down farther in the 2649 // list than it already is. 2650 clientIndex = lrui; 2651 } 2652 if (clientIndex >= 0 && index > clientIndex) { 2653 index = clientIndex; 2654 } 2655 } 2656 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2657 mLruProcesses.add(index, app); 2658 nextIndex = index-1; 2659 mLruProcessActivityStart++; 2660 mLruProcessServiceStart++; 2661 } 2662 2663 // If the app is currently using a content provider or service, 2664 // bump those processes as well. 2665 for (int j=app.connections.size()-1; j>=0; j--) { 2666 ConnectionRecord cr = app.connections.valueAt(j); 2667 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2668 && cr.binding.service.app != null 2669 && cr.binding.service.app.lruSeq != mLruSeq 2670 && !cr.binding.service.app.persistent) { 2671 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2672 "service connection", cr, app); 2673 } 2674 } 2675 for (int j=app.conProviders.size()-1; j>=0; j--) { 2676 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2677 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2678 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2679 "provider reference", cpr, app); 2680 } 2681 } 2682 } 2683 2684 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2685 if (uid == Process.SYSTEM_UID) { 2686 // The system gets to run in any process. If there are multiple 2687 // processes with the same uid, just pick the first (this 2688 // should never happen). 2689 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2690 if (procs == null) return null; 2691 final int N = procs.size(); 2692 for (int i = 0; i < N; i++) { 2693 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2694 } 2695 } 2696 ProcessRecord proc = mProcessNames.get(processName, uid); 2697 if (false && proc != null && !keepIfLarge 2698 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2699 && proc.lastCachedPss >= 4000) { 2700 // Turn this condition on to cause killing to happen regularly, for testing. 2701 if (proc.baseProcessTracker != null) { 2702 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2703 } 2704 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2705 + "k from cached"); 2706 } else if (proc != null && !keepIfLarge 2707 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2708 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2709 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2710 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2711 if (proc.baseProcessTracker != null) { 2712 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2713 } 2714 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2715 + "k from cached"); 2716 } 2717 } 2718 return proc; 2719 } 2720 2721 void ensurePackageDexOpt(String packageName) { 2722 IPackageManager pm = AppGlobals.getPackageManager(); 2723 try { 2724 if (pm.performDexOpt(packageName)) { 2725 mDidDexOpt = true; 2726 } 2727 } catch (RemoteException e) { 2728 } 2729 } 2730 2731 boolean isNextTransitionForward() { 2732 int transit = mWindowManager.getPendingAppTransition(); 2733 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2734 || transit == AppTransition.TRANSIT_TASK_OPEN 2735 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2736 } 2737 2738 final ProcessRecord startProcessLocked(String processName, 2739 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2740 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2741 boolean isolated, boolean keepIfLarge) { 2742 ProcessRecord app; 2743 if (!isolated) { 2744 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2745 } else { 2746 // If this is an isolated process, it can't re-use an existing process. 2747 app = null; 2748 } 2749 // We don't have to do anything more if: 2750 // (1) There is an existing application record; and 2751 // (2) The caller doesn't think it is dead, OR there is no thread 2752 // object attached to it so we know it couldn't have crashed; and 2753 // (3) There is a pid assigned to it, so it is either starting or 2754 // already running. 2755 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2756 + " app=" + app + " knownToBeDead=" + knownToBeDead 2757 + " thread=" + (app != null ? app.thread : null) 2758 + " pid=" + (app != null ? app.pid : -1)); 2759 if (app != null && app.pid > 0) { 2760 if (!knownToBeDead || app.thread == null) { 2761 // We already have the app running, or are waiting for it to 2762 // come up (we have a pid but not yet its thread), so keep it. 2763 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2764 // If this is a new package in the process, add the package to the list 2765 app.addPackage(info.packageName, mProcessStats); 2766 return app; 2767 } 2768 2769 // An application record is attached to a previous process, 2770 // clean it up now. 2771 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2772 handleAppDiedLocked(app, true, true); 2773 } 2774 2775 String hostingNameStr = hostingName != null 2776 ? hostingName.flattenToShortString() : null; 2777 2778 if (!isolated) { 2779 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2780 // If we are in the background, then check to see if this process 2781 // is bad. If so, we will just silently fail. 2782 if (mBadProcesses.get(info.processName, info.uid) != null) { 2783 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2784 + "/" + info.processName); 2785 return null; 2786 } 2787 } else { 2788 // When the user is explicitly starting a process, then clear its 2789 // crash count so that we won't make it bad until they see at 2790 // least one crash dialog again, and make the process good again 2791 // if it had been bad. 2792 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2793 + "/" + info.processName); 2794 mProcessCrashTimes.remove(info.processName, info.uid); 2795 if (mBadProcesses.get(info.processName, info.uid) != null) { 2796 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2797 UserHandle.getUserId(info.uid), info.uid, 2798 info.processName); 2799 mBadProcesses.remove(info.processName, info.uid); 2800 if (app != null) { 2801 app.bad = false; 2802 } 2803 } 2804 } 2805 } 2806 2807 if (app == null) { 2808 app = newProcessRecordLocked(info, processName, isolated); 2809 if (app == null) { 2810 Slog.w(TAG, "Failed making new process record for " 2811 + processName + "/" + info.uid + " isolated=" + isolated); 2812 return null; 2813 } 2814 mProcessNames.put(processName, app.uid, app); 2815 if (isolated) { 2816 mIsolatedProcesses.put(app.uid, app); 2817 } 2818 } else { 2819 // If this is a new package in the process, add the package to the list 2820 app.addPackage(info.packageName, mProcessStats); 2821 } 2822 2823 // If the system is not ready yet, then hold off on starting this 2824 // process until it is. 2825 if (!mProcessesReady 2826 && !isAllowedWhileBooting(info) 2827 && !allowWhileBooting) { 2828 if (!mProcessesOnHold.contains(app)) { 2829 mProcessesOnHold.add(app); 2830 } 2831 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2832 return app; 2833 } 2834 2835 startProcessLocked(app, hostingType, hostingNameStr); 2836 return (app.pid != 0) ? app : null; 2837 } 2838 2839 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2840 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2841 } 2842 2843 private final void startProcessLocked(ProcessRecord app, 2844 String hostingType, String hostingNameStr) { 2845 if (app.pid > 0 && app.pid != MY_PID) { 2846 synchronized (mPidsSelfLocked) { 2847 mPidsSelfLocked.remove(app.pid); 2848 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2849 } 2850 app.setPid(0); 2851 } 2852 2853 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2854 "startProcessLocked removing on hold: " + app); 2855 mProcessesOnHold.remove(app); 2856 2857 updateCpuStats(); 2858 2859 try { 2860 int uid = app.uid; 2861 2862 int[] gids = null; 2863 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2864 if (!app.isolated) { 2865 int[] permGids = null; 2866 try { 2867 final PackageManager pm = mContext.getPackageManager(); 2868 permGids = pm.getPackageGids(app.info.packageName); 2869 2870 if (Environment.isExternalStorageEmulated()) { 2871 if (pm.checkPermission( 2872 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2873 app.info.packageName) == PERMISSION_GRANTED) { 2874 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2875 } else { 2876 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2877 } 2878 } 2879 } catch (PackageManager.NameNotFoundException e) { 2880 Slog.w(TAG, "Unable to retrieve gids", e); 2881 } 2882 2883 /* 2884 * Add shared application GID so applications can share some 2885 * resources like shared libraries 2886 */ 2887 if (permGids == null) { 2888 gids = new int[1]; 2889 } else { 2890 gids = new int[permGids.length + 1]; 2891 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2892 } 2893 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2894 } 2895 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2896 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2897 && mTopComponent != null 2898 && app.processName.equals(mTopComponent.getPackageName())) { 2899 uid = 0; 2900 } 2901 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2902 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2903 uid = 0; 2904 } 2905 } 2906 int debugFlags = 0; 2907 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2908 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2909 // Also turn on CheckJNI for debuggable apps. It's quite 2910 // awkward to turn on otherwise. 2911 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2912 } 2913 // Run the app in safe mode if its manifest requests so or the 2914 // system is booted in safe mode. 2915 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2916 mSafeMode == true) { 2917 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2918 } 2919 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2920 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2921 } 2922 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2923 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2924 } 2925 if ("1".equals(SystemProperties.get("debug.assert"))) { 2926 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2927 } 2928 2929 String requiredAbi = app.info.cpuAbi; 2930 if (requiredAbi == null) { 2931 requiredAbi = Build.SUPPORTED_ABIS[0]; 2932 } 2933 2934 // Start the process. It will either succeed and return a result containing 2935 // the PID of the new process, or else throw a RuntimeException. 2936 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2937 app.processName, uid, uid, gids, debugFlags, mountExternal, 2938 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2939 2940 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2941 synchronized (bs) { 2942 if (bs.isOnBattery()) { 2943 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2944 } 2945 } 2946 2947 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2948 UserHandle.getUserId(uid), startResult.pid, uid, 2949 app.processName, hostingType, 2950 hostingNameStr != null ? hostingNameStr : ""); 2951 2952 if (app.persistent) { 2953 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2954 } 2955 2956 StringBuilder buf = mStringBuilder; 2957 buf.setLength(0); 2958 buf.append("Start proc "); 2959 buf.append(app.processName); 2960 buf.append(" for "); 2961 buf.append(hostingType); 2962 if (hostingNameStr != null) { 2963 buf.append(" "); 2964 buf.append(hostingNameStr); 2965 } 2966 buf.append(": pid="); 2967 buf.append(startResult.pid); 2968 buf.append(" uid="); 2969 buf.append(uid); 2970 buf.append(" gids={"); 2971 if (gids != null) { 2972 for (int gi=0; gi<gids.length; gi++) { 2973 if (gi != 0) buf.append(", "); 2974 buf.append(gids[gi]); 2975 2976 } 2977 } 2978 buf.append("}"); 2979 Slog.i(TAG, buf.toString()); 2980 app.setPid(startResult.pid); 2981 app.usingWrapper = startResult.usingWrapper; 2982 app.removed = false; 2983 synchronized (mPidsSelfLocked) { 2984 this.mPidsSelfLocked.put(startResult.pid, app); 2985 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2986 msg.obj = app; 2987 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2988 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2989 } 2990 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2991 app.processName, app.info.uid); 2992 if (app.isolated) { 2993 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2994 } 2995 } catch (RuntimeException e) { 2996 // XXX do better error recovery. 2997 app.setPid(0); 2998 Slog.e(TAG, "Failure starting process " + app.processName, e); 2999 } 3000 } 3001 3002 void updateUsageStats(ActivityRecord component, boolean resumed) { 3003 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3004 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3005 if (resumed) { 3006 mUsageStatsService.noteResumeComponent(component.realActivity); 3007 synchronized (stats) { 3008 stats.noteActivityResumedLocked(component.app.uid); 3009 } 3010 } else { 3011 mUsageStatsService.notePauseComponent(component.realActivity); 3012 synchronized (stats) { 3013 stats.noteActivityPausedLocked(component.app.uid); 3014 } 3015 } 3016 } 3017 3018 Intent getHomeIntent() { 3019 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3020 intent.setComponent(mTopComponent); 3021 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3022 intent.addCategory(Intent.CATEGORY_HOME); 3023 } 3024 return intent; 3025 } 3026 3027 boolean startHomeActivityLocked(int userId) { 3028 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3029 && mTopAction == null) { 3030 // We are running in factory test mode, but unable to find 3031 // the factory test app, so just sit around displaying the 3032 // error message and don't try to start anything. 3033 return false; 3034 } 3035 Intent intent = getHomeIntent(); 3036 ActivityInfo aInfo = 3037 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3038 if (aInfo != null) { 3039 intent.setComponent(new ComponentName( 3040 aInfo.applicationInfo.packageName, aInfo.name)); 3041 // Don't do this if the home app is currently being 3042 // instrumented. 3043 aInfo = new ActivityInfo(aInfo); 3044 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3045 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3046 aInfo.applicationInfo.uid, true); 3047 if (app == null || app.instrumentationClass == null) { 3048 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3049 mStackSupervisor.startHomeActivity(intent, aInfo); 3050 } 3051 } 3052 3053 return true; 3054 } 3055 3056 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3057 ActivityInfo ai = null; 3058 ComponentName comp = intent.getComponent(); 3059 try { 3060 if (comp != null) { 3061 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3062 } else { 3063 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3064 intent, 3065 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3066 flags, userId); 3067 3068 if (info != null) { 3069 ai = info.activityInfo; 3070 } 3071 } 3072 } catch (RemoteException e) { 3073 // ignore 3074 } 3075 3076 return ai; 3077 } 3078 3079 /** 3080 * Starts the "new version setup screen" if appropriate. 3081 */ 3082 void startSetupActivityLocked() { 3083 // Only do this once per boot. 3084 if (mCheckedForSetup) { 3085 return; 3086 } 3087 3088 // We will show this screen if the current one is a different 3089 // version than the last one shown, and we are not running in 3090 // low-level factory test mode. 3091 final ContentResolver resolver = mContext.getContentResolver(); 3092 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3093 Settings.Global.getInt(resolver, 3094 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3095 mCheckedForSetup = true; 3096 3097 // See if we should be showing the platform update setup UI. 3098 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3099 List<ResolveInfo> ris = mContext.getPackageManager() 3100 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3101 3102 // We don't allow third party apps to replace this. 3103 ResolveInfo ri = null; 3104 for (int i=0; ris != null && i<ris.size(); i++) { 3105 if ((ris.get(i).activityInfo.applicationInfo.flags 3106 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3107 ri = ris.get(i); 3108 break; 3109 } 3110 } 3111 3112 if (ri != null) { 3113 String vers = ri.activityInfo.metaData != null 3114 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3115 : null; 3116 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3117 vers = ri.activityInfo.applicationInfo.metaData.getString( 3118 Intent.METADATA_SETUP_VERSION); 3119 } 3120 String lastVers = Settings.Secure.getString( 3121 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3122 if (vers != null && !vers.equals(lastVers)) { 3123 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3124 intent.setComponent(new ComponentName( 3125 ri.activityInfo.packageName, ri.activityInfo.name)); 3126 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3127 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3128 } 3129 } 3130 } 3131 } 3132 3133 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3134 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3135 } 3136 3137 void enforceNotIsolatedCaller(String caller) { 3138 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3139 throw new SecurityException("Isolated process not allowed to call " + caller); 3140 } 3141 } 3142 3143 @Override 3144 public int getFrontActivityScreenCompatMode() { 3145 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3146 synchronized (this) { 3147 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3148 } 3149 } 3150 3151 @Override 3152 public void setFrontActivityScreenCompatMode(int mode) { 3153 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3154 "setFrontActivityScreenCompatMode"); 3155 synchronized (this) { 3156 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3157 } 3158 } 3159 3160 @Override 3161 public int getPackageScreenCompatMode(String packageName) { 3162 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3163 synchronized (this) { 3164 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3165 } 3166 } 3167 3168 @Override 3169 public void setPackageScreenCompatMode(String packageName, int mode) { 3170 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3171 "setPackageScreenCompatMode"); 3172 synchronized (this) { 3173 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3174 } 3175 } 3176 3177 @Override 3178 public boolean getPackageAskScreenCompat(String packageName) { 3179 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3180 synchronized (this) { 3181 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3182 } 3183 } 3184 3185 @Override 3186 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3187 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3188 "setPackageAskScreenCompat"); 3189 synchronized (this) { 3190 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3191 } 3192 } 3193 3194 private void dispatchProcessesChanged() { 3195 int N; 3196 synchronized (this) { 3197 N = mPendingProcessChanges.size(); 3198 if (mActiveProcessChanges.length < N) { 3199 mActiveProcessChanges = new ProcessChangeItem[N]; 3200 } 3201 mPendingProcessChanges.toArray(mActiveProcessChanges); 3202 mAvailProcessChanges.addAll(mPendingProcessChanges); 3203 mPendingProcessChanges.clear(); 3204 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3205 } 3206 3207 int i = mProcessObservers.beginBroadcast(); 3208 while (i > 0) { 3209 i--; 3210 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3211 if (observer != null) { 3212 try { 3213 for (int j=0; j<N; j++) { 3214 ProcessChangeItem item = mActiveProcessChanges[j]; 3215 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3216 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3217 + item.pid + " uid=" + item.uid + ": " 3218 + item.foregroundActivities); 3219 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3220 item.foregroundActivities); 3221 } 3222 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3223 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3224 + item.pid + " uid=" + item.uid + ": " + item.processState); 3225 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3226 } 3227 } 3228 } catch (RemoteException e) { 3229 } 3230 } 3231 } 3232 mProcessObservers.finishBroadcast(); 3233 } 3234 3235 private void dispatchProcessDied(int pid, int uid) { 3236 int i = mProcessObservers.beginBroadcast(); 3237 while (i > 0) { 3238 i--; 3239 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3240 if (observer != null) { 3241 try { 3242 observer.onProcessDied(pid, uid); 3243 } catch (RemoteException e) { 3244 } 3245 } 3246 } 3247 mProcessObservers.finishBroadcast(); 3248 } 3249 3250 final void doPendingActivityLaunchesLocked(boolean doResume) { 3251 final int N = mPendingActivityLaunches.size(); 3252 if (N <= 0) { 3253 return; 3254 } 3255 for (int i=0; i<N; i++) { 3256 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3257 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3258 doResume && i == (N-1), null); 3259 } 3260 mPendingActivityLaunches.clear(); 3261 } 3262 3263 @Override 3264 public final int startActivity(IApplicationThread caller, String callingPackage, 3265 Intent intent, String resolvedType, IBinder resultTo, 3266 String resultWho, int requestCode, int startFlags, 3267 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3268 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3269 resultWho, requestCode, 3270 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3271 } 3272 3273 @Override 3274 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3275 Intent intent, String resolvedType, IBinder resultTo, 3276 String resultWho, int requestCode, int startFlags, 3277 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3278 enforceNotIsolatedCaller("startActivity"); 3279 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3280 false, true, "startActivity", null); 3281 // TODO: Switch to user app stacks here. 3282 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3283 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3284 null, null, options, userId, null); 3285 } 3286 3287 @Override 3288 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3289 Intent intent, String resolvedType, IBinder resultTo, 3290 String resultWho, int requestCode, int startFlags, String profileFile, 3291 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3292 enforceNotIsolatedCaller("startActivityAndWait"); 3293 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3294 false, true, "startActivityAndWait", null); 3295 WaitResult res = new WaitResult(); 3296 // TODO: Switch to user app stacks here. 3297 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3298 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3299 res, null, options, UserHandle.getCallingUserId(), null); 3300 return res; 3301 } 3302 3303 @Override 3304 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3305 Intent intent, String resolvedType, IBinder resultTo, 3306 String resultWho, int requestCode, int startFlags, Configuration config, 3307 Bundle options, int userId) { 3308 enforceNotIsolatedCaller("startActivityWithConfig"); 3309 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3310 false, true, "startActivityWithConfig", null); 3311 // TODO: Switch to user app stacks here. 3312 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3313 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3314 null, null, null, config, options, userId, null); 3315 return ret; 3316 } 3317 3318 @Override 3319 public int startActivityIntentSender(IApplicationThread caller, 3320 IntentSender intent, Intent fillInIntent, String resolvedType, 3321 IBinder resultTo, String resultWho, int requestCode, 3322 int flagsMask, int flagsValues, Bundle options) { 3323 enforceNotIsolatedCaller("startActivityIntentSender"); 3324 // Refuse possible leaked file descriptors 3325 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3326 throw new IllegalArgumentException("File descriptors passed in Intent"); 3327 } 3328 3329 IIntentSender sender = intent.getTarget(); 3330 if (!(sender instanceof PendingIntentRecord)) { 3331 throw new IllegalArgumentException("Bad PendingIntent object"); 3332 } 3333 3334 PendingIntentRecord pir = (PendingIntentRecord)sender; 3335 3336 synchronized (this) { 3337 // If this is coming from the currently resumed activity, it is 3338 // effectively saying that app switches are allowed at this point. 3339 final ActivityStack stack = getFocusedStack(); 3340 if (stack.mResumedActivity != null && 3341 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3342 mAppSwitchesAllowedTime = 0; 3343 } 3344 } 3345 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3346 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3347 return ret; 3348 } 3349 3350 @Override 3351 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3352 Intent intent, String resolvedType, IVoiceInteractionSession session, 3353 IVoiceInteractor interactor, int startFlags, String profileFile, 3354 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3355 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3356 != PackageManager.PERMISSION_GRANTED) { 3357 String msg = "Permission Denial: startVoiceActivity() from pid=" 3358 + Binder.getCallingPid() 3359 + ", uid=" + Binder.getCallingUid() 3360 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3361 Slog.w(TAG, msg); 3362 throw new SecurityException(msg); 3363 } 3364 if (session == null || interactor == null) { 3365 throw new NullPointerException("null session or interactor"); 3366 } 3367 userId = handleIncomingUser(callingPid, callingUid, userId, 3368 false, true, "startVoiceActivity", null); 3369 // TODO: Switch to user app stacks here. 3370 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3371 resolvedType, session, interactor, null, null, 0, startFlags, 3372 profileFile, profileFd, null, null, options, userId, null); 3373 } 3374 3375 @Override 3376 public boolean startNextMatchingActivity(IBinder callingActivity, 3377 Intent intent, Bundle options) { 3378 // Refuse possible leaked file descriptors 3379 if (intent != null && intent.hasFileDescriptors() == true) { 3380 throw new IllegalArgumentException("File descriptors passed in Intent"); 3381 } 3382 3383 synchronized (this) { 3384 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3385 if (r == null) { 3386 ActivityOptions.abort(options); 3387 return false; 3388 } 3389 if (r.app == null || r.app.thread == null) { 3390 // The caller is not running... d'oh! 3391 ActivityOptions.abort(options); 3392 return false; 3393 } 3394 intent = new Intent(intent); 3395 // The caller is not allowed to change the data. 3396 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3397 // And we are resetting to find the next component... 3398 intent.setComponent(null); 3399 3400 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3401 3402 ActivityInfo aInfo = null; 3403 try { 3404 List<ResolveInfo> resolves = 3405 AppGlobals.getPackageManager().queryIntentActivities( 3406 intent, r.resolvedType, 3407 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3408 UserHandle.getCallingUserId()); 3409 3410 // Look for the original activity in the list... 3411 final int N = resolves != null ? resolves.size() : 0; 3412 for (int i=0; i<N; i++) { 3413 ResolveInfo rInfo = resolves.get(i); 3414 if (rInfo.activityInfo.packageName.equals(r.packageName) 3415 && rInfo.activityInfo.name.equals(r.info.name)) { 3416 // We found the current one... the next matching is 3417 // after it. 3418 i++; 3419 if (i<N) { 3420 aInfo = resolves.get(i).activityInfo; 3421 } 3422 if (debug) { 3423 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3424 + "/" + r.info.name); 3425 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3426 + "/" + aInfo.name); 3427 } 3428 break; 3429 } 3430 } 3431 } catch (RemoteException e) { 3432 } 3433 3434 if (aInfo == null) { 3435 // Nobody who is next! 3436 ActivityOptions.abort(options); 3437 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3438 return false; 3439 } 3440 3441 intent.setComponent(new ComponentName( 3442 aInfo.applicationInfo.packageName, aInfo.name)); 3443 intent.setFlags(intent.getFlags()&~( 3444 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3445 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3446 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3447 Intent.FLAG_ACTIVITY_NEW_TASK)); 3448 3449 // Okay now we need to start the new activity, replacing the 3450 // currently running activity. This is a little tricky because 3451 // we want to start the new one as if the current one is finished, 3452 // but not finish the current one first so that there is no flicker. 3453 // And thus... 3454 final boolean wasFinishing = r.finishing; 3455 r.finishing = true; 3456 3457 // Propagate reply information over to the new activity. 3458 final ActivityRecord resultTo = r.resultTo; 3459 final String resultWho = r.resultWho; 3460 final int requestCode = r.requestCode; 3461 r.resultTo = null; 3462 if (resultTo != null) { 3463 resultTo.removeResultsLocked(r, resultWho, requestCode); 3464 } 3465 3466 final long origId = Binder.clearCallingIdentity(); 3467 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3468 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3469 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3470 options, false, null, null); 3471 Binder.restoreCallingIdentity(origId); 3472 3473 r.finishing = wasFinishing; 3474 if (res != ActivityManager.START_SUCCESS) { 3475 return false; 3476 } 3477 return true; 3478 } 3479 } 3480 3481 final int startActivityInPackage(int uid, String callingPackage, 3482 Intent intent, String resolvedType, IBinder resultTo, 3483 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3484 IActivityContainer container) { 3485 3486 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3487 false, true, "startActivityInPackage", null); 3488 3489 // TODO: Switch to user app stacks here. 3490 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3491 null, null, resultTo, resultWho, requestCode, startFlags, 3492 null, null, null, null, options, userId, container); 3493 return ret; 3494 } 3495 3496 @Override 3497 public final int startActivities(IApplicationThread caller, String callingPackage, 3498 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3499 int userId) { 3500 enforceNotIsolatedCaller("startActivities"); 3501 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3502 false, true, "startActivity", null); 3503 // TODO: Switch to user app stacks here. 3504 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3505 resolvedTypes, resultTo, options, userId); 3506 return ret; 3507 } 3508 3509 final int startActivitiesInPackage(int uid, String callingPackage, 3510 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3511 Bundle options, int userId) { 3512 3513 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3514 false, true, "startActivityInPackage", null); 3515 // TODO: Switch to user app stacks here. 3516 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3517 resultTo, options, userId); 3518 return ret; 3519 } 3520 3521 final void addRecentTaskLocked(TaskRecord task) { 3522 int N = mRecentTasks.size(); 3523 // Quick case: check if the top-most recent task is the same. 3524 if (N > 0 && mRecentTasks.get(0) == task) { 3525 return; 3526 } 3527 // Another quick case: never add voice sessions. 3528 if (task.voiceSession != null) { 3529 return; 3530 } 3531 // Remove any existing entries that are the same kind of task. 3532 final Intent intent = task.intent; 3533 final boolean document = intent != null && intent.isDocument(); 3534 for (int i=0; i<N; i++) { 3535 TaskRecord tr = mRecentTasks.get(i); 3536 if (task != tr) { 3537 if (task.userId != tr.userId) { 3538 continue; 3539 } 3540 final Intent trIntent = tr.intent; 3541 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3542 (intent == null || !intent.filterEquals(trIntent))) { 3543 continue; 3544 } 3545 if (document || trIntent != null && trIntent.isDocument()) { 3546 // Document tasks do not match other tasks. 3547 continue; 3548 } 3549 } 3550 3551 // Either task and tr are the same or, their affinities match or their intents match 3552 // and neither of them is a document. 3553 tr.disposeThumbnail(); 3554 mRecentTasks.remove(i); 3555 i--; 3556 N--; 3557 if (task.intent == null) { 3558 // If the new recent task we are adding is not fully 3559 // specified, then replace it with the existing recent task. 3560 task = tr; 3561 } 3562 } 3563 if (N >= MAX_RECENT_TASKS) { 3564 mRecentTasks.remove(N-1).disposeThumbnail(); 3565 } 3566 mRecentTasks.add(0, task); 3567 } 3568 3569 @Override 3570 public void reportActivityFullyDrawn(IBinder token) { 3571 synchronized (this) { 3572 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3573 if (r == null) { 3574 return; 3575 } 3576 r.reportFullyDrawnLocked(); 3577 } 3578 } 3579 3580 @Override 3581 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3582 synchronized (this) { 3583 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3584 if (r == null) { 3585 return; 3586 } 3587 final long origId = Binder.clearCallingIdentity(); 3588 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3589 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3590 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3591 if (config != null) { 3592 r.frozenBeforeDestroy = true; 3593 if (!updateConfigurationLocked(config, r, false, false)) { 3594 mStackSupervisor.resumeTopActivitiesLocked(); 3595 } 3596 } 3597 Binder.restoreCallingIdentity(origId); 3598 } 3599 } 3600 3601 @Override 3602 public int getRequestedOrientation(IBinder token) { 3603 synchronized (this) { 3604 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3605 if (r == null) { 3606 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3607 } 3608 return mWindowManager.getAppOrientation(r.appToken); 3609 } 3610 } 3611 3612 /** 3613 * This is the internal entry point for handling Activity.finish(). 3614 * 3615 * @param token The Binder token referencing the Activity we want to finish. 3616 * @param resultCode Result code, if any, from this Activity. 3617 * @param resultData Result data (Intent), if any, from this Activity. 3618 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3619 * the root Activity in the task. 3620 * 3621 * @return Returns true if the activity successfully finished, or false if it is still running. 3622 */ 3623 @Override 3624 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3625 boolean finishTask) { 3626 // Refuse possible leaked file descriptors 3627 if (resultData != null && resultData.hasFileDescriptors() == true) { 3628 throw new IllegalArgumentException("File descriptors passed in Intent"); 3629 } 3630 3631 synchronized(this) { 3632 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3633 if (r == null) { 3634 return true; 3635 } 3636 // Keep track of the root activity of the task before we finish it 3637 TaskRecord tr = r.task; 3638 ActivityRecord rootR = tr.getRootActivity(); 3639 if (mController != null) { 3640 // Find the first activity that is not finishing. 3641 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3642 if (next != null) { 3643 // ask watcher if this is allowed 3644 boolean resumeOK = true; 3645 try { 3646 resumeOK = mController.activityResuming(next.packageName); 3647 } catch (RemoteException e) { 3648 mController = null; 3649 Watchdog.getInstance().setActivityController(null); 3650 } 3651 3652 if (!resumeOK) { 3653 return false; 3654 } 3655 } 3656 } 3657 final long origId = Binder.clearCallingIdentity(); 3658 try { 3659 boolean res; 3660 if (finishTask && r == rootR) { 3661 // If requested, remove the task that is associated to this activity only if it 3662 // was the root activity in the task. The result code and data is ignored because 3663 // we don't support returning them across task boundaries. 3664 res = removeTaskByIdLocked(tr.taskId, 0); 3665 } else { 3666 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3667 resultData, "app-request", true); 3668 } 3669 return res; 3670 } finally { 3671 Binder.restoreCallingIdentity(origId); 3672 } 3673 } 3674 } 3675 3676 @Override 3677 public final void finishHeavyWeightApp() { 3678 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3679 != PackageManager.PERMISSION_GRANTED) { 3680 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3681 + Binder.getCallingPid() 3682 + ", uid=" + Binder.getCallingUid() 3683 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3684 Slog.w(TAG, msg); 3685 throw new SecurityException(msg); 3686 } 3687 3688 synchronized(this) { 3689 if (mHeavyWeightProcess == null) { 3690 return; 3691 } 3692 3693 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3694 mHeavyWeightProcess.activities); 3695 for (int i=0; i<activities.size(); i++) { 3696 ActivityRecord r = activities.get(i); 3697 if (!r.finishing) { 3698 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3699 null, "finish-heavy", true); 3700 } 3701 } 3702 3703 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3704 mHeavyWeightProcess.userId, 0)); 3705 mHeavyWeightProcess = null; 3706 } 3707 } 3708 3709 @Override 3710 public void crashApplication(int uid, int initialPid, String packageName, 3711 String message) { 3712 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3713 != PackageManager.PERMISSION_GRANTED) { 3714 String msg = "Permission Denial: crashApplication() from pid=" 3715 + Binder.getCallingPid() 3716 + ", uid=" + Binder.getCallingUid() 3717 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3718 Slog.w(TAG, msg); 3719 throw new SecurityException(msg); 3720 } 3721 3722 synchronized(this) { 3723 ProcessRecord proc = null; 3724 3725 // Figure out which process to kill. We don't trust that initialPid 3726 // still has any relation to current pids, so must scan through the 3727 // list. 3728 synchronized (mPidsSelfLocked) { 3729 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3730 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3731 if (p.uid != uid) { 3732 continue; 3733 } 3734 if (p.pid == initialPid) { 3735 proc = p; 3736 break; 3737 } 3738 if (p.pkgList.containsKey(packageName)) { 3739 proc = p; 3740 } 3741 } 3742 } 3743 3744 if (proc == null) { 3745 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3746 + " initialPid=" + initialPid 3747 + " packageName=" + packageName); 3748 return; 3749 } 3750 3751 if (proc.thread != null) { 3752 if (proc.pid == Process.myPid()) { 3753 Log.w(TAG, "crashApplication: trying to crash self!"); 3754 return; 3755 } 3756 long ident = Binder.clearCallingIdentity(); 3757 try { 3758 proc.thread.scheduleCrash(message); 3759 } catch (RemoteException e) { 3760 } 3761 Binder.restoreCallingIdentity(ident); 3762 } 3763 } 3764 } 3765 3766 @Override 3767 public final void finishSubActivity(IBinder token, String resultWho, 3768 int requestCode) { 3769 synchronized(this) { 3770 final long origId = Binder.clearCallingIdentity(); 3771 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3772 if (r != null) { 3773 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3774 } 3775 Binder.restoreCallingIdentity(origId); 3776 } 3777 } 3778 3779 @Override 3780 public boolean finishActivityAffinity(IBinder token) { 3781 synchronized(this) { 3782 final long origId = Binder.clearCallingIdentity(); 3783 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3784 boolean res = false; 3785 if (r != null) { 3786 res = r.task.stack.finishActivityAffinityLocked(r); 3787 } 3788 Binder.restoreCallingIdentity(origId); 3789 return res; 3790 } 3791 } 3792 3793 @Override 3794 public boolean willActivityBeVisible(IBinder token) { 3795 synchronized(this) { 3796 ActivityStack stack = ActivityRecord.getStackLocked(token); 3797 if (stack != null) { 3798 return stack.willActivityBeVisibleLocked(token); 3799 } 3800 return false; 3801 } 3802 } 3803 3804 @Override 3805 public void overridePendingTransition(IBinder token, String packageName, 3806 int enterAnim, int exitAnim) { 3807 synchronized(this) { 3808 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3809 if (self == null) { 3810 return; 3811 } 3812 3813 final long origId = Binder.clearCallingIdentity(); 3814 3815 if (self.state == ActivityState.RESUMED 3816 || self.state == ActivityState.PAUSING) { 3817 mWindowManager.overridePendingAppTransition(packageName, 3818 enterAnim, exitAnim, null); 3819 } 3820 3821 Binder.restoreCallingIdentity(origId); 3822 } 3823 } 3824 3825 /** 3826 * Main function for removing an existing process from the activity manager 3827 * as a result of that process going away. Clears out all connections 3828 * to the process. 3829 */ 3830 private final void handleAppDiedLocked(ProcessRecord app, 3831 boolean restarting, boolean allowRestart) { 3832 int pid = app.pid; 3833 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3834 if (!restarting) { 3835 removeLruProcessLocked(app); 3836 if (pid > 0) { 3837 ProcessList.remove(pid); 3838 } 3839 } 3840 3841 if (mProfileProc == app) { 3842 clearProfilerLocked(); 3843 } 3844 3845 // Remove this application's activities from active lists. 3846 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3847 3848 app.activities.clear(); 3849 3850 if (app.instrumentationClass != null) { 3851 Slog.w(TAG, "Crash of app " + app.processName 3852 + " running instrumentation " + app.instrumentationClass); 3853 Bundle info = new Bundle(); 3854 info.putString("shortMsg", "Process crashed."); 3855 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3856 } 3857 3858 if (!restarting) { 3859 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3860 // If there was nothing to resume, and we are not already 3861 // restarting this process, but there is a visible activity that 3862 // is hosted by the process... then make sure all visible 3863 // activities are running, taking care of restarting this 3864 // process. 3865 if (hasVisibleActivities) { 3866 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3867 } 3868 } 3869 } 3870 } 3871 3872 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3873 IBinder threadBinder = thread.asBinder(); 3874 // Find the application record. 3875 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3876 ProcessRecord rec = mLruProcesses.get(i); 3877 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3878 return i; 3879 } 3880 } 3881 return -1; 3882 } 3883 3884 final ProcessRecord getRecordForAppLocked( 3885 IApplicationThread thread) { 3886 if (thread == null) { 3887 return null; 3888 } 3889 3890 int appIndex = getLRURecordIndexForAppLocked(thread); 3891 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3892 } 3893 3894 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3895 // If there are no longer any background processes running, 3896 // and the app that died was not running instrumentation, 3897 // then tell everyone we are now low on memory. 3898 boolean haveBg = false; 3899 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3900 ProcessRecord rec = mLruProcesses.get(i); 3901 if (rec.thread != null 3902 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3903 haveBg = true; 3904 break; 3905 } 3906 } 3907 3908 if (!haveBg) { 3909 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3910 if (doReport) { 3911 long now = SystemClock.uptimeMillis(); 3912 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3913 doReport = false; 3914 } else { 3915 mLastMemUsageReportTime = now; 3916 } 3917 } 3918 final ArrayList<ProcessMemInfo> memInfos 3919 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3920 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3921 long now = SystemClock.uptimeMillis(); 3922 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3923 ProcessRecord rec = mLruProcesses.get(i); 3924 if (rec == dyingProc || rec.thread == null) { 3925 continue; 3926 } 3927 if (doReport) { 3928 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3929 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3930 } 3931 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3932 // The low memory report is overriding any current 3933 // state for a GC request. Make sure to do 3934 // heavy/important/visible/foreground processes first. 3935 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3936 rec.lastRequestedGc = 0; 3937 } else { 3938 rec.lastRequestedGc = rec.lastLowMemory; 3939 } 3940 rec.reportLowMemory = true; 3941 rec.lastLowMemory = now; 3942 mProcessesToGc.remove(rec); 3943 addProcessToGcListLocked(rec); 3944 } 3945 } 3946 if (doReport) { 3947 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3948 mHandler.sendMessage(msg); 3949 } 3950 scheduleAppGcsLocked(); 3951 } 3952 } 3953 3954 final void appDiedLocked(ProcessRecord app, int pid, 3955 IApplicationThread thread) { 3956 3957 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3958 synchronized (stats) { 3959 stats.noteProcessDiedLocked(app.info.uid, pid); 3960 } 3961 3962 // Clean up already done if the process has been re-started. 3963 if (app.pid == pid && app.thread != null && 3964 app.thread.asBinder() == thread.asBinder()) { 3965 boolean doLowMem = app.instrumentationClass == null; 3966 boolean doOomAdj = doLowMem; 3967 if (!app.killedByAm) { 3968 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3969 + ") has died."); 3970 mAllowLowerMemLevel = true; 3971 } else { 3972 // Note that we always want to do oom adj to update our state with the 3973 // new number of procs. 3974 mAllowLowerMemLevel = false; 3975 doLowMem = false; 3976 } 3977 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3978 if (DEBUG_CLEANUP) Slog.v( 3979 TAG, "Dying app: " + app + ", pid: " + pid 3980 + ", thread: " + thread.asBinder()); 3981 handleAppDiedLocked(app, false, true); 3982 3983 if (doOomAdj) { 3984 updateOomAdjLocked(); 3985 } 3986 if (doLowMem) { 3987 doLowMemReportIfNeededLocked(app); 3988 } 3989 } else if (app.pid != pid) { 3990 // A new process has already been started. 3991 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3992 + ") has died and restarted (pid " + app.pid + ")."); 3993 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3994 } else if (DEBUG_PROCESSES) { 3995 Slog.d(TAG, "Received spurious death notification for thread " 3996 + thread.asBinder()); 3997 } 3998 } 3999 4000 /** 4001 * If a stack trace dump file is configured, dump process stack traces. 4002 * @param clearTraces causes the dump file to be erased prior to the new 4003 * traces being written, if true; when false, the new traces will be 4004 * appended to any existing file content. 4005 * @param firstPids of dalvik VM processes to dump stack traces for first 4006 * @param lastPids of dalvik VM processes to dump stack traces for last 4007 * @param nativeProcs optional list of native process names to dump stack crawls 4008 * @return file containing stack traces, or null if no dump file is configured 4009 */ 4010 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4011 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4012 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4013 if (tracesPath == null || tracesPath.length() == 0) { 4014 return null; 4015 } 4016 4017 File tracesFile = new File(tracesPath); 4018 try { 4019 File tracesDir = tracesFile.getParentFile(); 4020 if (!tracesDir.exists()) { 4021 tracesFile.mkdirs(); 4022 if (!SELinux.restorecon(tracesDir)) { 4023 return null; 4024 } 4025 } 4026 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4027 4028 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4029 tracesFile.createNewFile(); 4030 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4031 } catch (IOException e) { 4032 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4033 return null; 4034 } 4035 4036 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4037 return tracesFile; 4038 } 4039 4040 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4041 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4042 // Use a FileObserver to detect when traces finish writing. 4043 // The order of traces is considered important to maintain for legibility. 4044 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4045 @Override 4046 public synchronized void onEvent(int event, String path) { notify(); } 4047 }; 4048 4049 try { 4050 observer.startWatching(); 4051 4052 // First collect all of the stacks of the most important pids. 4053 if (firstPids != null) { 4054 try { 4055 int num = firstPids.size(); 4056 for (int i = 0; i < num; i++) { 4057 synchronized (observer) { 4058 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4059 observer.wait(200); // Wait for write-close, give up after 200msec 4060 } 4061 } 4062 } catch (InterruptedException e) { 4063 Log.wtf(TAG, e); 4064 } 4065 } 4066 4067 // Next collect the stacks of the native pids 4068 if (nativeProcs != null) { 4069 int[] pids = Process.getPidsForCommands(nativeProcs); 4070 if (pids != null) { 4071 for (int pid : pids) { 4072 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4073 } 4074 } 4075 } 4076 4077 // Lastly, measure CPU usage. 4078 if (processCpuTracker != null) { 4079 processCpuTracker.init(); 4080 System.gc(); 4081 processCpuTracker.update(); 4082 try { 4083 synchronized (processCpuTracker) { 4084 processCpuTracker.wait(500); // measure over 1/2 second. 4085 } 4086 } catch (InterruptedException e) { 4087 } 4088 processCpuTracker.update(); 4089 4090 // We'll take the stack crawls of just the top apps using CPU. 4091 final int N = processCpuTracker.countWorkingStats(); 4092 int numProcs = 0; 4093 for (int i=0; i<N && numProcs<5; i++) { 4094 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4095 if (lastPids.indexOfKey(stats.pid) >= 0) { 4096 numProcs++; 4097 try { 4098 synchronized (observer) { 4099 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4100 observer.wait(200); // Wait for write-close, give up after 200msec 4101 } 4102 } catch (InterruptedException e) { 4103 Log.wtf(TAG, e); 4104 } 4105 4106 } 4107 } 4108 } 4109 } finally { 4110 observer.stopWatching(); 4111 } 4112 } 4113 4114 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4115 if (true || IS_USER_BUILD) { 4116 return; 4117 } 4118 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4119 if (tracesPath == null || tracesPath.length() == 0) { 4120 return; 4121 } 4122 4123 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4124 StrictMode.allowThreadDiskWrites(); 4125 try { 4126 final File tracesFile = new File(tracesPath); 4127 final File tracesDir = tracesFile.getParentFile(); 4128 final File tracesTmp = new File(tracesDir, "__tmp__"); 4129 try { 4130 if (!tracesDir.exists()) { 4131 tracesFile.mkdirs(); 4132 if (!SELinux.restorecon(tracesDir.getPath())) { 4133 return; 4134 } 4135 } 4136 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4137 4138 if (tracesFile.exists()) { 4139 tracesTmp.delete(); 4140 tracesFile.renameTo(tracesTmp); 4141 } 4142 StringBuilder sb = new StringBuilder(); 4143 Time tobj = new Time(); 4144 tobj.set(System.currentTimeMillis()); 4145 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4146 sb.append(": "); 4147 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4148 sb.append(" since "); 4149 sb.append(msg); 4150 FileOutputStream fos = new FileOutputStream(tracesFile); 4151 fos.write(sb.toString().getBytes()); 4152 if (app == null) { 4153 fos.write("\n*** No application process!".getBytes()); 4154 } 4155 fos.close(); 4156 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4157 } catch (IOException e) { 4158 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4159 return; 4160 } 4161 4162 if (app != null) { 4163 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4164 firstPids.add(app.pid); 4165 dumpStackTraces(tracesPath, firstPids, null, null, null); 4166 } 4167 4168 File lastTracesFile = null; 4169 File curTracesFile = null; 4170 for (int i=9; i>=0; i--) { 4171 String name = String.format(Locale.US, "slow%02d.txt", i); 4172 curTracesFile = new File(tracesDir, name); 4173 if (curTracesFile.exists()) { 4174 if (lastTracesFile != null) { 4175 curTracesFile.renameTo(lastTracesFile); 4176 } else { 4177 curTracesFile.delete(); 4178 } 4179 } 4180 lastTracesFile = curTracesFile; 4181 } 4182 tracesFile.renameTo(curTracesFile); 4183 if (tracesTmp.exists()) { 4184 tracesTmp.renameTo(tracesFile); 4185 } 4186 } finally { 4187 StrictMode.setThreadPolicy(oldPolicy); 4188 } 4189 } 4190 4191 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4192 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4193 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4194 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4195 4196 if (mController != null) { 4197 try { 4198 // 0 == continue, -1 = kill process immediately 4199 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4200 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4201 } catch (RemoteException e) { 4202 mController = null; 4203 Watchdog.getInstance().setActivityController(null); 4204 } 4205 } 4206 4207 long anrTime = SystemClock.uptimeMillis(); 4208 if (MONITOR_CPU_USAGE) { 4209 updateCpuStatsNow(); 4210 } 4211 4212 synchronized (this) { 4213 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4214 if (mShuttingDown) { 4215 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4216 return; 4217 } else if (app.notResponding) { 4218 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4219 return; 4220 } else if (app.crashing) { 4221 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4222 return; 4223 } 4224 4225 // In case we come through here for the same app before completing 4226 // this one, mark as anring now so we will bail out. 4227 app.notResponding = true; 4228 4229 // Log the ANR to the event log. 4230 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4231 app.processName, app.info.flags, annotation); 4232 4233 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4234 firstPids.add(app.pid); 4235 4236 int parentPid = app.pid; 4237 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4238 if (parentPid != app.pid) firstPids.add(parentPid); 4239 4240 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4241 4242 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4243 ProcessRecord r = mLruProcesses.get(i); 4244 if (r != null && r.thread != null) { 4245 int pid = r.pid; 4246 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4247 if (r.persistent) { 4248 firstPids.add(pid); 4249 } else { 4250 lastPids.put(pid, Boolean.TRUE); 4251 } 4252 } 4253 } 4254 } 4255 } 4256 4257 // Log the ANR to the main log. 4258 StringBuilder info = new StringBuilder(); 4259 info.setLength(0); 4260 info.append("ANR in ").append(app.processName); 4261 if (activity != null && activity.shortComponentName != null) { 4262 info.append(" (").append(activity.shortComponentName).append(")"); 4263 } 4264 info.append("\n"); 4265 info.append("PID: ").append(app.pid).append("\n"); 4266 if (annotation != null) { 4267 info.append("Reason: ").append(annotation).append("\n"); 4268 } 4269 if (parent != null && parent != activity) { 4270 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4271 } 4272 4273 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4274 4275 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4276 NATIVE_STACKS_OF_INTEREST); 4277 4278 String cpuInfo = null; 4279 if (MONITOR_CPU_USAGE) { 4280 updateCpuStatsNow(); 4281 synchronized (mProcessCpuThread) { 4282 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4283 } 4284 info.append(processCpuTracker.printCurrentLoad()); 4285 info.append(cpuInfo); 4286 } 4287 4288 info.append(processCpuTracker.printCurrentState(anrTime)); 4289 4290 Slog.e(TAG, info.toString()); 4291 if (tracesFile == null) { 4292 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4293 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4294 } 4295 4296 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4297 cpuInfo, tracesFile, null); 4298 4299 if (mController != null) { 4300 try { 4301 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4302 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4303 if (res != 0) { 4304 if (res < 0 && app.pid != MY_PID) { 4305 Process.killProcess(app.pid); 4306 } else { 4307 synchronized (this) { 4308 mServices.scheduleServiceTimeoutLocked(app); 4309 } 4310 } 4311 return; 4312 } 4313 } catch (RemoteException e) { 4314 mController = null; 4315 Watchdog.getInstance().setActivityController(null); 4316 } 4317 } 4318 4319 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4320 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4321 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4322 4323 synchronized (this) { 4324 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4325 killUnneededProcessLocked(app, "background ANR"); 4326 return; 4327 } 4328 4329 // Set the app's notResponding state, and look up the errorReportReceiver 4330 makeAppNotRespondingLocked(app, 4331 activity != null ? activity.shortComponentName : null, 4332 annotation != null ? "ANR " + annotation : "ANR", 4333 info.toString()); 4334 4335 // Bring up the infamous App Not Responding dialog 4336 Message msg = Message.obtain(); 4337 HashMap<String, Object> map = new HashMap<String, Object>(); 4338 msg.what = SHOW_NOT_RESPONDING_MSG; 4339 msg.obj = map; 4340 msg.arg1 = aboveSystem ? 1 : 0; 4341 map.put("app", app); 4342 if (activity != null) { 4343 map.put("activity", activity); 4344 } 4345 4346 mHandler.sendMessage(msg); 4347 } 4348 } 4349 4350 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4351 if (!mLaunchWarningShown) { 4352 mLaunchWarningShown = true; 4353 mHandler.post(new Runnable() { 4354 @Override 4355 public void run() { 4356 synchronized (ActivityManagerService.this) { 4357 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4358 d.show(); 4359 mHandler.postDelayed(new Runnable() { 4360 @Override 4361 public void run() { 4362 synchronized (ActivityManagerService.this) { 4363 d.dismiss(); 4364 mLaunchWarningShown = false; 4365 } 4366 } 4367 }, 4000); 4368 } 4369 } 4370 }); 4371 } 4372 } 4373 4374 @Override 4375 public boolean clearApplicationUserData(final String packageName, 4376 final IPackageDataObserver observer, int userId) { 4377 enforceNotIsolatedCaller("clearApplicationUserData"); 4378 int uid = Binder.getCallingUid(); 4379 int pid = Binder.getCallingPid(); 4380 userId = handleIncomingUser(pid, uid, 4381 userId, false, true, "clearApplicationUserData", null); 4382 long callingId = Binder.clearCallingIdentity(); 4383 try { 4384 IPackageManager pm = AppGlobals.getPackageManager(); 4385 int pkgUid = -1; 4386 synchronized(this) { 4387 try { 4388 pkgUid = pm.getPackageUid(packageName, userId); 4389 } catch (RemoteException e) { 4390 } 4391 if (pkgUid == -1) { 4392 Slog.w(TAG, "Invalid packageName: " + packageName); 4393 if (observer != null) { 4394 try { 4395 observer.onRemoveCompleted(packageName, false); 4396 } catch (RemoteException e) { 4397 Slog.i(TAG, "Observer no longer exists."); 4398 } 4399 } 4400 return false; 4401 } 4402 if (uid == pkgUid || checkComponentPermission( 4403 android.Manifest.permission.CLEAR_APP_USER_DATA, 4404 pid, uid, -1, true) 4405 == PackageManager.PERMISSION_GRANTED) { 4406 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4407 } else { 4408 throw new SecurityException("PID " + pid + " does not have permission " 4409 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4410 + " of package " + packageName); 4411 } 4412 } 4413 4414 try { 4415 // Clear application user data 4416 pm.clearApplicationUserData(packageName, observer, userId); 4417 4418 // Remove all permissions granted from/to this package 4419 removeUriPermissionsForPackageLocked(packageName, userId, true); 4420 4421 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4422 Uri.fromParts("package", packageName, null)); 4423 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4424 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4425 null, null, 0, null, null, null, false, false, userId); 4426 } catch (RemoteException e) { 4427 } 4428 } finally { 4429 Binder.restoreCallingIdentity(callingId); 4430 } 4431 return true; 4432 } 4433 4434 @Override 4435 public void killBackgroundProcesses(final String packageName, int userId) { 4436 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4437 != PackageManager.PERMISSION_GRANTED && 4438 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4439 != PackageManager.PERMISSION_GRANTED) { 4440 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4441 + Binder.getCallingPid() 4442 + ", uid=" + Binder.getCallingUid() 4443 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4444 Slog.w(TAG, msg); 4445 throw new SecurityException(msg); 4446 } 4447 4448 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4449 userId, true, true, "killBackgroundProcesses", null); 4450 long callingId = Binder.clearCallingIdentity(); 4451 try { 4452 IPackageManager pm = AppGlobals.getPackageManager(); 4453 synchronized(this) { 4454 int appId = -1; 4455 try { 4456 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4457 } catch (RemoteException e) { 4458 } 4459 if (appId == -1) { 4460 Slog.w(TAG, "Invalid packageName: " + packageName); 4461 return; 4462 } 4463 killPackageProcessesLocked(packageName, appId, userId, 4464 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4465 } 4466 } finally { 4467 Binder.restoreCallingIdentity(callingId); 4468 } 4469 } 4470 4471 @Override 4472 public void killAllBackgroundProcesses() { 4473 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4474 != PackageManager.PERMISSION_GRANTED) { 4475 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4476 + Binder.getCallingPid() 4477 + ", uid=" + Binder.getCallingUid() 4478 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4479 Slog.w(TAG, msg); 4480 throw new SecurityException(msg); 4481 } 4482 4483 long callingId = Binder.clearCallingIdentity(); 4484 try { 4485 synchronized(this) { 4486 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4487 final int NP = mProcessNames.getMap().size(); 4488 for (int ip=0; ip<NP; ip++) { 4489 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4490 final int NA = apps.size(); 4491 for (int ia=0; ia<NA; ia++) { 4492 ProcessRecord app = apps.valueAt(ia); 4493 if (app.persistent) { 4494 // we don't kill persistent processes 4495 continue; 4496 } 4497 if (app.removed) { 4498 procs.add(app); 4499 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4500 app.removed = true; 4501 procs.add(app); 4502 } 4503 } 4504 } 4505 4506 int N = procs.size(); 4507 for (int i=0; i<N; i++) { 4508 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4509 } 4510 mAllowLowerMemLevel = true; 4511 updateOomAdjLocked(); 4512 doLowMemReportIfNeededLocked(null); 4513 } 4514 } finally { 4515 Binder.restoreCallingIdentity(callingId); 4516 } 4517 } 4518 4519 @Override 4520 public void forceStopPackage(final String packageName, int userId) { 4521 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4522 != PackageManager.PERMISSION_GRANTED) { 4523 String msg = "Permission Denial: forceStopPackage() from pid=" 4524 + Binder.getCallingPid() 4525 + ", uid=" + Binder.getCallingUid() 4526 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4527 Slog.w(TAG, msg); 4528 throw new SecurityException(msg); 4529 } 4530 final int callingPid = Binder.getCallingPid(); 4531 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4532 userId, true, true, "forceStopPackage", null); 4533 long callingId = Binder.clearCallingIdentity(); 4534 try { 4535 IPackageManager pm = AppGlobals.getPackageManager(); 4536 synchronized(this) { 4537 int[] users = userId == UserHandle.USER_ALL 4538 ? getUsersLocked() : new int[] { userId }; 4539 for (int user : users) { 4540 int pkgUid = -1; 4541 try { 4542 pkgUid = pm.getPackageUid(packageName, user); 4543 } catch (RemoteException e) { 4544 } 4545 if (pkgUid == -1) { 4546 Slog.w(TAG, "Invalid packageName: " + packageName); 4547 continue; 4548 } 4549 try { 4550 pm.setPackageStoppedState(packageName, true, user); 4551 } catch (RemoteException e) { 4552 } catch (IllegalArgumentException e) { 4553 Slog.w(TAG, "Failed trying to unstop package " 4554 + packageName + ": " + e); 4555 } 4556 if (isUserRunningLocked(user, false)) { 4557 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4558 } 4559 } 4560 } 4561 } finally { 4562 Binder.restoreCallingIdentity(callingId); 4563 } 4564 } 4565 4566 /* 4567 * The pkg name and app id have to be specified. 4568 */ 4569 @Override 4570 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4571 if (pkg == null) { 4572 return; 4573 } 4574 // Make sure the uid is valid. 4575 if (appid < 0) { 4576 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4577 return; 4578 } 4579 int callerUid = Binder.getCallingUid(); 4580 // Only the system server can kill an application 4581 if (callerUid == Process.SYSTEM_UID) { 4582 // Post an aysnc message to kill the application 4583 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4584 msg.arg1 = appid; 4585 msg.arg2 = 0; 4586 Bundle bundle = new Bundle(); 4587 bundle.putString("pkg", pkg); 4588 bundle.putString("reason", reason); 4589 msg.obj = bundle; 4590 mHandler.sendMessage(msg); 4591 } else { 4592 throw new SecurityException(callerUid + " cannot kill pkg: " + 4593 pkg); 4594 } 4595 } 4596 4597 @Override 4598 public void closeSystemDialogs(String reason) { 4599 enforceNotIsolatedCaller("closeSystemDialogs"); 4600 4601 final int pid = Binder.getCallingPid(); 4602 final int uid = Binder.getCallingUid(); 4603 final long origId = Binder.clearCallingIdentity(); 4604 try { 4605 synchronized (this) { 4606 // Only allow this from foreground processes, so that background 4607 // applications can't abuse it to prevent system UI from being shown. 4608 if (uid >= Process.FIRST_APPLICATION_UID) { 4609 ProcessRecord proc; 4610 synchronized (mPidsSelfLocked) { 4611 proc = mPidsSelfLocked.get(pid); 4612 } 4613 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4614 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4615 + " from background process " + proc); 4616 return; 4617 } 4618 } 4619 closeSystemDialogsLocked(reason); 4620 } 4621 } finally { 4622 Binder.restoreCallingIdentity(origId); 4623 } 4624 } 4625 4626 void closeSystemDialogsLocked(String reason) { 4627 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4628 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4629 | Intent.FLAG_RECEIVER_FOREGROUND); 4630 if (reason != null) { 4631 intent.putExtra("reason", reason); 4632 } 4633 mWindowManager.closeSystemDialogs(reason); 4634 4635 mStackSupervisor.closeSystemDialogsLocked(); 4636 4637 broadcastIntentLocked(null, null, intent, null, 4638 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4639 Process.SYSTEM_UID, UserHandle.USER_ALL); 4640 } 4641 4642 @Override 4643 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4644 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4645 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4646 for (int i=pids.length-1; i>=0; i--) { 4647 ProcessRecord proc; 4648 int oomAdj; 4649 synchronized (this) { 4650 synchronized (mPidsSelfLocked) { 4651 proc = mPidsSelfLocked.get(pids[i]); 4652 oomAdj = proc != null ? proc.setAdj : 0; 4653 } 4654 } 4655 infos[i] = new Debug.MemoryInfo(); 4656 Debug.getMemoryInfo(pids[i], infos[i]); 4657 if (proc != null) { 4658 synchronized (this) { 4659 if (proc.thread != null && proc.setAdj == oomAdj) { 4660 // Record this for posterity if the process has been stable. 4661 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4662 infos[i].getTotalUss(), false, proc.pkgList); 4663 } 4664 } 4665 } 4666 } 4667 return infos; 4668 } 4669 4670 @Override 4671 public long[] getProcessPss(int[] pids) { 4672 enforceNotIsolatedCaller("getProcessPss"); 4673 long[] pss = new long[pids.length]; 4674 for (int i=pids.length-1; i>=0; i--) { 4675 ProcessRecord proc; 4676 int oomAdj; 4677 synchronized (this) { 4678 synchronized (mPidsSelfLocked) { 4679 proc = mPidsSelfLocked.get(pids[i]); 4680 oomAdj = proc != null ? proc.setAdj : 0; 4681 } 4682 } 4683 long[] tmpUss = new long[1]; 4684 pss[i] = Debug.getPss(pids[i], tmpUss); 4685 if (proc != null) { 4686 synchronized (this) { 4687 if (proc.thread != null && proc.setAdj == oomAdj) { 4688 // Record this for posterity if the process has been stable. 4689 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4690 } 4691 } 4692 } 4693 } 4694 return pss; 4695 } 4696 4697 @Override 4698 public void killApplicationProcess(String processName, int uid) { 4699 if (processName == null) { 4700 return; 4701 } 4702 4703 int callerUid = Binder.getCallingUid(); 4704 // Only the system server can kill an application 4705 if (callerUid == Process.SYSTEM_UID) { 4706 synchronized (this) { 4707 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4708 if (app != null && app.thread != null) { 4709 try { 4710 app.thread.scheduleSuicide(); 4711 } catch (RemoteException e) { 4712 // If the other end already died, then our work here is done. 4713 } 4714 } else { 4715 Slog.w(TAG, "Process/uid not found attempting kill of " 4716 + processName + " / " + uid); 4717 } 4718 } 4719 } else { 4720 throw new SecurityException(callerUid + " cannot kill app process: " + 4721 processName); 4722 } 4723 } 4724 4725 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4726 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4727 false, true, false, false, UserHandle.getUserId(uid), reason); 4728 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4729 Uri.fromParts("package", packageName, null)); 4730 if (!mProcessesReady) { 4731 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4732 | Intent.FLAG_RECEIVER_FOREGROUND); 4733 } 4734 intent.putExtra(Intent.EXTRA_UID, uid); 4735 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4736 broadcastIntentLocked(null, null, intent, 4737 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4738 false, false, 4739 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4740 } 4741 4742 private void forceStopUserLocked(int userId, String reason) { 4743 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4744 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4745 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4746 | Intent.FLAG_RECEIVER_FOREGROUND); 4747 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4748 broadcastIntentLocked(null, null, intent, 4749 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4750 false, false, 4751 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4752 } 4753 4754 private final boolean killPackageProcessesLocked(String packageName, int appId, 4755 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4756 boolean doit, boolean evenPersistent, String reason) { 4757 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4758 4759 // Remove all processes this package may have touched: all with the 4760 // same UID (except for the system or root user), and all whose name 4761 // matches the package name. 4762 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4763 final int NP = mProcessNames.getMap().size(); 4764 for (int ip=0; ip<NP; ip++) { 4765 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4766 final int NA = apps.size(); 4767 for (int ia=0; ia<NA; ia++) { 4768 ProcessRecord app = apps.valueAt(ia); 4769 if (app.persistent && !evenPersistent) { 4770 // we don't kill persistent processes 4771 continue; 4772 } 4773 if (app.removed) { 4774 if (doit) { 4775 procs.add(app); 4776 } 4777 continue; 4778 } 4779 4780 // Skip process if it doesn't meet our oom adj requirement. 4781 if (app.setAdj < minOomAdj) { 4782 continue; 4783 } 4784 4785 // If no package is specified, we call all processes under the 4786 // give user id. 4787 if (packageName == null) { 4788 if (app.userId != userId) { 4789 continue; 4790 } 4791 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4792 continue; 4793 } 4794 // Package has been specified, we want to hit all processes 4795 // that match it. We need to qualify this by the processes 4796 // that are running under the specified app and user ID. 4797 } else { 4798 if (UserHandle.getAppId(app.uid) != appId) { 4799 continue; 4800 } 4801 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4802 continue; 4803 } 4804 if (!app.pkgList.containsKey(packageName)) { 4805 continue; 4806 } 4807 } 4808 4809 // Process has passed all conditions, kill it! 4810 if (!doit) { 4811 return true; 4812 } 4813 app.removed = true; 4814 procs.add(app); 4815 } 4816 } 4817 4818 int N = procs.size(); 4819 for (int i=0; i<N; i++) { 4820 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4821 } 4822 updateOomAdjLocked(); 4823 return N > 0; 4824 } 4825 4826 private final boolean forceStopPackageLocked(String name, int appId, 4827 boolean callerWillRestart, boolean purgeCache, boolean doit, 4828 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4829 int i; 4830 int N; 4831 4832 if (userId == UserHandle.USER_ALL && name == null) { 4833 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4834 } 4835 4836 if (appId < 0 && name != null) { 4837 try { 4838 appId = UserHandle.getAppId( 4839 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4840 } catch (RemoteException e) { 4841 } 4842 } 4843 4844 if (doit) { 4845 if (name != null) { 4846 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4847 + " user=" + userId + ": " + reason); 4848 } else { 4849 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4850 } 4851 4852 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4853 for (int ip=pmap.size()-1; ip>=0; ip--) { 4854 SparseArray<Long> ba = pmap.valueAt(ip); 4855 for (i=ba.size()-1; i>=0; i--) { 4856 boolean remove = false; 4857 final int entUid = ba.keyAt(i); 4858 if (name != null) { 4859 if (userId == UserHandle.USER_ALL) { 4860 if (UserHandle.getAppId(entUid) == appId) { 4861 remove = true; 4862 } 4863 } else { 4864 if (entUid == UserHandle.getUid(userId, appId)) { 4865 remove = true; 4866 } 4867 } 4868 } else if (UserHandle.getUserId(entUid) == userId) { 4869 remove = true; 4870 } 4871 if (remove) { 4872 ba.removeAt(i); 4873 } 4874 } 4875 if (ba.size() == 0) { 4876 pmap.removeAt(ip); 4877 } 4878 } 4879 } 4880 4881 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4882 -100, callerWillRestart, true, doit, evenPersistent, 4883 name == null ? ("stop user " + userId) : ("stop " + name)); 4884 4885 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4886 if (!doit) { 4887 return true; 4888 } 4889 didSomething = true; 4890 } 4891 4892 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4893 if (!doit) { 4894 return true; 4895 } 4896 didSomething = true; 4897 } 4898 4899 if (name == null) { 4900 // Remove all sticky broadcasts from this user. 4901 mStickyBroadcasts.remove(userId); 4902 } 4903 4904 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4905 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4906 userId, providers)) { 4907 if (!doit) { 4908 return true; 4909 } 4910 didSomething = true; 4911 } 4912 N = providers.size(); 4913 for (i=0; i<N; i++) { 4914 removeDyingProviderLocked(null, providers.get(i), true); 4915 } 4916 4917 // Remove transient permissions granted from/to this package/user 4918 removeUriPermissionsForPackageLocked(name, userId, false); 4919 4920 if (name == null || uninstalling) { 4921 // Remove pending intents. For now we only do this when force 4922 // stopping users, because we have some problems when doing this 4923 // for packages -- app widgets are not currently cleaned up for 4924 // such packages, so they can be left with bad pending intents. 4925 if (mIntentSenderRecords.size() > 0) { 4926 Iterator<WeakReference<PendingIntentRecord>> it 4927 = mIntentSenderRecords.values().iterator(); 4928 while (it.hasNext()) { 4929 WeakReference<PendingIntentRecord> wpir = it.next(); 4930 if (wpir == null) { 4931 it.remove(); 4932 continue; 4933 } 4934 PendingIntentRecord pir = wpir.get(); 4935 if (pir == null) { 4936 it.remove(); 4937 continue; 4938 } 4939 if (name == null) { 4940 // Stopping user, remove all objects for the user. 4941 if (pir.key.userId != userId) { 4942 // Not the same user, skip it. 4943 continue; 4944 } 4945 } else { 4946 if (UserHandle.getAppId(pir.uid) != appId) { 4947 // Different app id, skip it. 4948 continue; 4949 } 4950 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4951 // Different user, skip it. 4952 continue; 4953 } 4954 if (!pir.key.packageName.equals(name)) { 4955 // Different package, skip it. 4956 continue; 4957 } 4958 } 4959 if (!doit) { 4960 return true; 4961 } 4962 didSomething = true; 4963 it.remove(); 4964 pir.canceled = true; 4965 if (pir.key.activity != null) { 4966 pir.key.activity.pendingResults.remove(pir.ref); 4967 } 4968 } 4969 } 4970 } 4971 4972 if (doit) { 4973 if (purgeCache && name != null) { 4974 AttributeCache ac = AttributeCache.instance(); 4975 if (ac != null) { 4976 ac.removePackage(name); 4977 } 4978 } 4979 if (mBooted) { 4980 mStackSupervisor.resumeTopActivitiesLocked(); 4981 mStackSupervisor.scheduleIdleLocked(); 4982 } 4983 } 4984 4985 return didSomething; 4986 } 4987 4988 private final boolean removeProcessLocked(ProcessRecord app, 4989 boolean callerWillRestart, boolean allowRestart, String reason) { 4990 final String name = app.processName; 4991 final int uid = app.uid; 4992 if (DEBUG_PROCESSES) Slog.d( 4993 TAG, "Force removing proc " + app.toShortString() + " (" + name 4994 + "/" + uid + ")"); 4995 4996 mProcessNames.remove(name, uid); 4997 mIsolatedProcesses.remove(app.uid); 4998 if (mHeavyWeightProcess == app) { 4999 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5000 mHeavyWeightProcess.userId, 0)); 5001 mHeavyWeightProcess = null; 5002 } 5003 boolean needRestart = false; 5004 if (app.pid > 0 && app.pid != MY_PID) { 5005 int pid = app.pid; 5006 synchronized (mPidsSelfLocked) { 5007 mPidsSelfLocked.remove(pid); 5008 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5009 } 5010 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5011 app.processName, app.info.uid); 5012 if (app.isolated) { 5013 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5014 } 5015 killUnneededProcessLocked(app, reason); 5016 handleAppDiedLocked(app, true, allowRestart); 5017 removeLruProcessLocked(app); 5018 5019 if (app.persistent && !app.isolated) { 5020 if (!callerWillRestart) { 5021 addAppLocked(app.info, false); 5022 } else { 5023 needRestart = true; 5024 } 5025 } 5026 } else { 5027 mRemovedProcesses.add(app); 5028 } 5029 5030 return needRestart; 5031 } 5032 5033 private final void processStartTimedOutLocked(ProcessRecord app) { 5034 final int pid = app.pid; 5035 boolean gone = false; 5036 synchronized (mPidsSelfLocked) { 5037 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5038 if (knownApp != null && knownApp.thread == null) { 5039 mPidsSelfLocked.remove(pid); 5040 gone = true; 5041 } 5042 } 5043 5044 if (gone) { 5045 Slog.w(TAG, "Process " + app + " failed to attach"); 5046 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5047 pid, app.uid, app.processName); 5048 mProcessNames.remove(app.processName, app.uid); 5049 mIsolatedProcesses.remove(app.uid); 5050 if (mHeavyWeightProcess == app) { 5051 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5052 mHeavyWeightProcess.userId, 0)); 5053 mHeavyWeightProcess = null; 5054 } 5055 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5056 app.processName, app.info.uid); 5057 if (app.isolated) { 5058 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5059 } 5060 // Take care of any launching providers waiting for this process. 5061 checkAppInLaunchingProvidersLocked(app, true); 5062 // Take care of any services that are waiting for the process. 5063 mServices.processStartTimedOutLocked(app); 5064 killUnneededProcessLocked(app, "start timeout"); 5065 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5066 Slog.w(TAG, "Unattached app died before backup, skipping"); 5067 try { 5068 IBackupManager bm = IBackupManager.Stub.asInterface( 5069 ServiceManager.getService(Context.BACKUP_SERVICE)); 5070 bm.agentDisconnected(app.info.packageName); 5071 } catch (RemoteException e) { 5072 // Can't happen; the backup manager is local 5073 } 5074 } 5075 if (isPendingBroadcastProcessLocked(pid)) { 5076 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5077 skipPendingBroadcastLocked(pid); 5078 } 5079 } else { 5080 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5081 } 5082 } 5083 5084 private final boolean attachApplicationLocked(IApplicationThread thread, 5085 int pid) { 5086 5087 // Find the application record that is being attached... either via 5088 // the pid if we are running in multiple processes, or just pull the 5089 // next app record if we are emulating process with anonymous threads. 5090 ProcessRecord app; 5091 if (pid != MY_PID && pid >= 0) { 5092 synchronized (mPidsSelfLocked) { 5093 app = mPidsSelfLocked.get(pid); 5094 } 5095 } else { 5096 app = null; 5097 } 5098 5099 if (app == null) { 5100 Slog.w(TAG, "No pending application record for pid " + pid 5101 + " (IApplicationThread " + thread + "); dropping process"); 5102 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5103 if (pid > 0 && pid != MY_PID) { 5104 Process.killProcessQuiet(pid); 5105 } else { 5106 try { 5107 thread.scheduleExit(); 5108 } catch (Exception e) { 5109 // Ignore exceptions. 5110 } 5111 } 5112 return false; 5113 } 5114 5115 // If this application record is still attached to a previous 5116 // process, clean it up now. 5117 if (app.thread != null) { 5118 handleAppDiedLocked(app, true, true); 5119 } 5120 5121 // Tell the process all about itself. 5122 5123 if (localLOGV) Slog.v( 5124 TAG, "Binding process pid " + pid + " to record " + app); 5125 5126 final String processName = app.processName; 5127 try { 5128 AppDeathRecipient adr = new AppDeathRecipient( 5129 app, pid, thread); 5130 thread.asBinder().linkToDeath(adr, 0); 5131 app.deathRecipient = adr; 5132 } catch (RemoteException e) { 5133 app.resetPackageList(mProcessStats); 5134 startProcessLocked(app, "link fail", processName); 5135 return false; 5136 } 5137 5138 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5139 5140 app.makeActive(thread, mProcessStats); 5141 app.curAdj = app.setAdj = -100; 5142 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5143 app.forcingToForeground = null; 5144 updateProcessForegroundLocked(app, false, false); 5145 app.hasShownUi = false; 5146 app.debugging = false; 5147 app.cached = false; 5148 5149 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5150 5151 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5152 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5153 5154 if (!normalMode) { 5155 Slog.i(TAG, "Launching preboot mode app: " + app); 5156 } 5157 5158 if (localLOGV) Slog.v( 5159 TAG, "New app record " + app 5160 + " thread=" + thread.asBinder() + " pid=" + pid); 5161 try { 5162 int testMode = IApplicationThread.DEBUG_OFF; 5163 if (mDebugApp != null && mDebugApp.equals(processName)) { 5164 testMode = mWaitForDebugger 5165 ? IApplicationThread.DEBUG_WAIT 5166 : IApplicationThread.DEBUG_ON; 5167 app.debugging = true; 5168 if (mDebugTransient) { 5169 mDebugApp = mOrigDebugApp; 5170 mWaitForDebugger = mOrigWaitForDebugger; 5171 } 5172 } 5173 String profileFile = app.instrumentationProfileFile; 5174 ParcelFileDescriptor profileFd = null; 5175 boolean profileAutoStop = false; 5176 if (mProfileApp != null && mProfileApp.equals(processName)) { 5177 mProfileProc = app; 5178 profileFile = mProfileFile; 5179 profileFd = mProfileFd; 5180 profileAutoStop = mAutoStopProfiler; 5181 } 5182 boolean enableOpenGlTrace = false; 5183 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5184 enableOpenGlTrace = true; 5185 mOpenGlTraceApp = null; 5186 } 5187 5188 // If the app is being launched for restore or full backup, set it up specially 5189 boolean isRestrictedBackupMode = false; 5190 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5191 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5192 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5193 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5194 } 5195 5196 ensurePackageDexOpt(app.instrumentationInfo != null 5197 ? app.instrumentationInfo.packageName 5198 : app.info.packageName); 5199 if (app.instrumentationClass != null) { 5200 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5201 } 5202 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5203 + processName + " with config " + mConfiguration); 5204 ApplicationInfo appInfo = app.instrumentationInfo != null 5205 ? app.instrumentationInfo : app.info; 5206 app.compat = compatibilityInfoForPackageLocked(appInfo); 5207 if (profileFd != null) { 5208 profileFd = profileFd.dup(); 5209 } 5210 thread.bindApplication(processName, appInfo, providers, 5211 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5212 app.instrumentationArguments, app.instrumentationWatcher, 5213 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5214 isRestrictedBackupMode || !normalMode, app.persistent, 5215 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5216 mCoreSettingsObserver.getCoreSettingsLocked()); 5217 updateLruProcessLocked(app, false, null); 5218 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5219 } catch (Exception e) { 5220 // todo: Yikes! What should we do? For now we will try to 5221 // start another process, but that could easily get us in 5222 // an infinite loop of restarting processes... 5223 Slog.w(TAG, "Exception thrown during bind!", e); 5224 5225 app.resetPackageList(mProcessStats); 5226 app.unlinkDeathRecipient(); 5227 startProcessLocked(app, "bind fail", processName); 5228 return false; 5229 } 5230 5231 // Remove this record from the list of starting applications. 5232 mPersistentStartingProcesses.remove(app); 5233 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5234 "Attach application locked removing on hold: " + app); 5235 mProcessesOnHold.remove(app); 5236 5237 boolean badApp = false; 5238 boolean didSomething = false; 5239 5240 // See if the top visible activity is waiting to run in this process... 5241 if (normalMode) { 5242 try { 5243 if (mStackSupervisor.attachApplicationLocked(app)) { 5244 didSomething = true; 5245 } 5246 } catch (Exception e) { 5247 badApp = true; 5248 } 5249 } 5250 5251 // Find any services that should be running in this process... 5252 if (!badApp) { 5253 try { 5254 didSomething |= mServices.attachApplicationLocked(app, processName); 5255 } catch (Exception e) { 5256 badApp = true; 5257 } 5258 } 5259 5260 // Check if a next-broadcast receiver is in this process... 5261 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5262 try { 5263 didSomething |= sendPendingBroadcastsLocked(app); 5264 } catch (Exception e) { 5265 // If the app died trying to launch the receiver we declare it 'bad' 5266 badApp = true; 5267 } 5268 } 5269 5270 // Check whether the next backup agent is in this process... 5271 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5272 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5273 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5274 try { 5275 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5276 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5277 mBackupTarget.backupMode); 5278 } catch (Exception e) { 5279 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5280 e.printStackTrace(); 5281 } 5282 } 5283 5284 if (badApp) { 5285 // todo: Also need to kill application to deal with all 5286 // kinds of exceptions. 5287 handleAppDiedLocked(app, false, true); 5288 return false; 5289 } 5290 5291 if (!didSomething) { 5292 updateOomAdjLocked(); 5293 } 5294 5295 return true; 5296 } 5297 5298 @Override 5299 public final void attachApplication(IApplicationThread thread) { 5300 synchronized (this) { 5301 int callingPid = Binder.getCallingPid(); 5302 final long origId = Binder.clearCallingIdentity(); 5303 attachApplicationLocked(thread, callingPid); 5304 Binder.restoreCallingIdentity(origId); 5305 } 5306 } 5307 5308 @Override 5309 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5310 final long origId = Binder.clearCallingIdentity(); 5311 synchronized (this) { 5312 ActivityStack stack = ActivityRecord.getStackLocked(token); 5313 if (stack != null) { 5314 ActivityRecord r = 5315 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5316 if (stopProfiling) { 5317 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5318 try { 5319 mProfileFd.close(); 5320 } catch (IOException e) { 5321 } 5322 clearProfilerLocked(); 5323 } 5324 } 5325 } 5326 } 5327 Binder.restoreCallingIdentity(origId); 5328 } 5329 5330 void enableScreenAfterBoot() { 5331 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5332 SystemClock.uptimeMillis()); 5333 mWindowManager.enableScreenAfterBoot(); 5334 5335 synchronized (this) { 5336 updateEventDispatchingLocked(); 5337 } 5338 } 5339 5340 @Override 5341 public void showBootMessage(final CharSequence msg, final boolean always) { 5342 enforceNotIsolatedCaller("showBootMessage"); 5343 mWindowManager.showBootMessage(msg, always); 5344 } 5345 5346 @Override 5347 public void dismissKeyguardOnNextActivity() { 5348 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5349 final long token = Binder.clearCallingIdentity(); 5350 try { 5351 synchronized (this) { 5352 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5353 if (mLockScreenShown) { 5354 mLockScreenShown = false; 5355 comeOutOfSleepIfNeededLocked(); 5356 } 5357 mStackSupervisor.setDismissKeyguard(true); 5358 } 5359 } finally { 5360 Binder.restoreCallingIdentity(token); 5361 } 5362 } 5363 5364 final void finishBooting() { 5365 // Register receivers to handle package update events 5366 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5367 5368 synchronized (this) { 5369 // Ensure that any processes we had put on hold are now started 5370 // up. 5371 final int NP = mProcessesOnHold.size(); 5372 if (NP > 0) { 5373 ArrayList<ProcessRecord> procs = 5374 new ArrayList<ProcessRecord>(mProcessesOnHold); 5375 for (int ip=0; ip<NP; ip++) { 5376 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5377 + procs.get(ip)); 5378 startProcessLocked(procs.get(ip), "on-hold", null); 5379 } 5380 } 5381 5382 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5383 // Start looking for apps that are abusing wake locks. 5384 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5385 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5386 // Tell anyone interested that we are done booting! 5387 SystemProperties.set("sys.boot_completed", "1"); 5388 SystemProperties.set("dev.bootcomplete", "1"); 5389 for (int i=0; i<mStartedUsers.size(); i++) { 5390 UserStartedState uss = mStartedUsers.valueAt(i); 5391 if (uss.mState == UserStartedState.STATE_BOOTING) { 5392 uss.mState = UserStartedState.STATE_RUNNING; 5393 final int userId = mStartedUsers.keyAt(i); 5394 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5395 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5396 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5397 broadcastIntentLocked(null, null, intent, null, 5398 new IIntentReceiver.Stub() { 5399 @Override 5400 public void performReceive(Intent intent, int resultCode, 5401 String data, Bundle extras, boolean ordered, 5402 boolean sticky, int sendingUser) { 5403 synchronized (ActivityManagerService.this) { 5404 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5405 true, false); 5406 } 5407 } 5408 }, 5409 0, null, null, 5410 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5411 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5412 userId); 5413 } 5414 } 5415 scheduleStartProfilesLocked(); 5416 } 5417 } 5418 } 5419 5420 final void ensureBootCompleted() { 5421 boolean booting; 5422 boolean enableScreen; 5423 synchronized (this) { 5424 booting = mBooting; 5425 mBooting = false; 5426 enableScreen = !mBooted; 5427 mBooted = true; 5428 } 5429 5430 if (booting) { 5431 finishBooting(); 5432 } 5433 5434 if (enableScreen) { 5435 enableScreenAfterBoot(); 5436 } 5437 } 5438 5439 @Override 5440 public final void activityResumed(IBinder token) { 5441 final long origId = Binder.clearCallingIdentity(); 5442 synchronized(this) { 5443 ActivityStack stack = ActivityRecord.getStackLocked(token); 5444 if (stack != null) { 5445 ActivityRecord.activityResumedLocked(token); 5446 } 5447 } 5448 Binder.restoreCallingIdentity(origId); 5449 } 5450 5451 @Override 5452 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5453 final long origId = Binder.clearCallingIdentity(); 5454 synchronized(this) { 5455 ActivityStack stack = ActivityRecord.getStackLocked(token); 5456 if (stack != null) { 5457 stack.activityPausedLocked(token, false, persistentState); 5458 } 5459 } 5460 Binder.restoreCallingIdentity(origId); 5461 } 5462 5463 @Override 5464 public final void activityStopped(IBinder token, Bundle icicle, 5465 PersistableBundle persistentState, CharSequence description) { 5466 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5467 5468 // Refuse possible leaked file descriptors 5469 if (icicle != null && icicle.hasFileDescriptors()) { 5470 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5471 } 5472 5473 final long origId = Binder.clearCallingIdentity(); 5474 5475 synchronized (this) { 5476 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5477 if (r != null) { 5478 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5479 } 5480 } 5481 5482 trimApplications(); 5483 5484 Binder.restoreCallingIdentity(origId); 5485 } 5486 5487 @Override 5488 public final void activityDestroyed(IBinder token) { 5489 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5490 synchronized (this) { 5491 ActivityStack stack = ActivityRecord.getStackLocked(token); 5492 if (stack != null) { 5493 stack.activityDestroyedLocked(token); 5494 } 5495 } 5496 } 5497 5498 @Override 5499 public String getCallingPackage(IBinder token) { 5500 synchronized (this) { 5501 ActivityRecord r = getCallingRecordLocked(token); 5502 return r != null ? r.info.packageName : null; 5503 } 5504 } 5505 5506 @Override 5507 public ComponentName getCallingActivity(IBinder token) { 5508 synchronized (this) { 5509 ActivityRecord r = getCallingRecordLocked(token); 5510 return r != null ? r.intent.getComponent() : null; 5511 } 5512 } 5513 5514 private ActivityRecord getCallingRecordLocked(IBinder token) { 5515 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5516 if (r == null) { 5517 return null; 5518 } 5519 return r.resultTo; 5520 } 5521 5522 @Override 5523 public ComponentName getActivityClassForToken(IBinder token) { 5524 synchronized(this) { 5525 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5526 if (r == null) { 5527 return null; 5528 } 5529 return r.intent.getComponent(); 5530 } 5531 } 5532 5533 @Override 5534 public String getPackageForToken(IBinder token) { 5535 synchronized(this) { 5536 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5537 if (r == null) { 5538 return null; 5539 } 5540 return r.packageName; 5541 } 5542 } 5543 5544 @Override 5545 public IIntentSender getIntentSender(int type, 5546 String packageName, IBinder token, String resultWho, 5547 int requestCode, Intent[] intents, String[] resolvedTypes, 5548 int flags, Bundle options, int userId) { 5549 enforceNotIsolatedCaller("getIntentSender"); 5550 // Refuse possible leaked file descriptors 5551 if (intents != null) { 5552 if (intents.length < 1) { 5553 throw new IllegalArgumentException("Intents array length must be >= 1"); 5554 } 5555 for (int i=0; i<intents.length; i++) { 5556 Intent intent = intents[i]; 5557 if (intent != null) { 5558 if (intent.hasFileDescriptors()) { 5559 throw new IllegalArgumentException("File descriptors passed in Intent"); 5560 } 5561 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5562 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5563 throw new IllegalArgumentException( 5564 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5565 } 5566 intents[i] = new Intent(intent); 5567 } 5568 } 5569 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5570 throw new IllegalArgumentException( 5571 "Intent array length does not match resolvedTypes length"); 5572 } 5573 } 5574 if (options != null) { 5575 if (options.hasFileDescriptors()) { 5576 throw new IllegalArgumentException("File descriptors passed in options"); 5577 } 5578 } 5579 5580 synchronized(this) { 5581 int callingUid = Binder.getCallingUid(); 5582 int origUserId = userId; 5583 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5584 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5585 "getIntentSender", null); 5586 if (origUserId == UserHandle.USER_CURRENT) { 5587 // We don't want to evaluate this until the pending intent is 5588 // actually executed. However, we do want to always do the 5589 // security checking for it above. 5590 userId = UserHandle.USER_CURRENT; 5591 } 5592 try { 5593 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5594 int uid = AppGlobals.getPackageManager() 5595 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5596 if (!UserHandle.isSameApp(callingUid, uid)) { 5597 String msg = "Permission Denial: getIntentSender() from pid=" 5598 + Binder.getCallingPid() 5599 + ", uid=" + Binder.getCallingUid() 5600 + ", (need uid=" + uid + ")" 5601 + " is not allowed to send as package " + packageName; 5602 Slog.w(TAG, msg); 5603 throw new SecurityException(msg); 5604 } 5605 } 5606 5607 return getIntentSenderLocked(type, packageName, callingUid, userId, 5608 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5609 5610 } catch (RemoteException e) { 5611 throw new SecurityException(e); 5612 } 5613 } 5614 } 5615 5616 IIntentSender getIntentSenderLocked(int type, String packageName, 5617 int callingUid, int userId, IBinder token, String resultWho, 5618 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5619 Bundle options) { 5620 if (DEBUG_MU) 5621 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5622 ActivityRecord activity = null; 5623 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5624 activity = ActivityRecord.isInStackLocked(token); 5625 if (activity == null) { 5626 return null; 5627 } 5628 if (activity.finishing) { 5629 return null; 5630 } 5631 } 5632 5633 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5634 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5635 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5636 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5637 |PendingIntent.FLAG_UPDATE_CURRENT); 5638 5639 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5640 type, packageName, activity, resultWho, 5641 requestCode, intents, resolvedTypes, flags, options, userId); 5642 WeakReference<PendingIntentRecord> ref; 5643 ref = mIntentSenderRecords.get(key); 5644 PendingIntentRecord rec = ref != null ? ref.get() : null; 5645 if (rec != null) { 5646 if (!cancelCurrent) { 5647 if (updateCurrent) { 5648 if (rec.key.requestIntent != null) { 5649 rec.key.requestIntent.replaceExtras(intents != null ? 5650 intents[intents.length - 1] : null); 5651 } 5652 if (intents != null) { 5653 intents[intents.length-1] = rec.key.requestIntent; 5654 rec.key.allIntents = intents; 5655 rec.key.allResolvedTypes = resolvedTypes; 5656 } else { 5657 rec.key.allIntents = null; 5658 rec.key.allResolvedTypes = null; 5659 } 5660 } 5661 return rec; 5662 } 5663 rec.canceled = true; 5664 mIntentSenderRecords.remove(key); 5665 } 5666 if (noCreate) { 5667 return rec; 5668 } 5669 rec = new PendingIntentRecord(this, key, callingUid); 5670 mIntentSenderRecords.put(key, rec.ref); 5671 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5672 if (activity.pendingResults == null) { 5673 activity.pendingResults 5674 = new HashSet<WeakReference<PendingIntentRecord>>(); 5675 } 5676 activity.pendingResults.add(rec.ref); 5677 } 5678 return rec; 5679 } 5680 5681 @Override 5682 public void cancelIntentSender(IIntentSender sender) { 5683 if (!(sender instanceof PendingIntentRecord)) { 5684 return; 5685 } 5686 synchronized(this) { 5687 PendingIntentRecord rec = (PendingIntentRecord)sender; 5688 try { 5689 int uid = AppGlobals.getPackageManager() 5690 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5691 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5692 String msg = "Permission Denial: cancelIntentSender() from pid=" 5693 + Binder.getCallingPid() 5694 + ", uid=" + Binder.getCallingUid() 5695 + " is not allowed to cancel packges " 5696 + rec.key.packageName; 5697 Slog.w(TAG, msg); 5698 throw new SecurityException(msg); 5699 } 5700 } catch (RemoteException e) { 5701 throw new SecurityException(e); 5702 } 5703 cancelIntentSenderLocked(rec, true); 5704 } 5705 } 5706 5707 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5708 rec.canceled = true; 5709 mIntentSenderRecords.remove(rec.key); 5710 if (cleanActivity && rec.key.activity != null) { 5711 rec.key.activity.pendingResults.remove(rec.ref); 5712 } 5713 } 5714 5715 @Override 5716 public String getPackageForIntentSender(IIntentSender pendingResult) { 5717 if (!(pendingResult instanceof PendingIntentRecord)) { 5718 return null; 5719 } 5720 try { 5721 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5722 return res.key.packageName; 5723 } catch (ClassCastException e) { 5724 } 5725 return null; 5726 } 5727 5728 @Override 5729 public int getUidForIntentSender(IIntentSender sender) { 5730 if (sender instanceof PendingIntentRecord) { 5731 try { 5732 PendingIntentRecord res = (PendingIntentRecord)sender; 5733 return res.uid; 5734 } catch (ClassCastException e) { 5735 } 5736 } 5737 return -1; 5738 } 5739 5740 @Override 5741 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5742 if (!(pendingResult instanceof PendingIntentRecord)) { 5743 return false; 5744 } 5745 try { 5746 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5747 if (res.key.allIntents == null) { 5748 return false; 5749 } 5750 for (int i=0; i<res.key.allIntents.length; i++) { 5751 Intent intent = res.key.allIntents[i]; 5752 if (intent.getPackage() != null && intent.getComponent() != null) { 5753 return false; 5754 } 5755 } 5756 return true; 5757 } catch (ClassCastException e) { 5758 } 5759 return false; 5760 } 5761 5762 @Override 5763 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5764 if (!(pendingResult instanceof PendingIntentRecord)) { 5765 return false; 5766 } 5767 try { 5768 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5769 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5770 return true; 5771 } 5772 return false; 5773 } catch (ClassCastException e) { 5774 } 5775 return false; 5776 } 5777 5778 @Override 5779 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5780 if (!(pendingResult instanceof PendingIntentRecord)) { 5781 return null; 5782 } 5783 try { 5784 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5785 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5786 } catch (ClassCastException e) { 5787 } 5788 return null; 5789 } 5790 5791 @Override 5792 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5793 if (!(pendingResult instanceof PendingIntentRecord)) { 5794 return null; 5795 } 5796 try { 5797 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5798 Intent intent = res.key.requestIntent; 5799 if (intent != null) { 5800 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5801 || res.lastTagPrefix.equals(prefix))) { 5802 return res.lastTag; 5803 } 5804 res.lastTagPrefix = prefix; 5805 StringBuilder sb = new StringBuilder(128); 5806 if (prefix != null) { 5807 sb.append(prefix); 5808 } 5809 if (intent.getAction() != null) { 5810 sb.append(intent.getAction()); 5811 } else if (intent.getComponent() != null) { 5812 intent.getComponent().appendShortString(sb); 5813 } else { 5814 sb.append("?"); 5815 } 5816 return res.lastTag = sb.toString(); 5817 } 5818 } catch (ClassCastException e) { 5819 } 5820 return null; 5821 } 5822 5823 @Override 5824 public void setProcessLimit(int max) { 5825 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5826 "setProcessLimit()"); 5827 synchronized (this) { 5828 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5829 mProcessLimitOverride = max; 5830 } 5831 trimApplications(); 5832 } 5833 5834 @Override 5835 public int getProcessLimit() { 5836 synchronized (this) { 5837 return mProcessLimitOverride; 5838 } 5839 } 5840 5841 void foregroundTokenDied(ForegroundToken token) { 5842 synchronized (ActivityManagerService.this) { 5843 synchronized (mPidsSelfLocked) { 5844 ForegroundToken cur 5845 = mForegroundProcesses.get(token.pid); 5846 if (cur != token) { 5847 return; 5848 } 5849 mForegroundProcesses.remove(token.pid); 5850 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5851 if (pr == null) { 5852 return; 5853 } 5854 pr.forcingToForeground = null; 5855 updateProcessForegroundLocked(pr, false, false); 5856 } 5857 updateOomAdjLocked(); 5858 } 5859 } 5860 5861 @Override 5862 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5863 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5864 "setProcessForeground()"); 5865 synchronized(this) { 5866 boolean changed = false; 5867 5868 synchronized (mPidsSelfLocked) { 5869 ProcessRecord pr = mPidsSelfLocked.get(pid); 5870 if (pr == null && isForeground) { 5871 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5872 return; 5873 } 5874 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5875 if (oldToken != null) { 5876 oldToken.token.unlinkToDeath(oldToken, 0); 5877 mForegroundProcesses.remove(pid); 5878 if (pr != null) { 5879 pr.forcingToForeground = null; 5880 } 5881 changed = true; 5882 } 5883 if (isForeground && token != null) { 5884 ForegroundToken newToken = new ForegroundToken() { 5885 @Override 5886 public void binderDied() { 5887 foregroundTokenDied(this); 5888 } 5889 }; 5890 newToken.pid = pid; 5891 newToken.token = token; 5892 try { 5893 token.linkToDeath(newToken, 0); 5894 mForegroundProcesses.put(pid, newToken); 5895 pr.forcingToForeground = token; 5896 changed = true; 5897 } catch (RemoteException e) { 5898 // If the process died while doing this, we will later 5899 // do the cleanup with the process death link. 5900 } 5901 } 5902 } 5903 5904 if (changed) { 5905 updateOomAdjLocked(); 5906 } 5907 } 5908 } 5909 5910 // ========================================================= 5911 // PERMISSIONS 5912 // ========================================================= 5913 5914 static class PermissionController extends IPermissionController.Stub { 5915 ActivityManagerService mActivityManagerService; 5916 PermissionController(ActivityManagerService activityManagerService) { 5917 mActivityManagerService = activityManagerService; 5918 } 5919 5920 @Override 5921 public boolean checkPermission(String permission, int pid, int uid) { 5922 return mActivityManagerService.checkPermission(permission, pid, 5923 uid) == PackageManager.PERMISSION_GRANTED; 5924 } 5925 } 5926 5927 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5928 @Override 5929 public int checkComponentPermission(String permission, int pid, int uid, 5930 int owningUid, boolean exported) { 5931 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5932 owningUid, exported); 5933 } 5934 5935 @Override 5936 public Object getAMSLock() { 5937 return ActivityManagerService.this; 5938 } 5939 } 5940 5941 /** 5942 * This can be called with or without the global lock held. 5943 */ 5944 int checkComponentPermission(String permission, int pid, int uid, 5945 int owningUid, boolean exported) { 5946 // We might be performing an operation on behalf of an indirect binder 5947 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5948 // client identity accordingly before proceeding. 5949 Identity tlsIdentity = sCallerIdentity.get(); 5950 if (tlsIdentity != null) { 5951 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5952 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5953 uid = tlsIdentity.uid; 5954 pid = tlsIdentity.pid; 5955 } 5956 5957 if (pid == MY_PID) { 5958 return PackageManager.PERMISSION_GRANTED; 5959 } 5960 5961 return ActivityManager.checkComponentPermission(permission, uid, 5962 owningUid, exported); 5963 } 5964 5965 /** 5966 * As the only public entry point for permissions checking, this method 5967 * can enforce the semantic that requesting a check on a null global 5968 * permission is automatically denied. (Internally a null permission 5969 * string is used when calling {@link #checkComponentPermission} in cases 5970 * when only uid-based security is needed.) 5971 * 5972 * This can be called with or without the global lock held. 5973 */ 5974 @Override 5975 public int checkPermission(String permission, int pid, int uid) { 5976 if (permission == null) { 5977 return PackageManager.PERMISSION_DENIED; 5978 } 5979 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5980 } 5981 5982 /** 5983 * Binder IPC calls go through the public entry point. 5984 * This can be called with or without the global lock held. 5985 */ 5986 int checkCallingPermission(String permission) { 5987 return checkPermission(permission, 5988 Binder.getCallingPid(), 5989 UserHandle.getAppId(Binder.getCallingUid())); 5990 } 5991 5992 /** 5993 * This can be called with or without the global lock held. 5994 */ 5995 void enforceCallingPermission(String permission, String func) { 5996 if (checkCallingPermission(permission) 5997 == PackageManager.PERMISSION_GRANTED) { 5998 return; 5999 } 6000 6001 String msg = "Permission Denial: " + func + " from pid=" 6002 + Binder.getCallingPid() 6003 + ", uid=" + Binder.getCallingUid() 6004 + " requires " + permission; 6005 Slog.w(TAG, msg); 6006 throw new SecurityException(msg); 6007 } 6008 6009 /** 6010 * Determine if UID is holding permissions required to access {@link Uri} in 6011 * the given {@link ProviderInfo}. Final permission checking is always done 6012 * in {@link ContentProvider}. 6013 */ 6014 private final boolean checkHoldingPermissionsLocked( 6015 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6016 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6017 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6018 6019 if (pi.applicationInfo.uid == uid) { 6020 return true; 6021 } else if (!pi.exported) { 6022 return false; 6023 } 6024 6025 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6026 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6027 try { 6028 // check if target holds top-level <provider> permissions 6029 if (!readMet && pi.readPermission != null 6030 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6031 readMet = true; 6032 } 6033 if (!writeMet && pi.writePermission != null 6034 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6035 writeMet = true; 6036 } 6037 6038 // track if unprotected read/write is allowed; any denied 6039 // <path-permission> below removes this ability 6040 boolean allowDefaultRead = pi.readPermission == null; 6041 boolean allowDefaultWrite = pi.writePermission == null; 6042 6043 // check if target holds any <path-permission> that match uri 6044 final PathPermission[] pps = pi.pathPermissions; 6045 if (pps != null) { 6046 final String path = grantUri.uri.getPath(); 6047 int i = pps.length; 6048 while (i > 0 && (!readMet || !writeMet)) { 6049 i--; 6050 PathPermission pp = pps[i]; 6051 if (pp.match(path)) { 6052 if (!readMet) { 6053 final String pprperm = pp.getReadPermission(); 6054 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6055 + pprperm + " for " + pp.getPath() 6056 + ": match=" + pp.match(path) 6057 + " check=" + pm.checkUidPermission(pprperm, uid)); 6058 if (pprperm != null) { 6059 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 6060 readMet = true; 6061 } else { 6062 allowDefaultRead = false; 6063 } 6064 } 6065 } 6066 if (!writeMet) { 6067 final String ppwperm = pp.getWritePermission(); 6068 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6069 + ppwperm + " for " + pp.getPath() 6070 + ": match=" + pp.match(path) 6071 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6072 if (ppwperm != null) { 6073 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 6074 writeMet = true; 6075 } else { 6076 allowDefaultWrite = false; 6077 } 6078 } 6079 } 6080 } 6081 } 6082 } 6083 6084 // grant unprotected <provider> read/write, if not blocked by 6085 // <path-permission> above 6086 if (allowDefaultRead) readMet = true; 6087 if (allowDefaultWrite) writeMet = true; 6088 6089 } catch (RemoteException e) { 6090 return false; 6091 } 6092 6093 return readMet && writeMet; 6094 } 6095 6096 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6097 ProviderInfo pi = null; 6098 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6099 if (cpr != null) { 6100 pi = cpr.info; 6101 } else { 6102 try { 6103 pi = AppGlobals.getPackageManager().resolveContentProvider( 6104 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6105 } catch (RemoteException ex) { 6106 } 6107 } 6108 return pi; 6109 } 6110 6111 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6112 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6113 if (targetUris != null) { 6114 return targetUris.get(grantUri); 6115 } 6116 return null; 6117 } 6118 6119 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6120 String targetPkg, int targetUid, GrantUri grantUri) { 6121 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6122 if (targetUris == null) { 6123 targetUris = Maps.newArrayMap(); 6124 mGrantedUriPermissions.put(targetUid, targetUris); 6125 } 6126 6127 UriPermission perm = targetUris.get(grantUri); 6128 if (perm == null) { 6129 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6130 targetUris.put(grantUri, perm); 6131 } 6132 6133 return perm; 6134 } 6135 6136 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6137 final int modeFlags) { 6138 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6139 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6140 : UriPermission.STRENGTH_OWNED; 6141 6142 // Root gets to do everything. 6143 if (uid == 0) { 6144 return true; 6145 } 6146 6147 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6148 if (perms == null) return false; 6149 6150 // First look for exact match 6151 final UriPermission exactPerm = perms.get(grantUri); 6152 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6153 return true; 6154 } 6155 6156 // No exact match, look for prefixes 6157 final int N = perms.size(); 6158 for (int i = 0; i < N; i++) { 6159 final UriPermission perm = perms.valueAt(i); 6160 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6161 && perm.getStrength(modeFlags) >= minStrength) { 6162 return true; 6163 } 6164 } 6165 6166 return false; 6167 } 6168 6169 @Override 6170 public int checkUriPermission(Uri uri, int pid, int uid, 6171 final int modeFlags, int userId) { 6172 enforceNotIsolatedCaller("checkUriPermission"); 6173 6174 // Another redirected-binder-call permissions check as in 6175 // {@link checkComponentPermission}. 6176 Identity tlsIdentity = sCallerIdentity.get(); 6177 if (tlsIdentity != null) { 6178 uid = tlsIdentity.uid; 6179 pid = tlsIdentity.pid; 6180 } 6181 6182 // Our own process gets to do everything. 6183 if (pid == MY_PID) { 6184 return PackageManager.PERMISSION_GRANTED; 6185 } 6186 synchronized (this) { 6187 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6188 ? PackageManager.PERMISSION_GRANTED 6189 : PackageManager.PERMISSION_DENIED; 6190 } 6191 } 6192 6193 /** 6194 * Check if the targetPkg can be granted permission to access uri by 6195 * the callingUid using the given modeFlags. Throws a security exception 6196 * if callingUid is not allowed to do this. Returns the uid of the target 6197 * if the URI permission grant should be performed; returns -1 if it is not 6198 * needed (for example targetPkg already has permission to access the URI). 6199 * If you already know the uid of the target, you can supply it in 6200 * lastTargetUid else set that to -1. 6201 */ 6202 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6203 final int modeFlags, int lastTargetUid) { 6204 if (!Intent.isAccessUriMode(modeFlags)) { 6205 return -1; 6206 } 6207 6208 if (targetPkg != null) { 6209 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6210 "Checking grant " + targetPkg + " permission to " + grantUri); 6211 } 6212 6213 final IPackageManager pm = AppGlobals.getPackageManager(); 6214 6215 // If this is not a content: uri, we can't do anything with it. 6216 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6217 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6218 "Can't grant URI permission for non-content URI: " + grantUri); 6219 return -1; 6220 } 6221 6222 final String authority = grantUri.uri.getAuthority(); 6223 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6224 if (pi == null) { 6225 Slog.w(TAG, "No content provider found for permission check: " + 6226 grantUri.uri.toSafeString()); 6227 return -1; 6228 } 6229 6230 int targetUid = lastTargetUid; 6231 if (targetUid < 0 && targetPkg != null) { 6232 try { 6233 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6234 if (targetUid < 0) { 6235 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6236 "Can't grant URI permission no uid for: " + targetPkg); 6237 return -1; 6238 } 6239 } catch (RemoteException ex) { 6240 return -1; 6241 } 6242 } 6243 6244 if (targetUid >= 0) { 6245 // First... does the target actually need this permission? 6246 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6247 // No need to grant the target this permission. 6248 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6249 "Target " + targetPkg + " already has full permission to " + grantUri); 6250 return -1; 6251 } 6252 } else { 6253 // First... there is no target package, so can anyone access it? 6254 boolean allowed = pi.exported; 6255 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6256 if (pi.readPermission != null) { 6257 allowed = false; 6258 } 6259 } 6260 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6261 if (pi.writePermission != null) { 6262 allowed = false; 6263 } 6264 } 6265 if (allowed) { 6266 return -1; 6267 } 6268 } 6269 6270 // Second... is the provider allowing granting of URI permissions? 6271 if (!pi.grantUriPermissions) { 6272 throw new SecurityException("Provider " + pi.packageName 6273 + "/" + pi.name 6274 + " does not allow granting of Uri permissions (uri " 6275 + grantUri + ")"); 6276 } 6277 if (pi.uriPermissionPatterns != null) { 6278 final int N = pi.uriPermissionPatterns.length; 6279 boolean allowed = false; 6280 for (int i=0; i<N; i++) { 6281 if (pi.uriPermissionPatterns[i] != null 6282 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6283 allowed = true; 6284 break; 6285 } 6286 } 6287 if (!allowed) { 6288 throw new SecurityException("Provider " + pi.packageName 6289 + "/" + pi.name 6290 + " does not allow granting of permission to path of Uri " 6291 + grantUri); 6292 } 6293 } 6294 6295 // Third... does the caller itself have permission to access 6296 // this uri? 6297 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6298 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6299 // Require they hold a strong enough Uri permission 6300 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6301 throw new SecurityException("Uid " + callingUid 6302 + " does not have permission to uri " + grantUri); 6303 } 6304 } 6305 } 6306 return targetUid; 6307 } 6308 6309 @Override 6310 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6311 final int modeFlags, int userId) { 6312 enforceNotIsolatedCaller("checkGrantUriPermission"); 6313 synchronized(this) { 6314 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6315 new GrantUri(userId, uri, false), modeFlags, -1); 6316 } 6317 } 6318 6319 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6320 final int modeFlags, UriPermissionOwner owner) { 6321 if (!Intent.isAccessUriMode(modeFlags)) { 6322 return; 6323 } 6324 6325 // So here we are: the caller has the assumed permission 6326 // to the uri, and the target doesn't. Let's now give this to 6327 // the target. 6328 6329 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6330 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6331 6332 final String authority = grantUri.uri.getAuthority(); 6333 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6334 if (pi == null) { 6335 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6336 return; 6337 } 6338 6339 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6340 grantUri.prefix = true; 6341 } 6342 final UriPermission perm = findOrCreateUriPermissionLocked( 6343 pi.packageName, targetPkg, targetUid, grantUri); 6344 perm.grantModes(modeFlags, owner); 6345 } 6346 6347 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6348 final int modeFlags, UriPermissionOwner owner) { 6349 if (targetPkg == null) { 6350 throw new NullPointerException("targetPkg"); 6351 } 6352 6353 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6354 -1); 6355 if (targetUid < 0) { 6356 return; 6357 } 6358 6359 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6360 owner); 6361 } 6362 6363 static class NeededUriGrants extends ArrayList<GrantUri> { 6364 final String targetPkg; 6365 final int targetUid; 6366 final int flags; 6367 6368 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6369 this.targetPkg = targetPkg; 6370 this.targetUid = targetUid; 6371 this.flags = flags; 6372 } 6373 } 6374 6375 /** 6376 * Like checkGrantUriPermissionLocked, but takes an Intent. 6377 */ 6378 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6379 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6380 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6381 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6382 + " clip=" + (intent != null ? intent.getClipData() : null) 6383 + " from " + intent + "; flags=0x" 6384 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6385 6386 if (targetPkg == null) { 6387 throw new NullPointerException("targetPkg"); 6388 } 6389 6390 if (intent == null) { 6391 return null; 6392 } 6393 Uri data = intent.getData(); 6394 ClipData clip = intent.getClipData(); 6395 if (data == null && clip == null) { 6396 return null; 6397 } 6398 6399 if (data != null) { 6400 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data); 6401 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6402 needed != null ? needed.targetUid : -1); 6403 if (targetUid > 0) { 6404 if (needed == null) { 6405 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6406 } 6407 needed.add(grantUri); 6408 } 6409 } 6410 if (clip != null) { 6411 for (int i=0; i<clip.getItemCount(); i++) { 6412 Uri uri = clip.getItemAt(i).getUri(); 6413 if (uri != null) { 6414 int targetUid = -1; 6415 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri); 6416 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6417 needed != null ? needed.targetUid : -1); 6418 if (targetUid > 0) { 6419 if (needed == null) { 6420 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6421 } 6422 needed.add(grantUri); 6423 } 6424 } else { 6425 Intent clipIntent = clip.getItemAt(i).getIntent(); 6426 if (clipIntent != null) { 6427 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6428 callingUid, targetPkg, clipIntent, mode, needed); 6429 if (newNeeded != null) { 6430 needed = newNeeded; 6431 } 6432 } 6433 } 6434 } 6435 } 6436 6437 return needed; 6438 } 6439 6440 /** 6441 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6442 */ 6443 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6444 UriPermissionOwner owner) { 6445 if (needed != null) { 6446 for (int i=0; i<needed.size(); i++) { 6447 GrantUri grantUri = needed.get(i); 6448 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6449 grantUri, needed.flags, owner); 6450 } 6451 } 6452 } 6453 6454 void grantUriPermissionFromIntentLocked(int callingUid, 6455 String targetPkg, Intent intent, UriPermissionOwner owner) { 6456 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6457 intent, intent != null ? intent.getFlags() : 0, null); 6458 if (needed == null) { 6459 return; 6460 } 6461 6462 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6463 } 6464 6465 @Override 6466 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6467 final int modeFlags, int userId) { 6468 enforceNotIsolatedCaller("grantUriPermission"); 6469 GrantUri grantUri = new GrantUri(userId, uri, false); 6470 synchronized(this) { 6471 final ProcessRecord r = getRecordForAppLocked(caller); 6472 if (r == null) { 6473 throw new SecurityException("Unable to find app for caller " 6474 + caller 6475 + " when granting permission to uri " + grantUri); 6476 } 6477 if (targetPkg == null) { 6478 throw new IllegalArgumentException("null target"); 6479 } 6480 if (grantUri == null) { 6481 throw new IllegalArgumentException("null uri"); 6482 } 6483 6484 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6485 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6486 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6487 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6488 6489 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null); 6490 } 6491 } 6492 6493 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6494 if (perm.modeFlags == 0) { 6495 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6496 perm.targetUid); 6497 if (perms != null) { 6498 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6499 "Removing " + perm.targetUid + " permission to " + perm.uri); 6500 6501 perms.remove(perm.uri); 6502 if (perms.isEmpty()) { 6503 mGrantedUriPermissions.remove(perm.targetUid); 6504 } 6505 } 6506 } 6507 } 6508 6509 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 6510 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 6511 6512 final IPackageManager pm = AppGlobals.getPackageManager(); 6513 final String authority = grantUri.uri.getAuthority(); 6514 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6515 if (pi == null) { 6516 Slog.w(TAG, "No content provider found for permission revoke: " 6517 + grantUri.toSafeString()); 6518 return; 6519 } 6520 6521 // Does the caller have this permission on the URI? 6522 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6523 // Right now, if you are not the original owner of the permission, 6524 // you are not allowed to revoke it. 6525 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6526 throw new SecurityException("Uid " + callingUid 6527 + " does not have permission to uri " + grantUri); 6528 //} 6529 } 6530 6531 boolean persistChanged = false; 6532 6533 // Go through all of the permissions and remove any that match. 6534 int N = mGrantedUriPermissions.size(); 6535 for (int i = 0; i < N; i++) { 6536 final int targetUid = mGrantedUriPermissions.keyAt(i); 6537 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6538 6539 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6540 final UriPermission perm = it.next(); 6541 if (perm.uri.sourceUserId == grantUri.sourceUserId 6542 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 6543 if (DEBUG_URI_PERMISSION) 6544 Slog.v(TAG, 6545 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6546 persistChanged |= perm.revokeModes( 6547 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6548 if (perm.modeFlags == 0) { 6549 it.remove(); 6550 } 6551 } 6552 } 6553 6554 if (perms.isEmpty()) { 6555 mGrantedUriPermissions.remove(targetUid); 6556 N--; 6557 i--; 6558 } 6559 } 6560 6561 if (persistChanged) { 6562 schedulePersistUriGrants(); 6563 } 6564 } 6565 6566 @Override 6567 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 6568 int userId) { 6569 enforceNotIsolatedCaller("revokeUriPermission"); 6570 synchronized(this) { 6571 final ProcessRecord r = getRecordForAppLocked(caller); 6572 if (r == null) { 6573 throw new SecurityException("Unable to find app for caller " 6574 + caller 6575 + " when revoking permission to uri " + uri); 6576 } 6577 if (uri == null) { 6578 Slog.w(TAG, "revokeUriPermission: null uri"); 6579 return; 6580 } 6581 6582 if (!Intent.isAccessUriMode(modeFlags)) { 6583 return; 6584 } 6585 6586 final IPackageManager pm = AppGlobals.getPackageManager(); 6587 final String authority = uri.getAuthority(); 6588 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 6589 if (pi == null) { 6590 Slog.w(TAG, "No content provider found for permission revoke: " 6591 + uri.toSafeString()); 6592 return; 6593 } 6594 6595 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 6596 } 6597 } 6598 6599 /** 6600 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6601 * given package. 6602 * 6603 * @param packageName Package name to match, or {@code null} to apply to all 6604 * packages. 6605 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6606 * to all users. 6607 * @param persistable If persistable grants should be removed. 6608 */ 6609 private void removeUriPermissionsForPackageLocked( 6610 String packageName, int userHandle, boolean persistable) { 6611 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6612 throw new IllegalArgumentException("Must narrow by either package or user"); 6613 } 6614 6615 boolean persistChanged = false; 6616 6617 int N = mGrantedUriPermissions.size(); 6618 for (int i = 0; i < N; i++) { 6619 final int targetUid = mGrantedUriPermissions.keyAt(i); 6620 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6621 6622 // Only inspect grants matching user 6623 if (userHandle == UserHandle.USER_ALL 6624 || userHandle == UserHandle.getUserId(targetUid)) { 6625 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6626 final UriPermission perm = it.next(); 6627 6628 // Only inspect grants matching package 6629 if (packageName == null || perm.sourcePkg.equals(packageName) 6630 || perm.targetPkg.equals(packageName)) { 6631 persistChanged |= perm.revokeModes( 6632 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6633 6634 // Only remove when no modes remain; any persisted grants 6635 // will keep this alive. 6636 if (perm.modeFlags == 0) { 6637 it.remove(); 6638 } 6639 } 6640 } 6641 6642 if (perms.isEmpty()) { 6643 mGrantedUriPermissions.remove(targetUid); 6644 N--; 6645 i--; 6646 } 6647 } 6648 } 6649 6650 if (persistChanged) { 6651 schedulePersistUriGrants(); 6652 } 6653 } 6654 6655 @Override 6656 public IBinder newUriPermissionOwner(String name) { 6657 enforceNotIsolatedCaller("newUriPermissionOwner"); 6658 synchronized(this) { 6659 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6660 return owner.getExternalTokenLocked(); 6661 } 6662 } 6663 6664 @Override 6665 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 6666 final int modeFlags, int userId) { 6667 synchronized(this) { 6668 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6669 if (owner == null) { 6670 throw new IllegalArgumentException("Unknown owner: " + token); 6671 } 6672 if (fromUid != Binder.getCallingUid()) { 6673 if (Binder.getCallingUid() != Process.myUid()) { 6674 // Only system code can grant URI permissions on behalf 6675 // of other users. 6676 throw new SecurityException("nice try"); 6677 } 6678 } 6679 if (targetPkg == null) { 6680 throw new IllegalArgumentException("null target"); 6681 } 6682 if (uri == null) { 6683 throw new IllegalArgumentException("null uri"); 6684 } 6685 6686 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false), 6687 modeFlags, owner); 6688 } 6689 } 6690 6691 @Override 6692 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 6693 synchronized(this) { 6694 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6695 if (owner == null) { 6696 throw new IllegalArgumentException("Unknown owner: " + token); 6697 } 6698 6699 if (uri == null) { 6700 owner.removeUriPermissionsLocked(mode); 6701 } else { 6702 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 6703 } 6704 } 6705 } 6706 6707 private void schedulePersistUriGrants() { 6708 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6709 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6710 10 * DateUtils.SECOND_IN_MILLIS); 6711 } 6712 } 6713 6714 private void writeGrantedUriPermissions() { 6715 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6716 6717 // Snapshot permissions so we can persist without lock 6718 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6719 synchronized (this) { 6720 final int size = mGrantedUriPermissions.size(); 6721 for (int i = 0; i < size; i++) { 6722 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6723 for (UriPermission perm : perms.values()) { 6724 if (perm.persistedModeFlags != 0) { 6725 persist.add(perm.snapshot()); 6726 } 6727 } 6728 } 6729 } 6730 6731 FileOutputStream fos = null; 6732 try { 6733 fos = mGrantFile.startWrite(); 6734 6735 XmlSerializer out = new FastXmlSerializer(); 6736 out.setOutput(fos, "utf-8"); 6737 out.startDocument(null, true); 6738 out.startTag(null, TAG_URI_GRANTS); 6739 for (UriPermission.Snapshot perm : persist) { 6740 out.startTag(null, TAG_URI_GRANT); 6741 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 6742 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 6743 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6744 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6745 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6746 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6747 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6748 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6749 out.endTag(null, TAG_URI_GRANT); 6750 } 6751 out.endTag(null, TAG_URI_GRANTS); 6752 out.endDocument(); 6753 6754 mGrantFile.finishWrite(fos); 6755 } catch (IOException e) { 6756 if (fos != null) { 6757 mGrantFile.failWrite(fos); 6758 } 6759 } 6760 } 6761 6762 private void readGrantedUriPermissionsLocked() { 6763 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6764 6765 final long now = System.currentTimeMillis(); 6766 6767 FileInputStream fis = null; 6768 try { 6769 fis = mGrantFile.openRead(); 6770 final XmlPullParser in = Xml.newPullParser(); 6771 in.setInput(fis, null); 6772 6773 int type; 6774 while ((type = in.next()) != END_DOCUMENT) { 6775 final String tag = in.getName(); 6776 if (type == START_TAG) { 6777 if (TAG_URI_GRANT.equals(tag)) { 6778 final int sourceUserId; 6779 final int targetUserId; 6780 final int userHandle = readIntAttribute(in, 6781 ATTR_USER_HANDLE, UserHandle.USER_NULL); 6782 if (userHandle != UserHandle.USER_NULL) { 6783 // For backwards compatibility. 6784 sourceUserId = userHandle; 6785 targetUserId = userHandle; 6786 } else { 6787 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 6788 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 6789 } 6790 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6791 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6792 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6793 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6794 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6795 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6796 6797 // Sanity check that provider still belongs to source package 6798 final ProviderInfo pi = getProviderInfoLocked( 6799 uri.getAuthority(), sourceUserId); 6800 if (pi != null && sourcePkg.equals(pi.packageName)) { 6801 int targetUid = -1; 6802 try { 6803 targetUid = AppGlobals.getPackageManager() 6804 .getPackageUid(targetPkg, targetUserId); 6805 } catch (RemoteException e) { 6806 } 6807 if (targetUid != -1) { 6808 final UriPermission perm = findOrCreateUriPermissionLocked( 6809 sourcePkg, targetPkg, targetUid, 6810 new GrantUri(sourceUserId, uri, prefix)); 6811 perm.initPersistedModes(modeFlags, createdTime); 6812 } 6813 } else { 6814 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6815 + " but instead found " + pi); 6816 } 6817 } 6818 } 6819 } 6820 } catch (FileNotFoundException e) { 6821 // Missing grants is okay 6822 } catch (IOException e) { 6823 Log.wtf(TAG, "Failed reading Uri grants", e); 6824 } catch (XmlPullParserException e) { 6825 Log.wtf(TAG, "Failed reading Uri grants", e); 6826 } finally { 6827 IoUtils.closeQuietly(fis); 6828 } 6829 } 6830 6831 @Override 6832 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6833 enforceNotIsolatedCaller("takePersistableUriPermission"); 6834 6835 Preconditions.checkFlagsArgument(modeFlags, 6836 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6837 6838 synchronized (this) { 6839 final int callingUid = Binder.getCallingUid(); 6840 boolean persistChanged = false; 6841 GrantUri grantUri = new GrantUri(userId, uri, false); 6842 6843 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6844 new GrantUri(userId, uri, false)); 6845 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6846 new GrantUri(userId, uri, true)); 6847 6848 final boolean exactValid = (exactPerm != null) 6849 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6850 final boolean prefixValid = (prefixPerm != null) 6851 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6852 6853 if (!(exactValid || prefixValid)) { 6854 throw new SecurityException("No persistable permission grants found for UID " 6855 + callingUid + " and Uri " + grantUri.toSafeString()); 6856 } 6857 6858 if (exactValid) { 6859 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6860 } 6861 if (prefixValid) { 6862 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6863 } 6864 6865 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6866 6867 if (persistChanged) { 6868 schedulePersistUriGrants(); 6869 } 6870 } 6871 } 6872 6873 @Override 6874 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6875 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6876 6877 Preconditions.checkFlagsArgument(modeFlags, 6878 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6879 6880 synchronized (this) { 6881 final int callingUid = Binder.getCallingUid(); 6882 boolean persistChanged = false; 6883 6884 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6885 new GrantUri(userId, uri, false)); 6886 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6887 new GrantUri(userId, uri, true)); 6888 if (exactPerm == null && prefixPerm == null) { 6889 throw new SecurityException("No permission grants found for UID " + callingUid 6890 + " and Uri " + uri.toSafeString()); 6891 } 6892 6893 if (exactPerm != null) { 6894 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6895 removeUriPermissionIfNeededLocked(exactPerm); 6896 } 6897 if (prefixPerm != null) { 6898 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6899 removeUriPermissionIfNeededLocked(prefixPerm); 6900 } 6901 6902 if (persistChanged) { 6903 schedulePersistUriGrants(); 6904 } 6905 } 6906 } 6907 6908 /** 6909 * Prune any older {@link UriPermission} for the given UID until outstanding 6910 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6911 * 6912 * @return if any mutations occured that require persisting. 6913 */ 6914 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6915 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6916 if (perms == null) return false; 6917 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6918 6919 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6920 for (UriPermission perm : perms.values()) { 6921 if (perm.persistedModeFlags != 0) { 6922 persisted.add(perm); 6923 } 6924 } 6925 6926 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6927 if (trimCount <= 0) return false; 6928 6929 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6930 for (int i = 0; i < trimCount; i++) { 6931 final UriPermission perm = persisted.get(i); 6932 6933 if (DEBUG_URI_PERMISSION) { 6934 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6935 } 6936 6937 perm.releasePersistableModes(~0); 6938 removeUriPermissionIfNeededLocked(perm); 6939 } 6940 6941 return true; 6942 } 6943 6944 @Override 6945 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6946 String packageName, boolean incoming) { 6947 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6948 Preconditions.checkNotNull(packageName, "packageName"); 6949 6950 final int callingUid = Binder.getCallingUid(); 6951 final IPackageManager pm = AppGlobals.getPackageManager(); 6952 try { 6953 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6954 if (packageUid != callingUid) { 6955 throw new SecurityException( 6956 "Package " + packageName + " does not belong to calling UID " + callingUid); 6957 } 6958 } catch (RemoteException e) { 6959 throw new SecurityException("Failed to verify package name ownership"); 6960 } 6961 6962 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6963 synchronized (this) { 6964 if (incoming) { 6965 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6966 callingUid); 6967 if (perms == null) { 6968 Slog.w(TAG, "No permission grants found for " + packageName); 6969 } else { 6970 for (UriPermission perm : perms.values()) { 6971 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6972 result.add(perm.buildPersistedPublicApiObject()); 6973 } 6974 } 6975 } 6976 } else { 6977 final int size = mGrantedUriPermissions.size(); 6978 for (int i = 0; i < size; i++) { 6979 final ArrayMap<GrantUri, UriPermission> perms = 6980 mGrantedUriPermissions.valueAt(i); 6981 for (UriPermission perm : perms.values()) { 6982 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6983 result.add(perm.buildPersistedPublicApiObject()); 6984 } 6985 } 6986 } 6987 } 6988 } 6989 return new ParceledListSlice<android.content.UriPermission>(result); 6990 } 6991 6992 @Override 6993 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6994 synchronized (this) { 6995 ProcessRecord app = 6996 who != null ? getRecordForAppLocked(who) : null; 6997 if (app == null) return; 6998 6999 Message msg = Message.obtain(); 7000 msg.what = WAIT_FOR_DEBUGGER_MSG; 7001 msg.obj = app; 7002 msg.arg1 = waiting ? 1 : 0; 7003 mHandler.sendMessage(msg); 7004 } 7005 } 7006 7007 @Override 7008 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7009 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7010 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7011 outInfo.availMem = Process.getFreeMemory(); 7012 outInfo.totalMem = Process.getTotalMemory(); 7013 outInfo.threshold = homeAppMem; 7014 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7015 outInfo.hiddenAppThreshold = cachedAppMem; 7016 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7017 ProcessList.SERVICE_ADJ); 7018 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7019 ProcessList.VISIBLE_APP_ADJ); 7020 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7021 ProcessList.FOREGROUND_APP_ADJ); 7022 } 7023 7024 // ========================================================= 7025 // TASK MANAGEMENT 7026 // ========================================================= 7027 7028 @Override 7029 public List<IAppTask> getAppTasks() { 7030 int callingUid = Binder.getCallingUid(); 7031 long ident = Binder.clearCallingIdentity(); 7032 synchronized(this) { 7033 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7034 try { 7035 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7036 7037 final int N = mRecentTasks.size(); 7038 for (int i = 0; i < N; i++) { 7039 TaskRecord tr = mRecentTasks.get(i); 7040 // Skip tasks that are not created by the caller 7041 if (tr.creatorUid == callingUid) { 7042 ActivityManager.RecentTaskInfo taskInfo = 7043 createRecentTaskInfoFromTaskRecord(tr); 7044 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7045 list.add(taskImpl); 7046 } 7047 } 7048 } finally { 7049 Binder.restoreCallingIdentity(ident); 7050 } 7051 return list; 7052 } 7053 } 7054 7055 @Override 7056 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7057 final int callingUid = Binder.getCallingUid(); 7058 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7059 7060 synchronized(this) { 7061 if (localLOGV) Slog.v( 7062 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7063 7064 final boolean allowed = checkCallingPermission( 7065 android.Manifest.permission.GET_TASKS) 7066 == PackageManager.PERMISSION_GRANTED; 7067 if (!allowed) { 7068 Slog.w(TAG, "getTasks: caller " + callingUid 7069 + " does not hold GET_TASKS; limiting output"); 7070 } 7071 7072 // TODO: Improve with MRU list from all ActivityStacks. 7073 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7074 } 7075 7076 return list; 7077 } 7078 7079 TaskRecord getMostRecentTask() { 7080 return mRecentTasks.get(0); 7081 } 7082 7083 /** 7084 * Creates a new RecentTaskInfo from a TaskRecord. 7085 */ 7086 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7087 ActivityManager.RecentTaskInfo rti 7088 = new ActivityManager.RecentTaskInfo(); 7089 rti.id = tr.mActivities.isEmpty() ? -1 : tr.taskId; 7090 rti.persistentId = tr.taskId; 7091 rti.baseIntent = new Intent(tr.getBaseIntent()); 7092 rti.origActivity = tr.origActivity; 7093 rti.description = tr.lastDescription; 7094 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 7095 rti.userId = tr.userId; 7096 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7097 return rti; 7098 } 7099 7100 @Override 7101 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7102 int flags, int userId) { 7103 final int callingUid = Binder.getCallingUid(); 7104 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7105 false, true, "getRecentTasks", null); 7106 7107 synchronized (this) { 7108 final boolean allowed = checkCallingPermission( 7109 android.Manifest.permission.GET_TASKS) 7110 == PackageManager.PERMISSION_GRANTED; 7111 if (!allowed) { 7112 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7113 + " does not hold GET_TASKS; limiting output"); 7114 } 7115 final boolean detailed = checkCallingPermission( 7116 android.Manifest.permission.GET_DETAILED_TASKS) 7117 == PackageManager.PERMISSION_GRANTED; 7118 7119 IPackageManager pm = AppGlobals.getPackageManager(); 7120 7121 final int N = mRecentTasks.size(); 7122 ArrayList<ActivityManager.RecentTaskInfo> res 7123 = new ArrayList<ActivityManager.RecentTaskInfo>( 7124 maxNum < N ? maxNum : N); 7125 7126 final Set<Integer> includedUsers; 7127 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7128 includedUsers = getProfileIdsLocked(userId); 7129 } else { 7130 includedUsers = new HashSet<Integer>(); 7131 } 7132 includedUsers.add(Integer.valueOf(userId)); 7133 for (int i=0; i<N && maxNum > 0; i++) { 7134 TaskRecord tr = mRecentTasks.get(i); 7135 // Only add calling user or related users recent tasks 7136 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7137 7138 // Return the entry if desired by the caller. We always return 7139 // the first entry, because callers always expect this to be the 7140 // foreground app. We may filter others if the caller has 7141 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7142 // we should exclude the entry. 7143 7144 if (i == 0 7145 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7146 || (tr.intent == null) 7147 || ((tr.intent.getFlags() 7148 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7149 if (!allowed) { 7150 // If the caller doesn't have the GET_TASKS permission, then only 7151 // allow them to see a small subset of tasks -- their own and home. 7152 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7153 continue; 7154 } 7155 } 7156 7157 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7158 if (!detailed) { 7159 rti.baseIntent.replaceExtras((Bundle)null); 7160 } 7161 7162 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7163 // Check whether this activity is currently available. 7164 try { 7165 if (rti.origActivity != null) { 7166 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7167 == null) { 7168 continue; 7169 } 7170 } else if (rti.baseIntent != null) { 7171 if (pm.queryIntentActivities(rti.baseIntent, 7172 null, 0, userId) == null) { 7173 continue; 7174 } 7175 } 7176 } catch (RemoteException e) { 7177 // Will never happen. 7178 } 7179 } 7180 7181 res.add(rti); 7182 maxNum--; 7183 } 7184 } 7185 return res; 7186 } 7187 } 7188 7189 private TaskRecord recentTaskForIdLocked(int id) { 7190 final int N = mRecentTasks.size(); 7191 for (int i=0; i<N; i++) { 7192 TaskRecord tr = mRecentTasks.get(i); 7193 if (tr.taskId == id) { 7194 return tr; 7195 } 7196 } 7197 return null; 7198 } 7199 7200 @Override 7201 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7202 synchronized (this) { 7203 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7204 "getTaskThumbnails()"); 7205 TaskRecord tr = recentTaskForIdLocked(id); 7206 if (tr != null) { 7207 return tr.getTaskThumbnailsLocked(); 7208 } 7209 } 7210 return null; 7211 } 7212 7213 @Override 7214 public Bitmap getTaskTopThumbnail(int id) { 7215 synchronized (this) { 7216 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7217 "getTaskTopThumbnail()"); 7218 TaskRecord tr = recentTaskForIdLocked(id); 7219 if (tr != null) { 7220 return tr.getTaskTopThumbnailLocked(); 7221 } 7222 } 7223 return null; 7224 } 7225 7226 @Override 7227 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 7228 synchronized (this) { 7229 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7230 if (r != null) { 7231 r.taskDescription = td; 7232 r.task.updateTaskDescription(); 7233 } 7234 } 7235 } 7236 7237 @Override 7238 public boolean removeSubTask(int taskId, int subTaskIndex) { 7239 synchronized (this) { 7240 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7241 "removeSubTask()"); 7242 long ident = Binder.clearCallingIdentity(); 7243 try { 7244 TaskRecord tr = recentTaskForIdLocked(taskId); 7245 if (tr != null) { 7246 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7247 } 7248 return false; 7249 } finally { 7250 Binder.restoreCallingIdentity(ident); 7251 } 7252 } 7253 } 7254 7255 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7256 if (!pr.killedByAm) { 7257 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7258 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7259 pr.processName, pr.setAdj, reason); 7260 pr.killedByAm = true; 7261 Process.killProcessQuiet(pr.pid); 7262 } 7263 } 7264 7265 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7266 tr.disposeThumbnail(); 7267 mRecentTasks.remove(tr); 7268 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7269 Intent baseIntent = new Intent( 7270 tr.intent != null ? tr.intent : tr.affinityIntent); 7271 ComponentName component = baseIntent.getComponent(); 7272 if (component == null) { 7273 Slog.w(TAG, "Now component for base intent of task: " + tr); 7274 return; 7275 } 7276 7277 // Find any running services associated with this app. 7278 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7279 7280 if (killProcesses) { 7281 // Find any running processes associated with this app. 7282 final String pkg = component.getPackageName(); 7283 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7284 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7285 for (int i=0; i<pmap.size(); i++) { 7286 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7287 for (int j=0; j<uids.size(); j++) { 7288 ProcessRecord proc = uids.valueAt(j); 7289 if (proc.userId != tr.userId) { 7290 continue; 7291 } 7292 if (!proc.pkgList.containsKey(pkg)) { 7293 continue; 7294 } 7295 procs.add(proc); 7296 } 7297 } 7298 7299 // Kill the running processes. 7300 for (int i=0; i<procs.size(); i++) { 7301 ProcessRecord pr = procs.get(i); 7302 if (pr == mHomeProcess) { 7303 // Don't kill the home process along with tasks from the same package. 7304 continue; 7305 } 7306 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7307 killUnneededProcessLocked(pr, "remove task"); 7308 } else { 7309 pr.waitingToKill = "remove task"; 7310 } 7311 } 7312 } 7313 } 7314 7315 /** 7316 * Removes the task with the specified task id. 7317 * 7318 * @param taskId Identifier of the task to be removed. 7319 * @param flags Additional operational flags. May be 0 or 7320 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7321 * @return Returns true if the given task was found and removed. 7322 */ 7323 private boolean removeTaskByIdLocked(int taskId, int flags) { 7324 TaskRecord tr = recentTaskForIdLocked(taskId); 7325 if (tr != null) { 7326 tr.removeTaskActivitiesLocked(-1, false); 7327 cleanUpRemovedTaskLocked(tr, flags); 7328 if (tr.isPersistable) { 7329 notifyTaskPersisterLocked(tr, true); 7330 } 7331 return true; 7332 } 7333 return false; 7334 } 7335 7336 @Override 7337 public boolean removeTask(int taskId, int flags) { 7338 synchronized (this) { 7339 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7340 "removeTask()"); 7341 long ident = Binder.clearCallingIdentity(); 7342 try { 7343 return removeTaskByIdLocked(taskId, flags); 7344 } finally { 7345 Binder.restoreCallingIdentity(ident); 7346 } 7347 } 7348 } 7349 7350 /** 7351 * TODO: Add mController hook 7352 */ 7353 @Override 7354 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7355 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7356 "moveTaskToFront()"); 7357 7358 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7359 synchronized(this) { 7360 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7361 Binder.getCallingUid(), "Task to front")) { 7362 ActivityOptions.abort(options); 7363 return; 7364 } 7365 final long origId = Binder.clearCallingIdentity(); 7366 try { 7367 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7368 if (task == null) { 7369 return; 7370 } 7371 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7372 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7373 return; 7374 } 7375 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7376 } finally { 7377 Binder.restoreCallingIdentity(origId); 7378 } 7379 ActivityOptions.abort(options); 7380 } 7381 } 7382 7383 @Override 7384 public void moveTaskToBack(int taskId) { 7385 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7386 "moveTaskToBack()"); 7387 7388 synchronized(this) { 7389 TaskRecord tr = recentTaskForIdLocked(taskId); 7390 if (tr != null) { 7391 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7392 ActivityStack stack = tr.stack; 7393 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7394 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7395 Binder.getCallingUid(), "Task to back")) { 7396 return; 7397 } 7398 } 7399 final long origId = Binder.clearCallingIdentity(); 7400 try { 7401 stack.moveTaskToBackLocked(taskId, null); 7402 } finally { 7403 Binder.restoreCallingIdentity(origId); 7404 } 7405 } 7406 } 7407 } 7408 7409 /** 7410 * Moves an activity, and all of the other activities within the same task, to the bottom 7411 * of the history stack. The activity's order within the task is unchanged. 7412 * 7413 * @param token A reference to the activity we wish to move 7414 * @param nonRoot If false then this only works if the activity is the root 7415 * of a task; if true it will work for any activity in a task. 7416 * @return Returns true if the move completed, false if not. 7417 */ 7418 @Override 7419 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7420 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7421 synchronized(this) { 7422 final long origId = Binder.clearCallingIdentity(); 7423 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7424 if (taskId >= 0) { 7425 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7426 } 7427 Binder.restoreCallingIdentity(origId); 7428 } 7429 return false; 7430 } 7431 7432 @Override 7433 public void moveTaskBackwards(int task) { 7434 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7435 "moveTaskBackwards()"); 7436 7437 synchronized(this) { 7438 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7439 Binder.getCallingUid(), "Task backwards")) { 7440 return; 7441 } 7442 final long origId = Binder.clearCallingIdentity(); 7443 moveTaskBackwardsLocked(task); 7444 Binder.restoreCallingIdentity(origId); 7445 } 7446 } 7447 7448 private final void moveTaskBackwardsLocked(int task) { 7449 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7450 } 7451 7452 @Override 7453 public IBinder getHomeActivityToken() throws RemoteException { 7454 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7455 "getHomeActivityToken()"); 7456 synchronized (this) { 7457 return mStackSupervisor.getHomeActivityToken(); 7458 } 7459 } 7460 7461 @Override 7462 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7463 IActivityContainerCallback callback) throws RemoteException { 7464 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7465 "createActivityContainer()"); 7466 synchronized (this) { 7467 if (parentActivityToken == null) { 7468 throw new IllegalArgumentException("parent token must not be null"); 7469 } 7470 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7471 if (r == null) { 7472 return null; 7473 } 7474 if (callback == null) { 7475 throw new IllegalArgumentException("callback must not be null"); 7476 } 7477 return mStackSupervisor.createActivityContainer(r, callback); 7478 } 7479 } 7480 7481 @Override 7482 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7483 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7484 "deleteActivityContainer()"); 7485 synchronized (this) { 7486 mStackSupervisor.deleteActivityContainer(container); 7487 } 7488 } 7489 7490 @Override 7491 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7492 throws RemoteException { 7493 synchronized (this) { 7494 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7495 if (stack != null) { 7496 return stack.mActivityContainer; 7497 } 7498 return null; 7499 } 7500 } 7501 7502 @Override 7503 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7504 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7505 "moveTaskToStack()"); 7506 if (stackId == HOME_STACK_ID) { 7507 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7508 new RuntimeException("here").fillInStackTrace()); 7509 } 7510 synchronized (this) { 7511 long ident = Binder.clearCallingIdentity(); 7512 try { 7513 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7514 + stackId + " toTop=" + toTop); 7515 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7516 } finally { 7517 Binder.restoreCallingIdentity(ident); 7518 } 7519 } 7520 } 7521 7522 @Override 7523 public void resizeStack(int stackBoxId, Rect bounds) { 7524 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7525 "resizeStackBox()"); 7526 long ident = Binder.clearCallingIdentity(); 7527 try { 7528 mWindowManager.resizeStack(stackBoxId, bounds); 7529 } finally { 7530 Binder.restoreCallingIdentity(ident); 7531 } 7532 } 7533 7534 @Override 7535 public List<StackInfo> getAllStackInfos() { 7536 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7537 "getAllStackInfos()"); 7538 long ident = Binder.clearCallingIdentity(); 7539 try { 7540 synchronized (this) { 7541 return mStackSupervisor.getAllStackInfosLocked(); 7542 } 7543 } finally { 7544 Binder.restoreCallingIdentity(ident); 7545 } 7546 } 7547 7548 @Override 7549 public StackInfo getStackInfo(int stackId) { 7550 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7551 "getStackInfo()"); 7552 long ident = Binder.clearCallingIdentity(); 7553 try { 7554 synchronized (this) { 7555 return mStackSupervisor.getStackInfoLocked(stackId); 7556 } 7557 } finally { 7558 Binder.restoreCallingIdentity(ident); 7559 } 7560 } 7561 7562 @Override 7563 public boolean isInHomeStack(int taskId) { 7564 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7565 "getStackInfo()"); 7566 long ident = Binder.clearCallingIdentity(); 7567 try { 7568 synchronized (this) { 7569 TaskRecord tr = recentTaskForIdLocked(taskId); 7570 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 7571 } 7572 } finally { 7573 Binder.restoreCallingIdentity(ident); 7574 } 7575 } 7576 7577 @Override 7578 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7579 synchronized(this) { 7580 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7581 } 7582 } 7583 7584 private boolean isLockTaskAuthorized(ComponentName name) { 7585// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7586// "startLockTaskMode()"); 7587// DevicePolicyManager dpm = (DevicePolicyManager) 7588// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7589// return dpm != null && dpm.isLockTaskPermitted(name); 7590 return true; 7591 } 7592 7593 private void startLockTaskMode(TaskRecord task) { 7594 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7595 return; 7596 } 7597 long ident = Binder.clearCallingIdentity(); 7598 try { 7599 synchronized (this) { 7600 // Since we lost lock on task, make sure it is still there. 7601 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7602 if (task != null) { 7603 mStackSupervisor.setLockTaskModeLocked(task); 7604 } 7605 } 7606 } finally { 7607 Binder.restoreCallingIdentity(ident); 7608 } 7609 } 7610 7611 @Override 7612 public void startLockTaskMode(int taskId) { 7613 long ident = Binder.clearCallingIdentity(); 7614 try { 7615 final TaskRecord task; 7616 synchronized (this) { 7617 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7618 } 7619 if (task != null) { 7620 startLockTaskMode(task); 7621 } 7622 } finally { 7623 Binder.restoreCallingIdentity(ident); 7624 } 7625 } 7626 7627 @Override 7628 public void startLockTaskMode(IBinder token) { 7629 long ident = Binder.clearCallingIdentity(); 7630 try { 7631 final TaskRecord task; 7632 synchronized (this) { 7633 final ActivityRecord r = ActivityRecord.forToken(token); 7634 if (r == null) { 7635 return; 7636 } 7637 task = r.task; 7638 } 7639 if (task != null) { 7640 startLockTaskMode(task); 7641 } 7642 } finally { 7643 Binder.restoreCallingIdentity(ident); 7644 } 7645 } 7646 7647 @Override 7648 public void stopLockTaskMode() { 7649// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7650// "stopLockTaskMode()"); 7651 synchronized (this) { 7652 mStackSupervisor.setLockTaskModeLocked(null); 7653 } 7654 } 7655 7656 @Override 7657 public boolean isInLockTaskMode() { 7658 synchronized (this) { 7659 return mStackSupervisor.isInLockTaskMode(); 7660 } 7661 } 7662 7663 // ========================================================= 7664 // CONTENT PROVIDERS 7665 // ========================================================= 7666 7667 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7668 List<ProviderInfo> providers = null; 7669 try { 7670 providers = AppGlobals.getPackageManager(). 7671 queryContentProviders(app.processName, app.uid, 7672 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7673 } catch (RemoteException ex) { 7674 } 7675 if (DEBUG_MU) 7676 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7677 int userId = app.userId; 7678 if (providers != null) { 7679 int N = providers.size(); 7680 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7681 for (int i=0; i<N; i++) { 7682 ProviderInfo cpi = 7683 (ProviderInfo)providers.get(i); 7684 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7685 cpi.name, cpi.flags); 7686 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7687 // This is a singleton provider, but a user besides the 7688 // default user is asking to initialize a process it runs 7689 // in... well, no, it doesn't actually run in this process, 7690 // it runs in the process of the default user. Get rid of it. 7691 providers.remove(i); 7692 N--; 7693 i--; 7694 continue; 7695 } 7696 7697 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7698 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7699 if (cpr == null) { 7700 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7701 mProviderMap.putProviderByClass(comp, cpr); 7702 } 7703 if (DEBUG_MU) 7704 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7705 app.pubProviders.put(cpi.name, cpr); 7706 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7707 // Don't add this if it is a platform component that is marked 7708 // to run in multiple processes, because this is actually 7709 // part of the framework so doesn't make sense to track as a 7710 // separate apk in the process. 7711 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7712 } 7713 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7714 } 7715 } 7716 return providers; 7717 } 7718 7719 /** 7720 * Check if {@link ProcessRecord} has a possible chance at accessing the 7721 * given {@link ProviderInfo}. Final permission checking is always done 7722 * in {@link ContentProvider}. 7723 */ 7724 private final String checkContentProviderPermissionLocked( 7725 ProviderInfo cpi, ProcessRecord r, int userId) { 7726 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7727 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7728 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7729 // Looking for cross-user grants before to enforce the typical cross-users permissions 7730 if (userId != UserHandle.getUserId(callingUid)) { 7731 if (perms != null) { 7732 for (GrantUri grantUri : perms.keySet()) { 7733 if (grantUri.sourceUserId == userId) { 7734 String authority = grantUri.uri.getAuthority(); 7735 if (authority.equals(cpi.authority)) { 7736 return null; 7737 } 7738 } 7739 } 7740 } 7741 } 7742 userId = handleIncomingUser(callingPid, callingUid, userId, 7743 false, true, "checkContentProviderPermissionLocked", null); 7744 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7745 cpi.applicationInfo.uid, cpi.exported) 7746 == PackageManager.PERMISSION_GRANTED) { 7747 return null; 7748 } 7749 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7750 cpi.applicationInfo.uid, cpi.exported) 7751 == PackageManager.PERMISSION_GRANTED) { 7752 return null; 7753 } 7754 7755 PathPermission[] pps = cpi.pathPermissions; 7756 if (pps != null) { 7757 int i = pps.length; 7758 while (i > 0) { 7759 i--; 7760 PathPermission pp = pps[i]; 7761 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7762 cpi.applicationInfo.uid, cpi.exported) 7763 == PackageManager.PERMISSION_GRANTED) { 7764 return null; 7765 } 7766 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7767 cpi.applicationInfo.uid, cpi.exported) 7768 == PackageManager.PERMISSION_GRANTED) { 7769 return null; 7770 } 7771 } 7772 } 7773 7774 if (perms != null) { 7775 for (GrantUri grantUri : perms.keySet()) { 7776 if (grantUri.uri.getAuthority().equals(cpi.authority)) { 7777 return null; 7778 } 7779 } 7780 } 7781 7782 String msg; 7783 if (!cpi.exported) { 7784 msg = "Permission Denial: opening provider " + cpi.name 7785 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7786 + ", uid=" + callingUid + ") that is not exported from uid " 7787 + cpi.applicationInfo.uid; 7788 } else { 7789 msg = "Permission Denial: opening provider " + cpi.name 7790 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7791 + ", uid=" + callingUid + ") requires " 7792 + cpi.readPermission + " or " + cpi.writePermission; 7793 } 7794 Slog.w(TAG, msg); 7795 return msg; 7796 } 7797 7798 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7799 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7800 if (r != null) { 7801 for (int i=0; i<r.conProviders.size(); i++) { 7802 ContentProviderConnection conn = r.conProviders.get(i); 7803 if (conn.provider == cpr) { 7804 if (DEBUG_PROVIDER) Slog.v(TAG, 7805 "Adding provider requested by " 7806 + r.processName + " from process " 7807 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7808 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7809 if (stable) { 7810 conn.stableCount++; 7811 conn.numStableIncs++; 7812 } else { 7813 conn.unstableCount++; 7814 conn.numUnstableIncs++; 7815 } 7816 return conn; 7817 } 7818 } 7819 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7820 if (stable) { 7821 conn.stableCount = 1; 7822 conn.numStableIncs = 1; 7823 } else { 7824 conn.unstableCount = 1; 7825 conn.numUnstableIncs = 1; 7826 } 7827 cpr.connections.add(conn); 7828 r.conProviders.add(conn); 7829 return conn; 7830 } 7831 cpr.addExternalProcessHandleLocked(externalProcessToken); 7832 return null; 7833 } 7834 7835 boolean decProviderCountLocked(ContentProviderConnection conn, 7836 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7837 if (conn != null) { 7838 cpr = conn.provider; 7839 if (DEBUG_PROVIDER) Slog.v(TAG, 7840 "Removing provider requested by " 7841 + conn.client.processName + " from process " 7842 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7843 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7844 if (stable) { 7845 conn.stableCount--; 7846 } else { 7847 conn.unstableCount--; 7848 } 7849 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7850 cpr.connections.remove(conn); 7851 conn.client.conProviders.remove(conn); 7852 return true; 7853 } 7854 return false; 7855 } 7856 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7857 return false; 7858 } 7859 7860 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7861 String name, IBinder token, boolean stable, int userId) { 7862 ContentProviderRecord cpr; 7863 ContentProviderConnection conn = null; 7864 ProviderInfo cpi = null; 7865 7866 synchronized(this) { 7867 ProcessRecord r = null; 7868 if (caller != null) { 7869 r = getRecordForAppLocked(caller); 7870 if (r == null) { 7871 throw new SecurityException( 7872 "Unable to find app for caller " + caller 7873 + " (pid=" + Binder.getCallingPid() 7874 + ") when getting content provider " + name); 7875 } 7876 } 7877 7878 // First check if this content provider has been published... 7879 cpr = mProviderMap.getProviderByName(name, userId); 7880 boolean providerRunning = cpr != null; 7881 if (providerRunning) { 7882 cpi = cpr.info; 7883 String msg; 7884 if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) { 7885 throw new SecurityException(msg); 7886 } 7887 7888 if (r != null && cpr.canRunHere(r)) { 7889 // This provider has been published or is in the process 7890 // of being published... but it is also allowed to run 7891 // in the caller's process, so don't make a connection 7892 // and just let the caller instantiate its own instance. 7893 ContentProviderHolder holder = cpr.newHolder(null); 7894 // don't give caller the provider object, it needs 7895 // to make its own. 7896 holder.provider = null; 7897 return holder; 7898 } 7899 7900 final long origId = Binder.clearCallingIdentity(); 7901 7902 // In this case the provider instance already exists, so we can 7903 // return it right away. 7904 conn = incProviderCountLocked(r, cpr, token, stable); 7905 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7906 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7907 // If this is a perceptible app accessing the provider, 7908 // make sure to count it as being accessed and thus 7909 // back up on the LRU list. This is good because 7910 // content providers are often expensive to start. 7911 updateLruProcessLocked(cpr.proc, false, null); 7912 } 7913 } 7914 7915 if (cpr.proc != null) { 7916 if (false) { 7917 if (cpr.name.flattenToShortString().equals( 7918 "com.android.providers.calendar/.CalendarProvider2")) { 7919 Slog.v(TAG, "****************** KILLING " 7920 + cpr.name.flattenToShortString()); 7921 Process.killProcess(cpr.proc.pid); 7922 } 7923 } 7924 boolean success = updateOomAdjLocked(cpr.proc); 7925 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7926 // NOTE: there is still a race here where a signal could be 7927 // pending on the process even though we managed to update its 7928 // adj level. Not sure what to do about this, but at least 7929 // the race is now smaller. 7930 if (!success) { 7931 // Uh oh... it looks like the provider's process 7932 // has been killed on us. We need to wait for a new 7933 // process to be started, and make sure its death 7934 // doesn't kill our process. 7935 Slog.i(TAG, 7936 "Existing provider " + cpr.name.flattenToShortString() 7937 + " is crashing; detaching " + r); 7938 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7939 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7940 if (!lastRef) { 7941 // This wasn't the last ref our process had on 7942 // the provider... we have now been killed, bail. 7943 return null; 7944 } 7945 providerRunning = false; 7946 conn = null; 7947 } 7948 } 7949 7950 Binder.restoreCallingIdentity(origId); 7951 } 7952 7953 boolean singleton; 7954 if (!providerRunning) { 7955 try { 7956 cpi = AppGlobals.getPackageManager(). 7957 resolveContentProvider(name, 7958 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7959 } catch (RemoteException ex) { 7960 } 7961 if (cpi == null) { 7962 return null; 7963 } 7964 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7965 cpi.name, cpi.flags); 7966 if (singleton) { 7967 userId = 0; 7968 } 7969 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7970 7971 String msg; 7972 if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) { 7973 throw new SecurityException(msg); 7974 } 7975 7976 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7977 && !cpi.processName.equals("system")) { 7978 // If this content provider does not run in the system 7979 // process, and the system is not yet ready to run other 7980 // processes, then fail fast instead of hanging. 7981 throw new IllegalArgumentException( 7982 "Attempt to launch content provider before system ready"); 7983 } 7984 7985 // Make sure that the user who owns this provider is started. If not, 7986 // we don't want to allow it to run. 7987 if (mStartedUsers.get(userId) == null) { 7988 Slog.w(TAG, "Unable to launch app " 7989 + cpi.applicationInfo.packageName + "/" 7990 + cpi.applicationInfo.uid + " for provider " 7991 + name + ": user " + userId + " is stopped"); 7992 return null; 7993 } 7994 7995 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7996 cpr = mProviderMap.getProviderByClass(comp, userId); 7997 final boolean firstClass = cpr == null; 7998 if (firstClass) { 7999 try { 8000 ApplicationInfo ai = 8001 AppGlobals.getPackageManager(). 8002 getApplicationInfo( 8003 cpi.applicationInfo.packageName, 8004 STOCK_PM_FLAGS, userId); 8005 if (ai == null) { 8006 Slog.w(TAG, "No package info for content provider " 8007 + cpi.name); 8008 return null; 8009 } 8010 ai = getAppInfoForUser(ai, userId); 8011 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8012 } catch (RemoteException ex) { 8013 // pm is in same process, this will never happen. 8014 } 8015 } 8016 8017 if (r != null && cpr.canRunHere(r)) { 8018 // If this is a multiprocess provider, then just return its 8019 // info and allow the caller to instantiate it. Only do 8020 // this if the provider is the same user as the caller's 8021 // process, or can run as root (so can be in any process). 8022 return cpr.newHolder(null); 8023 } 8024 8025 if (DEBUG_PROVIDER) { 8026 RuntimeException e = new RuntimeException("here"); 8027 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8028 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8029 } 8030 8031 // This is single process, and our app is now connecting to it. 8032 // See if we are already in the process of launching this 8033 // provider. 8034 final int N = mLaunchingProviders.size(); 8035 int i; 8036 for (i=0; i<N; i++) { 8037 if (mLaunchingProviders.get(i) == cpr) { 8038 break; 8039 } 8040 } 8041 8042 // If the provider is not already being launched, then get it 8043 // started. 8044 if (i >= N) { 8045 final long origId = Binder.clearCallingIdentity(); 8046 8047 try { 8048 // Content provider is now in use, its package can't be stopped. 8049 try { 8050 AppGlobals.getPackageManager().setPackageStoppedState( 8051 cpr.appInfo.packageName, false, userId); 8052 } catch (RemoteException e) { 8053 } catch (IllegalArgumentException e) { 8054 Slog.w(TAG, "Failed trying to unstop package " 8055 + cpr.appInfo.packageName + ": " + e); 8056 } 8057 8058 // Use existing process if already started 8059 ProcessRecord proc = getProcessRecordLocked( 8060 cpi.processName, cpr.appInfo.uid, false); 8061 if (proc != null && proc.thread != null) { 8062 if (DEBUG_PROVIDER) { 8063 Slog.d(TAG, "Installing in existing process " + proc); 8064 } 8065 proc.pubProviders.put(cpi.name, cpr); 8066 try { 8067 proc.thread.scheduleInstallProvider(cpi); 8068 } catch (RemoteException e) { 8069 } 8070 } else { 8071 proc = startProcessLocked(cpi.processName, 8072 cpr.appInfo, false, 0, "content provider", 8073 new ComponentName(cpi.applicationInfo.packageName, 8074 cpi.name), false, false, false); 8075 if (proc == null) { 8076 Slog.w(TAG, "Unable to launch app " 8077 + cpi.applicationInfo.packageName + "/" 8078 + cpi.applicationInfo.uid + " for provider " 8079 + name + ": process is bad"); 8080 return null; 8081 } 8082 } 8083 cpr.launchingApp = proc; 8084 mLaunchingProviders.add(cpr); 8085 } finally { 8086 Binder.restoreCallingIdentity(origId); 8087 } 8088 } 8089 8090 // Make sure the provider is published (the same provider class 8091 // may be published under multiple names). 8092 if (firstClass) { 8093 mProviderMap.putProviderByClass(comp, cpr); 8094 } 8095 8096 mProviderMap.putProviderByName(name, cpr); 8097 conn = incProviderCountLocked(r, cpr, token, stable); 8098 if (conn != null) { 8099 conn.waiting = true; 8100 } 8101 } 8102 } 8103 8104 // Wait for the provider to be published... 8105 synchronized (cpr) { 8106 while (cpr.provider == null) { 8107 if (cpr.launchingApp == null) { 8108 Slog.w(TAG, "Unable to launch app " 8109 + cpi.applicationInfo.packageName + "/" 8110 + cpi.applicationInfo.uid + " for provider " 8111 + name + ": launching app became null"); 8112 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8113 UserHandle.getUserId(cpi.applicationInfo.uid), 8114 cpi.applicationInfo.packageName, 8115 cpi.applicationInfo.uid, name); 8116 return null; 8117 } 8118 try { 8119 if (DEBUG_MU) { 8120 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8121 + cpr.launchingApp); 8122 } 8123 if (conn != null) { 8124 conn.waiting = true; 8125 } 8126 cpr.wait(); 8127 } catch (InterruptedException ex) { 8128 } finally { 8129 if (conn != null) { 8130 conn.waiting = false; 8131 } 8132 } 8133 } 8134 } 8135 return cpr != null ? cpr.newHolder(conn) : null; 8136 } 8137 8138 @Override 8139 public final ContentProviderHolder getContentProvider( 8140 IApplicationThread caller, String name, int userId, boolean stable) { 8141 enforceNotIsolatedCaller("getContentProvider"); 8142 if (caller == null) { 8143 String msg = "null IApplicationThread when getting content provider " 8144 + name; 8145 Slog.w(TAG, msg); 8146 throw new SecurityException(msg); 8147 } 8148 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8149 // with cross-user grant. 8150 return getContentProviderImpl(caller, name, null, stable, userId); 8151 } 8152 8153 public ContentProviderHolder getContentProviderExternal( 8154 String name, int userId, IBinder token) { 8155 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8156 "Do not have permission in call getContentProviderExternal()"); 8157 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8158 false, true, "getContentProvider", null); 8159 return getContentProviderExternalUnchecked(name, token, userId); 8160 } 8161 8162 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8163 IBinder token, int userId) { 8164 return getContentProviderImpl(null, name, token, true, userId); 8165 } 8166 8167 /** 8168 * Drop a content provider from a ProcessRecord's bookkeeping 8169 */ 8170 public void removeContentProvider(IBinder connection, boolean stable) { 8171 enforceNotIsolatedCaller("removeContentProvider"); 8172 long ident = Binder.clearCallingIdentity(); 8173 try { 8174 synchronized (this) { 8175 ContentProviderConnection conn; 8176 try { 8177 conn = (ContentProviderConnection)connection; 8178 } catch (ClassCastException e) { 8179 String msg ="removeContentProvider: " + connection 8180 + " not a ContentProviderConnection"; 8181 Slog.w(TAG, msg); 8182 throw new IllegalArgumentException(msg); 8183 } 8184 if (conn == null) { 8185 throw new NullPointerException("connection is null"); 8186 } 8187 if (decProviderCountLocked(conn, null, null, stable)) { 8188 updateOomAdjLocked(); 8189 } 8190 } 8191 } finally { 8192 Binder.restoreCallingIdentity(ident); 8193 } 8194 } 8195 8196 public void removeContentProviderExternal(String name, IBinder token) { 8197 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8198 "Do not have permission in call removeContentProviderExternal()"); 8199 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8200 } 8201 8202 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8203 synchronized (this) { 8204 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8205 if(cpr == null) { 8206 //remove from mProvidersByClass 8207 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8208 return; 8209 } 8210 8211 //update content provider record entry info 8212 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8213 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8214 if (localCpr.hasExternalProcessHandles()) { 8215 if (localCpr.removeExternalProcessHandleLocked(token)) { 8216 updateOomAdjLocked(); 8217 } else { 8218 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8219 + " with no external reference for token: " 8220 + token + "."); 8221 } 8222 } else { 8223 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8224 + " with no external references."); 8225 } 8226 } 8227 } 8228 8229 public final void publishContentProviders(IApplicationThread caller, 8230 List<ContentProviderHolder> providers) { 8231 if (providers == null) { 8232 return; 8233 } 8234 8235 enforceNotIsolatedCaller("publishContentProviders"); 8236 synchronized (this) { 8237 final ProcessRecord r = getRecordForAppLocked(caller); 8238 if (DEBUG_MU) 8239 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8240 if (r == null) { 8241 throw new SecurityException( 8242 "Unable to find app for caller " + caller 8243 + " (pid=" + Binder.getCallingPid() 8244 + ") when publishing content providers"); 8245 } 8246 8247 final long origId = Binder.clearCallingIdentity(); 8248 8249 final int N = providers.size(); 8250 for (int i=0; i<N; i++) { 8251 ContentProviderHolder src = providers.get(i); 8252 if (src == null || src.info == null || src.provider == null) { 8253 continue; 8254 } 8255 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8256 if (DEBUG_MU) 8257 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8258 if (dst != null) { 8259 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8260 mProviderMap.putProviderByClass(comp, dst); 8261 String names[] = dst.info.authority.split(";"); 8262 for (int j = 0; j < names.length; j++) { 8263 mProviderMap.putProviderByName(names[j], dst); 8264 } 8265 8266 int NL = mLaunchingProviders.size(); 8267 int j; 8268 for (j=0; j<NL; j++) { 8269 if (mLaunchingProviders.get(j) == dst) { 8270 mLaunchingProviders.remove(j); 8271 j--; 8272 NL--; 8273 } 8274 } 8275 synchronized (dst) { 8276 dst.provider = src.provider; 8277 dst.proc = r; 8278 dst.notifyAll(); 8279 } 8280 updateOomAdjLocked(r); 8281 } 8282 } 8283 8284 Binder.restoreCallingIdentity(origId); 8285 } 8286 } 8287 8288 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8289 ContentProviderConnection conn; 8290 try { 8291 conn = (ContentProviderConnection)connection; 8292 } catch (ClassCastException e) { 8293 String msg ="refContentProvider: " + connection 8294 + " not a ContentProviderConnection"; 8295 Slog.w(TAG, msg); 8296 throw new IllegalArgumentException(msg); 8297 } 8298 if (conn == null) { 8299 throw new NullPointerException("connection is null"); 8300 } 8301 8302 synchronized (this) { 8303 if (stable > 0) { 8304 conn.numStableIncs += stable; 8305 } 8306 stable = conn.stableCount + stable; 8307 if (stable < 0) { 8308 throw new IllegalStateException("stableCount < 0: " + stable); 8309 } 8310 8311 if (unstable > 0) { 8312 conn.numUnstableIncs += unstable; 8313 } 8314 unstable = conn.unstableCount + unstable; 8315 if (unstable < 0) { 8316 throw new IllegalStateException("unstableCount < 0: " + unstable); 8317 } 8318 8319 if ((stable+unstable) <= 0) { 8320 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8321 + stable + " unstable=" + unstable); 8322 } 8323 conn.stableCount = stable; 8324 conn.unstableCount = unstable; 8325 return !conn.dead; 8326 } 8327 } 8328 8329 public void unstableProviderDied(IBinder connection) { 8330 ContentProviderConnection conn; 8331 try { 8332 conn = (ContentProviderConnection)connection; 8333 } catch (ClassCastException e) { 8334 String msg ="refContentProvider: " + connection 8335 + " not a ContentProviderConnection"; 8336 Slog.w(TAG, msg); 8337 throw new IllegalArgumentException(msg); 8338 } 8339 if (conn == null) { 8340 throw new NullPointerException("connection is null"); 8341 } 8342 8343 // Safely retrieve the content provider associated with the connection. 8344 IContentProvider provider; 8345 synchronized (this) { 8346 provider = conn.provider.provider; 8347 } 8348 8349 if (provider == null) { 8350 // Um, yeah, we're way ahead of you. 8351 return; 8352 } 8353 8354 // Make sure the caller is being honest with us. 8355 if (provider.asBinder().pingBinder()) { 8356 // Er, no, still looks good to us. 8357 synchronized (this) { 8358 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8359 + " says " + conn + " died, but we don't agree"); 8360 return; 8361 } 8362 } 8363 8364 // Well look at that! It's dead! 8365 synchronized (this) { 8366 if (conn.provider.provider != provider) { 8367 // But something changed... good enough. 8368 return; 8369 } 8370 8371 ProcessRecord proc = conn.provider.proc; 8372 if (proc == null || proc.thread == null) { 8373 // Seems like the process is already cleaned up. 8374 return; 8375 } 8376 8377 // As far as we're concerned, this is just like receiving a 8378 // death notification... just a bit prematurely. 8379 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8380 + ") early provider death"); 8381 final long ident = Binder.clearCallingIdentity(); 8382 try { 8383 appDiedLocked(proc, proc.pid, proc.thread); 8384 } finally { 8385 Binder.restoreCallingIdentity(ident); 8386 } 8387 } 8388 } 8389 8390 @Override 8391 public void appNotRespondingViaProvider(IBinder connection) { 8392 enforceCallingPermission( 8393 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8394 8395 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8396 if (conn == null) { 8397 Slog.w(TAG, "ContentProviderConnection is null"); 8398 return; 8399 } 8400 8401 final ProcessRecord host = conn.provider.proc; 8402 if (host == null) { 8403 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8404 return; 8405 } 8406 8407 final long token = Binder.clearCallingIdentity(); 8408 try { 8409 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8410 } finally { 8411 Binder.restoreCallingIdentity(token); 8412 } 8413 } 8414 8415 public final void installSystemProviders() { 8416 List<ProviderInfo> providers; 8417 synchronized (this) { 8418 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8419 providers = generateApplicationProvidersLocked(app); 8420 if (providers != null) { 8421 for (int i=providers.size()-1; i>=0; i--) { 8422 ProviderInfo pi = (ProviderInfo)providers.get(i); 8423 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8424 Slog.w(TAG, "Not installing system proc provider " + pi.name 8425 + ": not system .apk"); 8426 providers.remove(i); 8427 } 8428 } 8429 } 8430 } 8431 if (providers != null) { 8432 mSystemThread.installSystemProviders(providers); 8433 } 8434 8435 mCoreSettingsObserver = new CoreSettingsObserver(this); 8436 8437 mUsageStatsService.monitorPackages(); 8438 } 8439 8440 /** 8441 * Allows app to retrieve the MIME type of a URI without having permission 8442 * to access its content provider. 8443 * 8444 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8445 * 8446 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8447 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8448 */ 8449 public String getProviderMimeType(Uri uri, int userId) { 8450 enforceNotIsolatedCaller("getProviderMimeType"); 8451 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8452 userId, false, true, "getProviderMimeType", null); 8453 final String name = uri.getAuthority(); 8454 final long ident = Binder.clearCallingIdentity(); 8455 ContentProviderHolder holder = null; 8456 8457 try { 8458 holder = getContentProviderExternalUnchecked(name, null, userId); 8459 if (holder != null) { 8460 return holder.provider.getType(uri); 8461 } 8462 } catch (RemoteException e) { 8463 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8464 return null; 8465 } finally { 8466 if (holder != null) { 8467 removeContentProviderExternalUnchecked(name, null, userId); 8468 } 8469 Binder.restoreCallingIdentity(ident); 8470 } 8471 8472 return null; 8473 } 8474 8475 // ========================================================= 8476 // GLOBAL MANAGEMENT 8477 // ========================================================= 8478 8479 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8480 boolean isolated) { 8481 String proc = customProcess != null ? customProcess : info.processName; 8482 BatteryStatsImpl.Uid.Proc ps = null; 8483 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8484 int uid = info.uid; 8485 if (isolated) { 8486 int userId = UserHandle.getUserId(uid); 8487 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8488 while (true) { 8489 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8490 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8491 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8492 } 8493 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8494 mNextIsolatedProcessUid++; 8495 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8496 // No process for this uid, use it. 8497 break; 8498 } 8499 stepsLeft--; 8500 if (stepsLeft <= 0) { 8501 return null; 8502 } 8503 } 8504 } 8505 return new ProcessRecord(stats, info, proc, uid); 8506 } 8507 8508 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8509 ProcessRecord app; 8510 if (!isolated) { 8511 app = getProcessRecordLocked(info.processName, info.uid, true); 8512 } else { 8513 app = null; 8514 } 8515 8516 if (app == null) { 8517 app = newProcessRecordLocked(info, null, isolated); 8518 mProcessNames.put(info.processName, app.uid, app); 8519 if (isolated) { 8520 mIsolatedProcesses.put(app.uid, app); 8521 } 8522 updateLruProcessLocked(app, false, null); 8523 updateOomAdjLocked(); 8524 } 8525 8526 // This package really, really can not be stopped. 8527 try { 8528 AppGlobals.getPackageManager().setPackageStoppedState( 8529 info.packageName, false, UserHandle.getUserId(app.uid)); 8530 } catch (RemoteException e) { 8531 } catch (IllegalArgumentException e) { 8532 Slog.w(TAG, "Failed trying to unstop package " 8533 + info.packageName + ": " + e); 8534 } 8535 8536 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8537 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8538 app.persistent = true; 8539 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8540 } 8541 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8542 mPersistentStartingProcesses.add(app); 8543 startProcessLocked(app, "added application", app.processName); 8544 } 8545 8546 return app; 8547 } 8548 8549 public void unhandledBack() { 8550 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8551 "unhandledBack()"); 8552 8553 synchronized(this) { 8554 final long origId = Binder.clearCallingIdentity(); 8555 try { 8556 getFocusedStack().unhandledBackLocked(); 8557 } finally { 8558 Binder.restoreCallingIdentity(origId); 8559 } 8560 } 8561 } 8562 8563 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8564 enforceNotIsolatedCaller("openContentUri"); 8565 final int userId = UserHandle.getCallingUserId(); 8566 String name = uri.getAuthority(); 8567 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8568 ParcelFileDescriptor pfd = null; 8569 if (cph != null) { 8570 // We record the binder invoker's uid in thread-local storage before 8571 // going to the content provider to open the file. Later, in the code 8572 // that handles all permissions checks, we look for this uid and use 8573 // that rather than the Activity Manager's own uid. The effect is that 8574 // we do the check against the caller's permissions even though it looks 8575 // to the content provider like the Activity Manager itself is making 8576 // the request. 8577 sCallerIdentity.set(new Identity( 8578 Binder.getCallingPid(), Binder.getCallingUid())); 8579 try { 8580 pfd = cph.provider.openFile(null, uri, "r", null); 8581 } catch (FileNotFoundException e) { 8582 // do nothing; pfd will be returned null 8583 } finally { 8584 // Ensure that whatever happens, we clean up the identity state 8585 sCallerIdentity.remove(); 8586 } 8587 8588 // We've got the fd now, so we're done with the provider. 8589 removeContentProviderExternalUnchecked(name, null, userId); 8590 } else { 8591 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8592 } 8593 return pfd; 8594 } 8595 8596 // Actually is sleeping or shutting down or whatever else in the future 8597 // is an inactive state. 8598 public boolean isSleepingOrShuttingDown() { 8599 return mSleeping || mShuttingDown; 8600 } 8601 8602 public boolean isSleeping() { 8603 return mSleeping; 8604 } 8605 8606 void goingToSleep() { 8607 synchronized(this) { 8608 mWentToSleep = true; 8609 updateEventDispatchingLocked(); 8610 goToSleepIfNeededLocked(); 8611 } 8612 } 8613 8614 void finishRunningVoiceLocked() { 8615 if (mRunningVoice) { 8616 mRunningVoice = false; 8617 goToSleepIfNeededLocked(); 8618 } 8619 } 8620 8621 void goToSleepIfNeededLocked() { 8622 if (mWentToSleep && !mRunningVoice) { 8623 if (!mSleeping) { 8624 mSleeping = true; 8625 mStackSupervisor.goingToSleepLocked(); 8626 8627 // Initialize the wake times of all processes. 8628 checkExcessivePowerUsageLocked(false); 8629 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8630 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8631 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8632 } 8633 } 8634 } 8635 8636 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 8637 mTaskPersister.notify(task, flush); 8638 } 8639 8640 @Override 8641 public boolean shutdown(int timeout) { 8642 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8643 != PackageManager.PERMISSION_GRANTED) { 8644 throw new SecurityException("Requires permission " 8645 + android.Manifest.permission.SHUTDOWN); 8646 } 8647 8648 boolean timedout = false; 8649 8650 synchronized(this) { 8651 mShuttingDown = true; 8652 updateEventDispatchingLocked(); 8653 timedout = mStackSupervisor.shutdownLocked(timeout); 8654 } 8655 8656 mAppOpsService.shutdown(); 8657 mUsageStatsService.shutdown(); 8658 mBatteryStatsService.shutdown(); 8659 synchronized (this) { 8660 mProcessStats.shutdownLocked(); 8661 } 8662 notifyTaskPersisterLocked(null, true); 8663 8664 return timedout; 8665 } 8666 8667 public final void activitySlept(IBinder token) { 8668 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8669 8670 final long origId = Binder.clearCallingIdentity(); 8671 8672 synchronized (this) { 8673 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8674 if (r != null) { 8675 mStackSupervisor.activitySleptLocked(r); 8676 } 8677 } 8678 8679 Binder.restoreCallingIdentity(origId); 8680 } 8681 8682 void logLockScreen(String msg) { 8683 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8684 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8685 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8686 mStackSupervisor.mDismissKeyguardOnNextActivity); 8687 } 8688 8689 private void comeOutOfSleepIfNeededLocked() { 8690 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8691 if (mSleeping) { 8692 mSleeping = false; 8693 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8694 } 8695 } 8696 } 8697 8698 void wakingUp() { 8699 synchronized(this) { 8700 mWentToSleep = false; 8701 updateEventDispatchingLocked(); 8702 comeOutOfSleepIfNeededLocked(); 8703 } 8704 } 8705 8706 void startRunningVoiceLocked() { 8707 if (!mRunningVoice) { 8708 mRunningVoice = true; 8709 comeOutOfSleepIfNeededLocked(); 8710 } 8711 } 8712 8713 private void updateEventDispatchingLocked() { 8714 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8715 } 8716 8717 public void setLockScreenShown(boolean shown) { 8718 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8719 != PackageManager.PERMISSION_GRANTED) { 8720 throw new SecurityException("Requires permission " 8721 + android.Manifest.permission.DEVICE_POWER); 8722 } 8723 8724 synchronized(this) { 8725 long ident = Binder.clearCallingIdentity(); 8726 try { 8727 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8728 mLockScreenShown = shown; 8729 comeOutOfSleepIfNeededLocked(); 8730 } finally { 8731 Binder.restoreCallingIdentity(ident); 8732 } 8733 } 8734 } 8735 8736 public void stopAppSwitches() { 8737 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8738 != PackageManager.PERMISSION_GRANTED) { 8739 throw new SecurityException("Requires permission " 8740 + android.Manifest.permission.STOP_APP_SWITCHES); 8741 } 8742 8743 synchronized(this) { 8744 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8745 + APP_SWITCH_DELAY_TIME; 8746 mDidAppSwitch = false; 8747 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8748 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8749 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8750 } 8751 } 8752 8753 public void resumeAppSwitches() { 8754 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8755 != PackageManager.PERMISSION_GRANTED) { 8756 throw new SecurityException("Requires permission " 8757 + android.Manifest.permission.STOP_APP_SWITCHES); 8758 } 8759 8760 synchronized(this) { 8761 // Note that we don't execute any pending app switches... we will 8762 // let those wait until either the timeout, or the next start 8763 // activity request. 8764 mAppSwitchesAllowedTime = 0; 8765 } 8766 } 8767 8768 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8769 String name) { 8770 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8771 return true; 8772 } 8773 8774 final int perm = checkComponentPermission( 8775 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8776 callingUid, -1, true); 8777 if (perm == PackageManager.PERMISSION_GRANTED) { 8778 return true; 8779 } 8780 8781 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8782 return false; 8783 } 8784 8785 public void setDebugApp(String packageName, boolean waitForDebugger, 8786 boolean persistent) { 8787 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8788 "setDebugApp()"); 8789 8790 long ident = Binder.clearCallingIdentity(); 8791 try { 8792 // Note that this is not really thread safe if there are multiple 8793 // callers into it at the same time, but that's not a situation we 8794 // care about. 8795 if (persistent) { 8796 final ContentResolver resolver = mContext.getContentResolver(); 8797 Settings.Global.putString( 8798 resolver, Settings.Global.DEBUG_APP, 8799 packageName); 8800 Settings.Global.putInt( 8801 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8802 waitForDebugger ? 1 : 0); 8803 } 8804 8805 synchronized (this) { 8806 if (!persistent) { 8807 mOrigDebugApp = mDebugApp; 8808 mOrigWaitForDebugger = mWaitForDebugger; 8809 } 8810 mDebugApp = packageName; 8811 mWaitForDebugger = waitForDebugger; 8812 mDebugTransient = !persistent; 8813 if (packageName != null) { 8814 forceStopPackageLocked(packageName, -1, false, false, true, true, 8815 false, UserHandle.USER_ALL, "set debug app"); 8816 } 8817 } 8818 } finally { 8819 Binder.restoreCallingIdentity(ident); 8820 } 8821 } 8822 8823 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8824 synchronized (this) { 8825 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8826 if (!isDebuggable) { 8827 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8828 throw new SecurityException("Process not debuggable: " + app.packageName); 8829 } 8830 } 8831 8832 mOpenGlTraceApp = processName; 8833 } 8834 } 8835 8836 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8837 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8838 synchronized (this) { 8839 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8840 if (!isDebuggable) { 8841 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8842 throw new SecurityException("Process not debuggable: " + app.packageName); 8843 } 8844 } 8845 mProfileApp = processName; 8846 mProfileFile = profileFile; 8847 if (mProfileFd != null) { 8848 try { 8849 mProfileFd.close(); 8850 } catch (IOException e) { 8851 } 8852 mProfileFd = null; 8853 } 8854 mProfileFd = profileFd; 8855 mProfileType = 0; 8856 mAutoStopProfiler = autoStopProfiler; 8857 } 8858 } 8859 8860 @Override 8861 public void setAlwaysFinish(boolean enabled) { 8862 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8863 "setAlwaysFinish()"); 8864 8865 Settings.Global.putInt( 8866 mContext.getContentResolver(), 8867 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8868 8869 synchronized (this) { 8870 mAlwaysFinishActivities = enabled; 8871 } 8872 } 8873 8874 @Override 8875 public void setActivityController(IActivityController controller) { 8876 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8877 "setActivityController()"); 8878 synchronized (this) { 8879 mController = controller; 8880 Watchdog.getInstance().setActivityController(controller); 8881 } 8882 } 8883 8884 @Override 8885 public void setUserIsMonkey(boolean userIsMonkey) { 8886 synchronized (this) { 8887 synchronized (mPidsSelfLocked) { 8888 final int callingPid = Binder.getCallingPid(); 8889 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8890 if (precessRecord == null) { 8891 throw new SecurityException("Unknown process: " + callingPid); 8892 } 8893 if (precessRecord.instrumentationUiAutomationConnection == null) { 8894 throw new SecurityException("Only an instrumentation process " 8895 + "with a UiAutomation can call setUserIsMonkey"); 8896 } 8897 } 8898 mUserIsMonkey = userIsMonkey; 8899 } 8900 } 8901 8902 @Override 8903 public boolean isUserAMonkey() { 8904 synchronized (this) { 8905 // If there is a controller also implies the user is a monkey. 8906 return (mUserIsMonkey || mController != null); 8907 } 8908 } 8909 8910 public void requestBugReport() { 8911 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8912 SystemProperties.set("ctl.start", "bugreport"); 8913 } 8914 8915 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8916 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8917 } 8918 8919 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8920 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8921 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8922 } 8923 return KEY_DISPATCHING_TIMEOUT; 8924 } 8925 8926 @Override 8927 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8928 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8929 != PackageManager.PERMISSION_GRANTED) { 8930 throw new SecurityException("Requires permission " 8931 + android.Manifest.permission.FILTER_EVENTS); 8932 } 8933 ProcessRecord proc; 8934 long timeout; 8935 synchronized (this) { 8936 synchronized (mPidsSelfLocked) { 8937 proc = mPidsSelfLocked.get(pid); 8938 } 8939 timeout = getInputDispatchingTimeoutLocked(proc); 8940 } 8941 8942 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8943 return -1; 8944 } 8945 8946 return timeout; 8947 } 8948 8949 /** 8950 * Handle input dispatching timeouts. 8951 * Returns whether input dispatching should be aborted or not. 8952 */ 8953 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8954 final ActivityRecord activity, final ActivityRecord parent, 8955 final boolean aboveSystem, String reason) { 8956 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8957 != PackageManager.PERMISSION_GRANTED) { 8958 throw new SecurityException("Requires permission " 8959 + android.Manifest.permission.FILTER_EVENTS); 8960 } 8961 8962 final String annotation; 8963 if (reason == null) { 8964 annotation = "Input dispatching timed out"; 8965 } else { 8966 annotation = "Input dispatching timed out (" + reason + ")"; 8967 } 8968 8969 if (proc != null) { 8970 synchronized (this) { 8971 if (proc.debugging) { 8972 return false; 8973 } 8974 8975 if (mDidDexOpt) { 8976 // Give more time since we were dexopting. 8977 mDidDexOpt = false; 8978 return false; 8979 } 8980 8981 if (proc.instrumentationClass != null) { 8982 Bundle info = new Bundle(); 8983 info.putString("shortMsg", "keyDispatchingTimedOut"); 8984 info.putString("longMsg", annotation); 8985 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8986 return true; 8987 } 8988 } 8989 mHandler.post(new Runnable() { 8990 @Override 8991 public void run() { 8992 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8993 } 8994 }); 8995 } 8996 8997 return true; 8998 } 8999 9000 public Bundle getAssistContextExtras(int requestType) { 9001 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9002 "getAssistContextExtras()"); 9003 PendingAssistExtras pae; 9004 Bundle extras = new Bundle(); 9005 synchronized (this) { 9006 ActivityRecord activity = getFocusedStack().mResumedActivity; 9007 if (activity == null) { 9008 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9009 return null; 9010 } 9011 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9012 if (activity.app == null || activity.app.thread == null) { 9013 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9014 return extras; 9015 } 9016 if (activity.app.pid == Binder.getCallingPid()) { 9017 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9018 return extras; 9019 } 9020 pae = new PendingAssistExtras(activity); 9021 try { 9022 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9023 requestType); 9024 mPendingAssistExtras.add(pae); 9025 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9026 } catch (RemoteException e) { 9027 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9028 return extras; 9029 } 9030 } 9031 synchronized (pae) { 9032 while (!pae.haveResult) { 9033 try { 9034 pae.wait(); 9035 } catch (InterruptedException e) { 9036 } 9037 } 9038 if (pae.result != null) { 9039 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9040 } 9041 } 9042 synchronized (this) { 9043 mPendingAssistExtras.remove(pae); 9044 mHandler.removeCallbacks(pae); 9045 } 9046 return extras; 9047 } 9048 9049 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9050 PendingAssistExtras pae = (PendingAssistExtras)token; 9051 synchronized (pae) { 9052 pae.result = extras; 9053 pae.haveResult = true; 9054 pae.notifyAll(); 9055 } 9056 } 9057 9058 public void registerProcessObserver(IProcessObserver observer) { 9059 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9060 "registerProcessObserver()"); 9061 synchronized (this) { 9062 mProcessObservers.register(observer); 9063 } 9064 } 9065 9066 @Override 9067 public void unregisterProcessObserver(IProcessObserver observer) { 9068 synchronized (this) { 9069 mProcessObservers.unregister(observer); 9070 } 9071 } 9072 9073 @Override 9074 public boolean convertFromTranslucent(IBinder token) { 9075 final long origId = Binder.clearCallingIdentity(); 9076 try { 9077 synchronized (this) { 9078 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9079 if (r == null) { 9080 return false; 9081 } 9082 if (r.changeWindowTranslucency(true)) { 9083 mWindowManager.setAppFullscreen(token, true); 9084 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9085 return true; 9086 } 9087 return false; 9088 } 9089 } finally { 9090 Binder.restoreCallingIdentity(origId); 9091 } 9092 } 9093 9094 @Override 9095 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9096 final long origId = Binder.clearCallingIdentity(); 9097 try { 9098 synchronized (this) { 9099 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9100 if (r == null) { 9101 return false; 9102 } 9103 if (r.changeWindowTranslucency(false)) { 9104 r.task.stack.convertToTranslucent(r, options); 9105 mWindowManager.setAppFullscreen(token, false); 9106 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9107 return true; 9108 } 9109 return false; 9110 } 9111 } finally { 9112 Binder.restoreCallingIdentity(origId); 9113 } 9114 } 9115 9116 @Override 9117 public ActivityOptions getActivityOptions(IBinder token) { 9118 final long origId = Binder.clearCallingIdentity(); 9119 try { 9120 synchronized (this) { 9121 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9122 if (r != null) { 9123 final ActivityOptions activityOptions = r.pendingOptions; 9124 r.pendingOptions = null; 9125 return activityOptions; 9126 } 9127 return null; 9128 } 9129 } finally { 9130 Binder.restoreCallingIdentity(origId); 9131 } 9132 } 9133 9134 @Override 9135 public void setImmersive(IBinder token, boolean immersive) { 9136 synchronized(this) { 9137 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9138 if (r == null) { 9139 throw new IllegalArgumentException(); 9140 } 9141 r.immersive = immersive; 9142 9143 // update associated state if we're frontmost 9144 if (r == mFocusedActivity) { 9145 if (DEBUG_IMMERSIVE) { 9146 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9147 } 9148 applyUpdateLockStateLocked(r); 9149 } 9150 } 9151 } 9152 9153 @Override 9154 public boolean isImmersive(IBinder token) { 9155 synchronized (this) { 9156 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9157 if (r == null) { 9158 throw new IllegalArgumentException(); 9159 } 9160 return r.immersive; 9161 } 9162 } 9163 9164 public boolean isTopActivityImmersive() { 9165 enforceNotIsolatedCaller("startActivity"); 9166 synchronized (this) { 9167 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9168 return (r != null) ? r.immersive : false; 9169 } 9170 } 9171 9172 public final void enterSafeMode() { 9173 synchronized(this) { 9174 // It only makes sense to do this before the system is ready 9175 // and started launching other packages. 9176 if (!mSystemReady) { 9177 try { 9178 AppGlobals.getPackageManager().enterSafeMode(); 9179 } catch (RemoteException e) { 9180 } 9181 } 9182 9183 mSafeMode = true; 9184 } 9185 } 9186 9187 public final void showSafeModeOverlay() { 9188 View v = LayoutInflater.from(mContext).inflate( 9189 com.android.internal.R.layout.safe_mode, null); 9190 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9191 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9192 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9193 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9194 lp.gravity = Gravity.BOTTOM | Gravity.START; 9195 lp.format = v.getBackground().getOpacity(); 9196 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9197 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9198 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9199 ((WindowManager)mContext.getSystemService( 9200 Context.WINDOW_SERVICE)).addView(v, lp); 9201 } 9202 9203 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9204 if (!(sender instanceof PendingIntentRecord)) { 9205 return; 9206 } 9207 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9208 synchronized (stats) { 9209 if (mBatteryStatsService.isOnBattery()) { 9210 mBatteryStatsService.enforceCallingPermission(); 9211 PendingIntentRecord rec = (PendingIntentRecord)sender; 9212 int MY_UID = Binder.getCallingUid(); 9213 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9214 BatteryStatsImpl.Uid.Pkg pkg = 9215 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9216 sourcePkg != null ? sourcePkg : rec.key.packageName); 9217 pkg.incWakeupsLocked(); 9218 } 9219 } 9220 } 9221 9222 public boolean killPids(int[] pids, String pReason, boolean secure) { 9223 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9224 throw new SecurityException("killPids only available to the system"); 9225 } 9226 String reason = (pReason == null) ? "Unknown" : pReason; 9227 // XXX Note: don't acquire main activity lock here, because the window 9228 // manager calls in with its locks held. 9229 9230 boolean killed = false; 9231 synchronized (mPidsSelfLocked) { 9232 int[] types = new int[pids.length]; 9233 int worstType = 0; 9234 for (int i=0; i<pids.length; i++) { 9235 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9236 if (proc != null) { 9237 int type = proc.setAdj; 9238 types[i] = type; 9239 if (type > worstType) { 9240 worstType = type; 9241 } 9242 } 9243 } 9244 9245 // If the worst oom_adj is somewhere in the cached proc LRU range, 9246 // then constrain it so we will kill all cached procs. 9247 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9248 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9249 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9250 } 9251 9252 // If this is not a secure call, don't let it kill processes that 9253 // are important. 9254 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9255 worstType = ProcessList.SERVICE_ADJ; 9256 } 9257 9258 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9259 for (int i=0; i<pids.length; i++) { 9260 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9261 if (proc == null) { 9262 continue; 9263 } 9264 int adj = proc.setAdj; 9265 if (adj >= worstType && !proc.killedByAm) { 9266 killUnneededProcessLocked(proc, reason); 9267 killed = true; 9268 } 9269 } 9270 } 9271 return killed; 9272 } 9273 9274 @Override 9275 public void killUid(int uid, String reason) { 9276 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9277 throw new SecurityException("killUid only available to the system"); 9278 } 9279 synchronized (this) { 9280 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9281 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9282 reason != null ? reason : "kill uid"); 9283 } 9284 } 9285 9286 @Override 9287 public boolean killProcessesBelowForeground(String reason) { 9288 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9289 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9290 } 9291 9292 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9293 } 9294 9295 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9296 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9297 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9298 } 9299 9300 boolean killed = false; 9301 synchronized (mPidsSelfLocked) { 9302 final int size = mPidsSelfLocked.size(); 9303 for (int i = 0; i < size; i++) { 9304 final int pid = mPidsSelfLocked.keyAt(i); 9305 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9306 if (proc == null) continue; 9307 9308 final int adj = proc.setAdj; 9309 if (adj > belowAdj && !proc.killedByAm) { 9310 killUnneededProcessLocked(proc, reason); 9311 killed = true; 9312 } 9313 } 9314 } 9315 return killed; 9316 } 9317 9318 @Override 9319 public void hang(final IBinder who, boolean allowRestart) { 9320 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9321 != PackageManager.PERMISSION_GRANTED) { 9322 throw new SecurityException("Requires permission " 9323 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9324 } 9325 9326 final IBinder.DeathRecipient death = new DeathRecipient() { 9327 @Override 9328 public void binderDied() { 9329 synchronized (this) { 9330 notifyAll(); 9331 } 9332 } 9333 }; 9334 9335 try { 9336 who.linkToDeath(death, 0); 9337 } catch (RemoteException e) { 9338 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9339 return; 9340 } 9341 9342 synchronized (this) { 9343 Watchdog.getInstance().setAllowRestart(allowRestart); 9344 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9345 synchronized (death) { 9346 while (who.isBinderAlive()) { 9347 try { 9348 death.wait(); 9349 } catch (InterruptedException e) { 9350 } 9351 } 9352 } 9353 Watchdog.getInstance().setAllowRestart(true); 9354 } 9355 } 9356 9357 @Override 9358 public void restart() { 9359 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9360 != PackageManager.PERMISSION_GRANTED) { 9361 throw new SecurityException("Requires permission " 9362 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9363 } 9364 9365 Log.i(TAG, "Sending shutdown broadcast..."); 9366 9367 BroadcastReceiver br = new BroadcastReceiver() { 9368 @Override public void onReceive(Context context, Intent intent) { 9369 // Now the broadcast is done, finish up the low-level shutdown. 9370 Log.i(TAG, "Shutting down activity manager..."); 9371 shutdown(10000); 9372 Log.i(TAG, "Shutdown complete, restarting!"); 9373 Process.killProcess(Process.myPid()); 9374 System.exit(10); 9375 } 9376 }; 9377 9378 // First send the high-level shut down broadcast. 9379 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9380 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9381 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9382 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9383 mContext.sendOrderedBroadcastAsUser(intent, 9384 UserHandle.ALL, null, br, mHandler, 0, null, null); 9385 */ 9386 br.onReceive(mContext, intent); 9387 } 9388 9389 private long getLowRamTimeSinceIdle(long now) { 9390 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9391 } 9392 9393 @Override 9394 public void performIdleMaintenance() { 9395 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9396 != PackageManager.PERMISSION_GRANTED) { 9397 throw new SecurityException("Requires permission " 9398 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9399 } 9400 9401 synchronized (this) { 9402 final long now = SystemClock.uptimeMillis(); 9403 final long timeSinceLastIdle = now - mLastIdleTime; 9404 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9405 mLastIdleTime = now; 9406 mLowRamTimeSinceLastIdle = 0; 9407 if (mLowRamStartTime != 0) { 9408 mLowRamStartTime = now; 9409 } 9410 9411 StringBuilder sb = new StringBuilder(128); 9412 sb.append("Idle maintenance over "); 9413 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9414 sb.append(" low RAM for "); 9415 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9416 Slog.i(TAG, sb.toString()); 9417 9418 // If at least 1/3 of our time since the last idle period has been spent 9419 // with RAM low, then we want to kill processes. 9420 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9421 9422 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9423 ProcessRecord proc = mLruProcesses.get(i); 9424 if (proc.notCachedSinceIdle) { 9425 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9426 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9427 if (doKilling && proc.initialIdlePss != 0 9428 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9429 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9430 + " from " + proc.initialIdlePss + ")"); 9431 } 9432 } 9433 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9434 proc.notCachedSinceIdle = true; 9435 proc.initialIdlePss = 0; 9436 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9437 isSleeping(), now); 9438 } 9439 } 9440 9441 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9442 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9443 } 9444 } 9445 9446 private void retrieveSettings() { 9447 final ContentResolver resolver = mContext.getContentResolver(); 9448 String debugApp = Settings.Global.getString( 9449 resolver, Settings.Global.DEBUG_APP); 9450 boolean waitForDebugger = Settings.Global.getInt( 9451 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9452 boolean alwaysFinishActivities = Settings.Global.getInt( 9453 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9454 boolean forceRtl = Settings.Global.getInt( 9455 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9456 // Transfer any global setting for forcing RTL layout, into a System Property 9457 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9458 9459 Configuration configuration = new Configuration(); 9460 Settings.System.getConfiguration(resolver, configuration); 9461 if (forceRtl) { 9462 // This will take care of setting the correct layout direction flags 9463 configuration.setLayoutDirection(configuration.locale); 9464 } 9465 9466 synchronized (this) { 9467 mDebugApp = mOrigDebugApp = debugApp; 9468 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9469 mAlwaysFinishActivities = alwaysFinishActivities; 9470 // This happens before any activities are started, so we can 9471 // change mConfiguration in-place. 9472 updateConfigurationLocked(configuration, null, false, true); 9473 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9474 } 9475 } 9476 9477 public boolean testIsSystemReady() { 9478 // no need to synchronize(this) just to read & return the value 9479 return mSystemReady; 9480 } 9481 9482 private static File getCalledPreBootReceiversFile() { 9483 File dataDir = Environment.getDataDirectory(); 9484 File systemDir = new File(dataDir, "system"); 9485 File fname = new File(systemDir, "called_pre_boots.dat"); 9486 return fname; 9487 } 9488 9489 static final int LAST_DONE_VERSION = 10000; 9490 9491 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9492 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9493 File file = getCalledPreBootReceiversFile(); 9494 FileInputStream fis = null; 9495 try { 9496 fis = new FileInputStream(file); 9497 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9498 int fvers = dis.readInt(); 9499 if (fvers == LAST_DONE_VERSION) { 9500 String vers = dis.readUTF(); 9501 String codename = dis.readUTF(); 9502 String build = dis.readUTF(); 9503 if (android.os.Build.VERSION.RELEASE.equals(vers) 9504 && android.os.Build.VERSION.CODENAME.equals(codename) 9505 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9506 int num = dis.readInt(); 9507 while (num > 0) { 9508 num--; 9509 String pkg = dis.readUTF(); 9510 String cls = dis.readUTF(); 9511 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9512 } 9513 } 9514 } 9515 } catch (FileNotFoundException e) { 9516 } catch (IOException e) { 9517 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9518 } finally { 9519 if (fis != null) { 9520 try { 9521 fis.close(); 9522 } catch (IOException e) { 9523 } 9524 } 9525 } 9526 return lastDoneReceivers; 9527 } 9528 9529 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9530 File file = getCalledPreBootReceiversFile(); 9531 FileOutputStream fos = null; 9532 DataOutputStream dos = null; 9533 try { 9534 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9535 fos = new FileOutputStream(file); 9536 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9537 dos.writeInt(LAST_DONE_VERSION); 9538 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9539 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9540 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9541 dos.writeInt(list.size()); 9542 for (int i=0; i<list.size(); i++) { 9543 dos.writeUTF(list.get(i).getPackageName()); 9544 dos.writeUTF(list.get(i).getClassName()); 9545 } 9546 } catch (IOException e) { 9547 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9548 file.delete(); 9549 } finally { 9550 FileUtils.sync(fos); 9551 if (dos != null) { 9552 try { 9553 dos.close(); 9554 } catch (IOException e) { 9555 // TODO Auto-generated catch block 9556 e.printStackTrace(); 9557 } 9558 } 9559 } 9560 } 9561 9562 public void systemReady(final Runnable goingCallback) { 9563 synchronized(this) { 9564 if (mSystemReady) { 9565 if (goingCallback != null) goingCallback.run(); 9566 return; 9567 } 9568 9569 mRecentTasks = mTaskPersister.restoreTasksLocked(); 9570 if (!mRecentTasks.isEmpty()) { 9571 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 9572 } 9573 mTaskPersister.startPersisting(); 9574 9575 // Check to see if there are any update receivers to run. 9576 if (!mDidUpdate) { 9577 if (mWaitingUpdate) { 9578 return; 9579 } 9580 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9581 List<ResolveInfo> ris = null; 9582 try { 9583 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9584 intent, null, 0, 0); 9585 } catch (RemoteException e) { 9586 } 9587 if (ris != null) { 9588 for (int i=ris.size()-1; i>=0; i--) { 9589 if ((ris.get(i).activityInfo.applicationInfo.flags 9590 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9591 ris.remove(i); 9592 } 9593 } 9594 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9595 9596 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9597 9598 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9599 for (int i=0; i<ris.size(); i++) { 9600 ActivityInfo ai = ris.get(i).activityInfo; 9601 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9602 if (lastDoneReceivers.contains(comp)) { 9603 // We already did the pre boot receiver for this app with the current 9604 // platform version, so don't do it again... 9605 ris.remove(i); 9606 i--; 9607 // ...however, do keep it as one that has been done, so we don't 9608 // forget about it when rewriting the file of last done receivers. 9609 doneReceivers.add(comp); 9610 } 9611 } 9612 9613 final int[] users = getUsersLocked(); 9614 for (int i=0; i<ris.size(); i++) { 9615 ActivityInfo ai = ris.get(i).activityInfo; 9616 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9617 doneReceivers.add(comp); 9618 intent.setComponent(comp); 9619 for (int j=0; j<users.length; j++) { 9620 IIntentReceiver finisher = null; 9621 if (i == ris.size()-1 && j == users.length-1) { 9622 finisher = new IIntentReceiver.Stub() { 9623 public void performReceive(Intent intent, int resultCode, 9624 String data, Bundle extras, boolean ordered, 9625 boolean sticky, int sendingUser) { 9626 // The raw IIntentReceiver interface is called 9627 // with the AM lock held, so redispatch to 9628 // execute our code without the lock. 9629 mHandler.post(new Runnable() { 9630 public void run() { 9631 synchronized (ActivityManagerService.this) { 9632 mDidUpdate = true; 9633 } 9634 writeLastDonePreBootReceivers(doneReceivers); 9635 showBootMessage(mContext.getText( 9636 R.string.android_upgrading_complete), 9637 false); 9638 systemReady(goingCallback); 9639 } 9640 }); 9641 } 9642 }; 9643 } 9644 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9645 + " for user " + users[j]); 9646 broadcastIntentLocked(null, null, intent, null, finisher, 9647 0, null, null, null, AppOpsManager.OP_NONE, 9648 true, false, MY_PID, Process.SYSTEM_UID, 9649 users[j]); 9650 if (finisher != null) { 9651 mWaitingUpdate = true; 9652 } 9653 } 9654 } 9655 } 9656 if (mWaitingUpdate) { 9657 return; 9658 } 9659 mDidUpdate = true; 9660 } 9661 9662 mAppOpsService.systemReady(); 9663 mUsageStatsService.systemReady(); 9664 mSystemReady = true; 9665 } 9666 9667 ArrayList<ProcessRecord> procsToKill = null; 9668 synchronized(mPidsSelfLocked) { 9669 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9670 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9671 if (!isAllowedWhileBooting(proc.info)){ 9672 if (procsToKill == null) { 9673 procsToKill = new ArrayList<ProcessRecord>(); 9674 } 9675 procsToKill.add(proc); 9676 } 9677 } 9678 } 9679 9680 synchronized(this) { 9681 if (procsToKill != null) { 9682 for (int i=procsToKill.size()-1; i>=0; i--) { 9683 ProcessRecord proc = procsToKill.get(i); 9684 Slog.i(TAG, "Removing system update proc: " + proc); 9685 removeProcessLocked(proc, true, false, "system update done"); 9686 } 9687 } 9688 9689 // Now that we have cleaned up any update processes, we 9690 // are ready to start launching real processes and know that 9691 // we won't trample on them any more. 9692 mProcessesReady = true; 9693 } 9694 9695 Slog.i(TAG, "System now ready"); 9696 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9697 SystemClock.uptimeMillis()); 9698 9699 synchronized(this) { 9700 // Make sure we have no pre-ready processes sitting around. 9701 9702 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9703 ResolveInfo ri = mContext.getPackageManager() 9704 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9705 STOCK_PM_FLAGS); 9706 CharSequence errorMsg = null; 9707 if (ri != null) { 9708 ActivityInfo ai = ri.activityInfo; 9709 ApplicationInfo app = ai.applicationInfo; 9710 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9711 mTopAction = Intent.ACTION_FACTORY_TEST; 9712 mTopData = null; 9713 mTopComponent = new ComponentName(app.packageName, 9714 ai.name); 9715 } else { 9716 errorMsg = mContext.getResources().getText( 9717 com.android.internal.R.string.factorytest_not_system); 9718 } 9719 } else { 9720 errorMsg = mContext.getResources().getText( 9721 com.android.internal.R.string.factorytest_no_action); 9722 } 9723 if (errorMsg != null) { 9724 mTopAction = null; 9725 mTopData = null; 9726 mTopComponent = null; 9727 Message msg = Message.obtain(); 9728 msg.what = SHOW_FACTORY_ERROR_MSG; 9729 msg.getData().putCharSequence("msg", errorMsg); 9730 mHandler.sendMessage(msg); 9731 } 9732 } 9733 } 9734 9735 retrieveSettings(); 9736 9737 synchronized (this) { 9738 readGrantedUriPermissionsLocked(); 9739 } 9740 9741 if (goingCallback != null) goingCallback.run(); 9742 9743 mSystemServiceManager.startUser(mCurrentUserId); 9744 9745 synchronized (this) { 9746 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9747 try { 9748 List apps = AppGlobals.getPackageManager(). 9749 getPersistentApplications(STOCK_PM_FLAGS); 9750 if (apps != null) { 9751 int N = apps.size(); 9752 int i; 9753 for (i=0; i<N; i++) { 9754 ApplicationInfo info 9755 = (ApplicationInfo)apps.get(i); 9756 if (info != null && 9757 !info.packageName.equals("android")) { 9758 addAppLocked(info, false); 9759 } 9760 } 9761 } 9762 } catch (RemoteException ex) { 9763 // pm is in same process, this will never happen. 9764 } 9765 } 9766 9767 // Start up initial activity. 9768 mBooting = true; 9769 9770 try { 9771 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9772 Message msg = Message.obtain(); 9773 msg.what = SHOW_UID_ERROR_MSG; 9774 mHandler.sendMessage(msg); 9775 } 9776 } catch (RemoteException e) { 9777 } 9778 9779 long ident = Binder.clearCallingIdentity(); 9780 try { 9781 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9782 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9783 | Intent.FLAG_RECEIVER_FOREGROUND); 9784 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9785 broadcastIntentLocked(null, null, intent, 9786 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9787 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9788 intent = new Intent(Intent.ACTION_USER_STARTING); 9789 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9790 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9791 broadcastIntentLocked(null, null, intent, 9792 null, new IIntentReceiver.Stub() { 9793 @Override 9794 public void performReceive(Intent intent, int resultCode, String data, 9795 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9796 throws RemoteException { 9797 } 9798 }, 0, null, null, 9799 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9800 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9801 } catch (Throwable t) { 9802 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 9803 } finally { 9804 Binder.restoreCallingIdentity(ident); 9805 } 9806 mStackSupervisor.resumeTopActivitiesLocked(); 9807 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9808 } 9809 } 9810 9811 private boolean makeAppCrashingLocked(ProcessRecord app, 9812 String shortMsg, String longMsg, String stackTrace) { 9813 app.crashing = true; 9814 app.crashingReport = generateProcessError(app, 9815 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9816 startAppProblemLocked(app); 9817 app.stopFreezingAllLocked(); 9818 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9819 } 9820 9821 private void makeAppNotRespondingLocked(ProcessRecord app, 9822 String activity, String shortMsg, String longMsg) { 9823 app.notResponding = true; 9824 app.notRespondingReport = generateProcessError(app, 9825 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9826 activity, shortMsg, longMsg, null); 9827 startAppProblemLocked(app); 9828 app.stopFreezingAllLocked(); 9829 } 9830 9831 /** 9832 * Generate a process error record, suitable for attachment to a ProcessRecord. 9833 * 9834 * @param app The ProcessRecord in which the error occurred. 9835 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9836 * ActivityManager.AppErrorStateInfo 9837 * @param activity The activity associated with the crash, if known. 9838 * @param shortMsg Short message describing the crash. 9839 * @param longMsg Long message describing the crash. 9840 * @param stackTrace Full crash stack trace, may be null. 9841 * 9842 * @return Returns a fully-formed AppErrorStateInfo record. 9843 */ 9844 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9845 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9846 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9847 9848 report.condition = condition; 9849 report.processName = app.processName; 9850 report.pid = app.pid; 9851 report.uid = app.info.uid; 9852 report.tag = activity; 9853 report.shortMsg = shortMsg; 9854 report.longMsg = longMsg; 9855 report.stackTrace = stackTrace; 9856 9857 return report; 9858 } 9859 9860 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9861 synchronized (this) { 9862 app.crashing = false; 9863 app.crashingReport = null; 9864 app.notResponding = false; 9865 app.notRespondingReport = null; 9866 if (app.anrDialog == fromDialog) { 9867 app.anrDialog = null; 9868 } 9869 if (app.waitDialog == fromDialog) { 9870 app.waitDialog = null; 9871 } 9872 if (app.pid > 0 && app.pid != MY_PID) { 9873 handleAppCrashLocked(app, null, null, null); 9874 killUnneededProcessLocked(app, "user request after error"); 9875 } 9876 } 9877 } 9878 9879 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9880 String stackTrace) { 9881 long now = SystemClock.uptimeMillis(); 9882 9883 Long crashTime; 9884 if (!app.isolated) { 9885 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9886 } else { 9887 crashTime = null; 9888 } 9889 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9890 // This process loses! 9891 Slog.w(TAG, "Process " + app.info.processName 9892 + " has crashed too many times: killing!"); 9893 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9894 app.userId, app.info.processName, app.uid); 9895 mStackSupervisor.handleAppCrashLocked(app); 9896 if (!app.persistent) { 9897 // We don't want to start this process again until the user 9898 // explicitly does so... but for persistent process, we really 9899 // need to keep it running. If a persistent process is actually 9900 // repeatedly crashing, then badness for everyone. 9901 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9902 app.info.processName); 9903 if (!app.isolated) { 9904 // XXX We don't have a way to mark isolated processes 9905 // as bad, since they don't have a peristent identity. 9906 mBadProcesses.put(app.info.processName, app.uid, 9907 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9908 mProcessCrashTimes.remove(app.info.processName, app.uid); 9909 } 9910 app.bad = true; 9911 app.removed = true; 9912 // Don't let services in this process be restarted and potentially 9913 // annoy the user repeatedly. Unless it is persistent, since those 9914 // processes run critical code. 9915 removeProcessLocked(app, false, false, "crash"); 9916 mStackSupervisor.resumeTopActivitiesLocked(); 9917 return false; 9918 } 9919 mStackSupervisor.resumeTopActivitiesLocked(); 9920 } else { 9921 mStackSupervisor.finishTopRunningActivityLocked(app); 9922 } 9923 9924 // Bump up the crash count of any services currently running in the proc. 9925 for (int i=app.services.size()-1; i>=0; i--) { 9926 // Any services running in the application need to be placed 9927 // back in the pending list. 9928 ServiceRecord sr = app.services.valueAt(i); 9929 sr.crashCount++; 9930 } 9931 9932 // If the crashing process is what we consider to be the "home process" and it has been 9933 // replaced by a third-party app, clear the package preferred activities from packages 9934 // with a home activity running in the process to prevent a repeatedly crashing app 9935 // from blocking the user to manually clear the list. 9936 final ArrayList<ActivityRecord> activities = app.activities; 9937 if (app == mHomeProcess && activities.size() > 0 9938 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9939 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9940 final ActivityRecord r = activities.get(activityNdx); 9941 if (r.isHomeActivity()) { 9942 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9943 try { 9944 ActivityThread.getPackageManager() 9945 .clearPackagePreferredActivities(r.packageName); 9946 } catch (RemoteException c) { 9947 // pm is in same process, this will never happen. 9948 } 9949 } 9950 } 9951 } 9952 9953 if (!app.isolated) { 9954 // XXX Can't keep track of crash times for isolated processes, 9955 // because they don't have a perisistent identity. 9956 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9957 } 9958 9959 return true; 9960 } 9961 9962 void startAppProblemLocked(ProcessRecord app) { 9963 if (app.userId == mCurrentUserId) { 9964 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9965 mContext, app.info.packageName, app.info.flags); 9966 } else { 9967 // If this app is not running under the current user, then we 9968 // can't give it a report button because that would require 9969 // launching the report UI under a different user. 9970 app.errorReportReceiver = null; 9971 } 9972 skipCurrentReceiverLocked(app); 9973 } 9974 9975 void skipCurrentReceiverLocked(ProcessRecord app) { 9976 for (BroadcastQueue queue : mBroadcastQueues) { 9977 queue.skipCurrentReceiverLocked(app); 9978 } 9979 } 9980 9981 /** 9982 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9983 * The application process will exit immediately after this call returns. 9984 * @param app object of the crashing app, null for the system server 9985 * @param crashInfo describing the exception 9986 */ 9987 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9988 ProcessRecord r = findAppProcess(app, "Crash"); 9989 final String processName = app == null ? "system_server" 9990 : (r == null ? "unknown" : r.processName); 9991 9992 handleApplicationCrashInner("crash", r, processName, crashInfo); 9993 } 9994 9995 /* Native crash reporting uses this inner version because it needs to be somewhat 9996 * decoupled from the AM-managed cleanup lifecycle 9997 */ 9998 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9999 ApplicationErrorReport.CrashInfo crashInfo) { 10000 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10001 UserHandle.getUserId(Binder.getCallingUid()), processName, 10002 r == null ? -1 : r.info.flags, 10003 crashInfo.exceptionClassName, 10004 crashInfo.exceptionMessage, 10005 crashInfo.throwFileName, 10006 crashInfo.throwLineNumber); 10007 10008 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10009 10010 crashApplication(r, crashInfo); 10011 } 10012 10013 public void handleApplicationStrictModeViolation( 10014 IBinder app, 10015 int violationMask, 10016 StrictMode.ViolationInfo info) { 10017 ProcessRecord r = findAppProcess(app, "StrictMode"); 10018 if (r == null) { 10019 return; 10020 } 10021 10022 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10023 Integer stackFingerprint = info.hashCode(); 10024 boolean logIt = true; 10025 synchronized (mAlreadyLoggedViolatedStacks) { 10026 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10027 logIt = false; 10028 // TODO: sub-sample into EventLog for these, with 10029 // the info.durationMillis? Then we'd get 10030 // the relative pain numbers, without logging all 10031 // the stack traces repeatedly. We'd want to do 10032 // likewise in the client code, which also does 10033 // dup suppression, before the Binder call. 10034 } else { 10035 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10036 mAlreadyLoggedViolatedStacks.clear(); 10037 } 10038 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10039 } 10040 } 10041 if (logIt) { 10042 logStrictModeViolationToDropBox(r, info); 10043 } 10044 } 10045 10046 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10047 AppErrorResult result = new AppErrorResult(); 10048 synchronized (this) { 10049 final long origId = Binder.clearCallingIdentity(); 10050 10051 Message msg = Message.obtain(); 10052 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10053 HashMap<String, Object> data = new HashMap<String, Object>(); 10054 data.put("result", result); 10055 data.put("app", r); 10056 data.put("violationMask", violationMask); 10057 data.put("info", info); 10058 msg.obj = data; 10059 mHandler.sendMessage(msg); 10060 10061 Binder.restoreCallingIdentity(origId); 10062 } 10063 int res = result.get(); 10064 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10065 } 10066 } 10067 10068 // Depending on the policy in effect, there could be a bunch of 10069 // these in quick succession so we try to batch these together to 10070 // minimize disk writes, number of dropbox entries, and maximize 10071 // compression, by having more fewer, larger records. 10072 private void logStrictModeViolationToDropBox( 10073 ProcessRecord process, 10074 StrictMode.ViolationInfo info) { 10075 if (info == null) { 10076 return; 10077 } 10078 final boolean isSystemApp = process == null || 10079 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10080 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10081 final String processName = process == null ? "unknown" : process.processName; 10082 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10083 final DropBoxManager dbox = (DropBoxManager) 10084 mContext.getSystemService(Context.DROPBOX_SERVICE); 10085 10086 // Exit early if the dropbox isn't configured to accept this report type. 10087 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10088 10089 boolean bufferWasEmpty; 10090 boolean needsFlush; 10091 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10092 synchronized (sb) { 10093 bufferWasEmpty = sb.length() == 0; 10094 appendDropBoxProcessHeaders(process, processName, sb); 10095 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10096 sb.append("System-App: ").append(isSystemApp).append("\n"); 10097 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10098 if (info.violationNumThisLoop != 0) { 10099 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10100 } 10101 if (info.numAnimationsRunning != 0) { 10102 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10103 } 10104 if (info.broadcastIntentAction != null) { 10105 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10106 } 10107 if (info.durationMillis != -1) { 10108 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10109 } 10110 if (info.numInstances != -1) { 10111 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10112 } 10113 if (info.tags != null) { 10114 for (String tag : info.tags) { 10115 sb.append("Span-Tag: ").append(tag).append("\n"); 10116 } 10117 } 10118 sb.append("\n"); 10119 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10120 sb.append(info.crashInfo.stackTrace); 10121 } 10122 sb.append("\n"); 10123 10124 // Only buffer up to ~64k. Various logging bits truncate 10125 // things at 128k. 10126 needsFlush = (sb.length() > 64 * 1024); 10127 } 10128 10129 // Flush immediately if the buffer's grown too large, or this 10130 // is a non-system app. Non-system apps are isolated with a 10131 // different tag & policy and not batched. 10132 // 10133 // Batching is useful during internal testing with 10134 // StrictMode settings turned up high. Without batching, 10135 // thousands of separate files could be created on boot. 10136 if (!isSystemApp || needsFlush) { 10137 new Thread("Error dump: " + dropboxTag) { 10138 @Override 10139 public void run() { 10140 String report; 10141 synchronized (sb) { 10142 report = sb.toString(); 10143 sb.delete(0, sb.length()); 10144 sb.trimToSize(); 10145 } 10146 if (report.length() != 0) { 10147 dbox.addText(dropboxTag, report); 10148 } 10149 } 10150 }.start(); 10151 return; 10152 } 10153 10154 // System app batching: 10155 if (!bufferWasEmpty) { 10156 // An existing dropbox-writing thread is outstanding, so 10157 // we don't need to start it up. The existing thread will 10158 // catch the buffer appends we just did. 10159 return; 10160 } 10161 10162 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10163 // (After this point, we shouldn't access AMS internal data structures.) 10164 new Thread("Error dump: " + dropboxTag) { 10165 @Override 10166 public void run() { 10167 // 5 second sleep to let stacks arrive and be batched together 10168 try { 10169 Thread.sleep(5000); // 5 seconds 10170 } catch (InterruptedException e) {} 10171 10172 String errorReport; 10173 synchronized (mStrictModeBuffer) { 10174 errorReport = mStrictModeBuffer.toString(); 10175 if (errorReport.length() == 0) { 10176 return; 10177 } 10178 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10179 mStrictModeBuffer.trimToSize(); 10180 } 10181 dbox.addText(dropboxTag, errorReport); 10182 } 10183 }.start(); 10184 } 10185 10186 /** 10187 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10188 * @param app object of the crashing app, null for the system server 10189 * @param tag reported by the caller 10190 * @param crashInfo describing the context of the error 10191 * @return true if the process should exit immediately (WTF is fatal) 10192 */ 10193 public boolean handleApplicationWtf(IBinder app, String tag, 10194 ApplicationErrorReport.CrashInfo crashInfo) { 10195 ProcessRecord r = findAppProcess(app, "WTF"); 10196 final String processName = app == null ? "system_server" 10197 : (r == null ? "unknown" : r.processName); 10198 10199 EventLog.writeEvent(EventLogTags.AM_WTF, 10200 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10201 processName, 10202 r == null ? -1 : r.info.flags, 10203 tag, crashInfo.exceptionMessage); 10204 10205 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10206 10207 if (r != null && r.pid != Process.myPid() && 10208 Settings.Global.getInt(mContext.getContentResolver(), 10209 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10210 crashApplication(r, crashInfo); 10211 return true; 10212 } else { 10213 return false; 10214 } 10215 } 10216 10217 /** 10218 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10219 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10220 */ 10221 private ProcessRecord findAppProcess(IBinder app, String reason) { 10222 if (app == null) { 10223 return null; 10224 } 10225 10226 synchronized (this) { 10227 final int NP = mProcessNames.getMap().size(); 10228 for (int ip=0; ip<NP; ip++) { 10229 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10230 final int NA = apps.size(); 10231 for (int ia=0; ia<NA; ia++) { 10232 ProcessRecord p = apps.valueAt(ia); 10233 if (p.thread != null && p.thread.asBinder() == app) { 10234 return p; 10235 } 10236 } 10237 } 10238 10239 Slog.w(TAG, "Can't find mystery application for " + reason 10240 + " from pid=" + Binder.getCallingPid() 10241 + " uid=" + Binder.getCallingUid() + ": " + app); 10242 return null; 10243 } 10244 } 10245 10246 /** 10247 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10248 * to append various headers to the dropbox log text. 10249 */ 10250 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10251 StringBuilder sb) { 10252 // Watchdog thread ends up invoking this function (with 10253 // a null ProcessRecord) to add the stack file to dropbox. 10254 // Do not acquire a lock on this (am) in such cases, as it 10255 // could cause a potential deadlock, if and when watchdog 10256 // is invoked due to unavailability of lock on am and it 10257 // would prevent watchdog from killing system_server. 10258 if (process == null) { 10259 sb.append("Process: ").append(processName).append("\n"); 10260 return; 10261 } 10262 // Note: ProcessRecord 'process' is guarded by the service 10263 // instance. (notably process.pkgList, which could otherwise change 10264 // concurrently during execution of this method) 10265 synchronized (this) { 10266 sb.append("Process: ").append(processName).append("\n"); 10267 int flags = process.info.flags; 10268 IPackageManager pm = AppGlobals.getPackageManager(); 10269 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10270 for (int ip=0; ip<process.pkgList.size(); ip++) { 10271 String pkg = process.pkgList.keyAt(ip); 10272 sb.append("Package: ").append(pkg); 10273 try { 10274 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10275 if (pi != null) { 10276 sb.append(" v").append(pi.versionCode); 10277 if (pi.versionName != null) { 10278 sb.append(" (").append(pi.versionName).append(")"); 10279 } 10280 } 10281 } catch (RemoteException e) { 10282 Slog.e(TAG, "Error getting package info: " + pkg, e); 10283 } 10284 sb.append("\n"); 10285 } 10286 } 10287 } 10288 10289 private static String processClass(ProcessRecord process) { 10290 if (process == null || process.pid == MY_PID) { 10291 return "system_server"; 10292 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10293 return "system_app"; 10294 } else { 10295 return "data_app"; 10296 } 10297 } 10298 10299 /** 10300 * Write a description of an error (crash, WTF, ANR) to the drop box. 10301 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10302 * @param process which caused the error, null means the system server 10303 * @param activity which triggered the error, null if unknown 10304 * @param parent activity related to the error, null if unknown 10305 * @param subject line related to the error, null if absent 10306 * @param report in long form describing the error, null if absent 10307 * @param logFile to include in the report, null if none 10308 * @param crashInfo giving an application stack trace, null if absent 10309 */ 10310 public void addErrorToDropBox(String eventType, 10311 ProcessRecord process, String processName, ActivityRecord activity, 10312 ActivityRecord parent, String subject, 10313 final String report, final File logFile, 10314 final ApplicationErrorReport.CrashInfo crashInfo) { 10315 // NOTE -- this must never acquire the ActivityManagerService lock, 10316 // otherwise the watchdog may be prevented from resetting the system. 10317 10318 final String dropboxTag = processClass(process) + "_" + eventType; 10319 final DropBoxManager dbox = (DropBoxManager) 10320 mContext.getSystemService(Context.DROPBOX_SERVICE); 10321 10322 // Exit early if the dropbox isn't configured to accept this report type. 10323 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10324 10325 final StringBuilder sb = new StringBuilder(1024); 10326 appendDropBoxProcessHeaders(process, processName, sb); 10327 if (activity != null) { 10328 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10329 } 10330 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10331 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10332 } 10333 if (parent != null && parent != activity) { 10334 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10335 } 10336 if (subject != null) { 10337 sb.append("Subject: ").append(subject).append("\n"); 10338 } 10339 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10340 if (Debug.isDebuggerConnected()) { 10341 sb.append("Debugger: Connected\n"); 10342 } 10343 sb.append("\n"); 10344 10345 // Do the rest in a worker thread to avoid blocking the caller on I/O 10346 // (After this point, we shouldn't access AMS internal data structures.) 10347 Thread worker = new Thread("Error dump: " + dropboxTag) { 10348 @Override 10349 public void run() { 10350 if (report != null) { 10351 sb.append(report); 10352 } 10353 if (logFile != null) { 10354 try { 10355 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10356 "\n\n[[TRUNCATED]]")); 10357 } catch (IOException e) { 10358 Slog.e(TAG, "Error reading " + logFile, e); 10359 } 10360 } 10361 if (crashInfo != null && crashInfo.stackTrace != null) { 10362 sb.append(crashInfo.stackTrace); 10363 } 10364 10365 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10366 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10367 if (lines > 0) { 10368 sb.append("\n"); 10369 10370 // Merge several logcat streams, and take the last N lines 10371 InputStreamReader input = null; 10372 try { 10373 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10374 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10375 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10376 10377 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10378 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10379 input = new InputStreamReader(logcat.getInputStream()); 10380 10381 int num; 10382 char[] buf = new char[8192]; 10383 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10384 } catch (IOException e) { 10385 Slog.e(TAG, "Error running logcat", e); 10386 } finally { 10387 if (input != null) try { input.close(); } catch (IOException e) {} 10388 } 10389 } 10390 10391 dbox.addText(dropboxTag, sb.toString()); 10392 } 10393 }; 10394 10395 if (process == null) { 10396 // If process is null, we are being called from some internal code 10397 // and may be about to die -- run this synchronously. 10398 worker.run(); 10399 } else { 10400 worker.start(); 10401 } 10402 } 10403 10404 /** 10405 * Bring up the "unexpected error" dialog box for a crashing app. 10406 * Deal with edge cases (intercepts from instrumented applications, 10407 * ActivityController, error intent receivers, that sort of thing). 10408 * @param r the application crashing 10409 * @param crashInfo describing the failure 10410 */ 10411 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10412 long timeMillis = System.currentTimeMillis(); 10413 String shortMsg = crashInfo.exceptionClassName; 10414 String longMsg = crashInfo.exceptionMessage; 10415 String stackTrace = crashInfo.stackTrace; 10416 if (shortMsg != null && longMsg != null) { 10417 longMsg = shortMsg + ": " + longMsg; 10418 } else if (shortMsg != null) { 10419 longMsg = shortMsg; 10420 } 10421 10422 AppErrorResult result = new AppErrorResult(); 10423 synchronized (this) { 10424 if (mController != null) { 10425 try { 10426 String name = r != null ? r.processName : null; 10427 int pid = r != null ? r.pid : Binder.getCallingPid(); 10428 if (!mController.appCrashed(name, pid, 10429 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10430 Slog.w(TAG, "Force-killing crashed app " + name 10431 + " at watcher's request"); 10432 Process.killProcess(pid); 10433 return; 10434 } 10435 } catch (RemoteException e) { 10436 mController = null; 10437 Watchdog.getInstance().setActivityController(null); 10438 } 10439 } 10440 10441 final long origId = Binder.clearCallingIdentity(); 10442 10443 // If this process is running instrumentation, finish it. 10444 if (r != null && r.instrumentationClass != null) { 10445 Slog.w(TAG, "Error in app " + r.processName 10446 + " running instrumentation " + r.instrumentationClass + ":"); 10447 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10448 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10449 Bundle info = new Bundle(); 10450 info.putString("shortMsg", shortMsg); 10451 info.putString("longMsg", longMsg); 10452 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10453 Binder.restoreCallingIdentity(origId); 10454 return; 10455 } 10456 10457 // If we can't identify the process or it's already exceeded its crash quota, 10458 // quit right away without showing a crash dialog. 10459 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10460 Binder.restoreCallingIdentity(origId); 10461 return; 10462 } 10463 10464 Message msg = Message.obtain(); 10465 msg.what = SHOW_ERROR_MSG; 10466 HashMap data = new HashMap(); 10467 data.put("result", result); 10468 data.put("app", r); 10469 msg.obj = data; 10470 mHandler.sendMessage(msg); 10471 10472 Binder.restoreCallingIdentity(origId); 10473 } 10474 10475 int res = result.get(); 10476 10477 Intent appErrorIntent = null; 10478 synchronized (this) { 10479 if (r != null && !r.isolated) { 10480 // XXX Can't keep track of crash time for isolated processes, 10481 // since they don't have a persistent identity. 10482 mProcessCrashTimes.put(r.info.processName, r.uid, 10483 SystemClock.uptimeMillis()); 10484 } 10485 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10486 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10487 } 10488 } 10489 10490 if (appErrorIntent != null) { 10491 try { 10492 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10493 } catch (ActivityNotFoundException e) { 10494 Slog.w(TAG, "bug report receiver dissappeared", e); 10495 } 10496 } 10497 } 10498 10499 Intent createAppErrorIntentLocked(ProcessRecord r, 10500 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10501 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10502 if (report == null) { 10503 return null; 10504 } 10505 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10506 result.setComponent(r.errorReportReceiver); 10507 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10508 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10509 return result; 10510 } 10511 10512 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10513 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10514 if (r.errorReportReceiver == null) { 10515 return null; 10516 } 10517 10518 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10519 return null; 10520 } 10521 10522 ApplicationErrorReport report = new ApplicationErrorReport(); 10523 report.packageName = r.info.packageName; 10524 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10525 report.processName = r.processName; 10526 report.time = timeMillis; 10527 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10528 10529 if (r.crashing || r.forceCrashReport) { 10530 report.type = ApplicationErrorReport.TYPE_CRASH; 10531 report.crashInfo = crashInfo; 10532 } else if (r.notResponding) { 10533 report.type = ApplicationErrorReport.TYPE_ANR; 10534 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10535 10536 report.anrInfo.activity = r.notRespondingReport.tag; 10537 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10538 report.anrInfo.info = r.notRespondingReport.longMsg; 10539 } 10540 10541 return report; 10542 } 10543 10544 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10545 enforceNotIsolatedCaller("getProcessesInErrorState"); 10546 // assume our apps are happy - lazy create the list 10547 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10548 10549 final boolean allUsers = ActivityManager.checkUidPermission( 10550 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10551 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10552 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10553 10554 synchronized (this) { 10555 10556 // iterate across all processes 10557 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10558 ProcessRecord app = mLruProcesses.get(i); 10559 if (!allUsers && app.userId != userId) { 10560 continue; 10561 } 10562 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10563 // This one's in trouble, so we'll generate a report for it 10564 // crashes are higher priority (in case there's a crash *and* an anr) 10565 ActivityManager.ProcessErrorStateInfo report = null; 10566 if (app.crashing) { 10567 report = app.crashingReport; 10568 } else if (app.notResponding) { 10569 report = app.notRespondingReport; 10570 } 10571 10572 if (report != null) { 10573 if (errList == null) { 10574 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10575 } 10576 errList.add(report); 10577 } else { 10578 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10579 " crashing = " + app.crashing + 10580 " notResponding = " + app.notResponding); 10581 } 10582 } 10583 } 10584 } 10585 10586 return errList; 10587 } 10588 10589 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10590 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10591 if (currApp != null) { 10592 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10593 } 10594 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10595 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10596 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10597 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10598 if (currApp != null) { 10599 currApp.lru = 0; 10600 } 10601 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10602 } else if (adj >= ProcessList.SERVICE_ADJ) { 10603 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10604 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10605 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10606 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10607 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10608 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10609 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10610 } else { 10611 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10612 } 10613 } 10614 10615 private void fillInProcMemInfo(ProcessRecord app, 10616 ActivityManager.RunningAppProcessInfo outInfo) { 10617 outInfo.pid = app.pid; 10618 outInfo.uid = app.info.uid; 10619 if (mHeavyWeightProcess == app) { 10620 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10621 } 10622 if (app.persistent) { 10623 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10624 } 10625 if (app.activities.size() > 0) { 10626 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10627 } 10628 outInfo.lastTrimLevel = app.trimMemoryLevel; 10629 int adj = app.curAdj; 10630 outInfo.importance = oomAdjToImportance(adj, outInfo); 10631 outInfo.importanceReasonCode = app.adjTypeCode; 10632 outInfo.processState = app.curProcState; 10633 } 10634 10635 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10636 enforceNotIsolatedCaller("getRunningAppProcesses"); 10637 // Lazy instantiation of list 10638 List<ActivityManager.RunningAppProcessInfo> runList = null; 10639 final boolean allUsers = ActivityManager.checkUidPermission( 10640 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10641 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10642 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10643 synchronized (this) { 10644 // Iterate across all processes 10645 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10646 ProcessRecord app = mLruProcesses.get(i); 10647 if (!allUsers && app.userId != userId) { 10648 continue; 10649 } 10650 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10651 // Generate process state info for running application 10652 ActivityManager.RunningAppProcessInfo currApp = 10653 new ActivityManager.RunningAppProcessInfo(app.processName, 10654 app.pid, app.getPackageList()); 10655 fillInProcMemInfo(app, currApp); 10656 if (app.adjSource instanceof ProcessRecord) { 10657 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10658 currApp.importanceReasonImportance = oomAdjToImportance( 10659 app.adjSourceOom, null); 10660 } else if (app.adjSource instanceof ActivityRecord) { 10661 ActivityRecord r = (ActivityRecord)app.adjSource; 10662 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10663 } 10664 if (app.adjTarget instanceof ComponentName) { 10665 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10666 } 10667 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10668 // + " lru=" + currApp.lru); 10669 if (runList == null) { 10670 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10671 } 10672 runList.add(currApp); 10673 } 10674 } 10675 } 10676 return runList; 10677 } 10678 10679 public List<ApplicationInfo> getRunningExternalApplications() { 10680 enforceNotIsolatedCaller("getRunningExternalApplications"); 10681 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10682 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10683 if (runningApps != null && runningApps.size() > 0) { 10684 Set<String> extList = new HashSet<String>(); 10685 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10686 if (app.pkgList != null) { 10687 for (String pkg : app.pkgList) { 10688 extList.add(pkg); 10689 } 10690 } 10691 } 10692 IPackageManager pm = AppGlobals.getPackageManager(); 10693 for (String pkg : extList) { 10694 try { 10695 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10696 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10697 retList.add(info); 10698 } 10699 } catch (RemoteException e) { 10700 } 10701 } 10702 } 10703 return retList; 10704 } 10705 10706 @Override 10707 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10708 enforceNotIsolatedCaller("getMyMemoryState"); 10709 synchronized (this) { 10710 ProcessRecord proc; 10711 synchronized (mPidsSelfLocked) { 10712 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10713 } 10714 fillInProcMemInfo(proc, outInfo); 10715 } 10716 } 10717 10718 @Override 10719 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10720 if (checkCallingPermission(android.Manifest.permission.DUMP) 10721 != PackageManager.PERMISSION_GRANTED) { 10722 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10723 + Binder.getCallingPid() 10724 + ", uid=" + Binder.getCallingUid() 10725 + " without permission " 10726 + android.Manifest.permission.DUMP); 10727 return; 10728 } 10729 10730 boolean dumpAll = false; 10731 boolean dumpClient = false; 10732 String dumpPackage = null; 10733 10734 int opti = 0; 10735 while (opti < args.length) { 10736 String opt = args[opti]; 10737 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10738 break; 10739 } 10740 opti++; 10741 if ("-a".equals(opt)) { 10742 dumpAll = true; 10743 } else if ("-c".equals(opt)) { 10744 dumpClient = true; 10745 } else if ("-h".equals(opt)) { 10746 pw.println("Activity manager dump options:"); 10747 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10748 pw.println(" cmd may be one of:"); 10749 pw.println(" a[ctivities]: activity stack state"); 10750 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10751 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10752 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10753 pw.println(" o[om]: out of memory management"); 10754 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10755 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10756 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10757 pw.println(" service [COMP_SPEC]: service client-side state"); 10758 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10759 pw.println(" all: dump all activities"); 10760 pw.println(" top: dump the top activity"); 10761 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10762 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10763 pw.println(" a partial substring in a component name, a"); 10764 pw.println(" hex object identifier."); 10765 pw.println(" -a: include all available server state."); 10766 pw.println(" -c: include client state."); 10767 return; 10768 } else { 10769 pw.println("Unknown argument: " + opt + "; use -h for help"); 10770 } 10771 } 10772 10773 long origId = Binder.clearCallingIdentity(); 10774 boolean more = false; 10775 // Is the caller requesting to dump a particular piece of data? 10776 if (opti < args.length) { 10777 String cmd = args[opti]; 10778 opti++; 10779 if ("activities".equals(cmd) || "a".equals(cmd)) { 10780 synchronized (this) { 10781 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10782 } 10783 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10784 String[] newArgs; 10785 String name; 10786 if (opti >= args.length) { 10787 name = null; 10788 newArgs = EMPTY_STRING_ARRAY; 10789 } else { 10790 name = args[opti]; 10791 opti++; 10792 newArgs = new String[args.length - opti]; 10793 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10794 args.length - opti); 10795 } 10796 synchronized (this) { 10797 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10798 } 10799 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10800 String[] newArgs; 10801 String name; 10802 if (opti >= args.length) { 10803 name = null; 10804 newArgs = EMPTY_STRING_ARRAY; 10805 } else { 10806 name = args[opti]; 10807 opti++; 10808 newArgs = new String[args.length - opti]; 10809 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10810 args.length - opti); 10811 } 10812 synchronized (this) { 10813 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10814 } 10815 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10816 String[] newArgs; 10817 String name; 10818 if (opti >= args.length) { 10819 name = null; 10820 newArgs = EMPTY_STRING_ARRAY; 10821 } else { 10822 name = args[opti]; 10823 opti++; 10824 newArgs = new String[args.length - opti]; 10825 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10826 args.length - opti); 10827 } 10828 synchronized (this) { 10829 dumpProcessesLocked(fd, pw, args, opti, true, name); 10830 } 10831 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10832 synchronized (this) { 10833 dumpOomLocked(fd, pw, args, opti, true); 10834 } 10835 } else if ("provider".equals(cmd)) { 10836 String[] newArgs; 10837 String name; 10838 if (opti >= args.length) { 10839 name = null; 10840 newArgs = EMPTY_STRING_ARRAY; 10841 } else { 10842 name = args[opti]; 10843 opti++; 10844 newArgs = new String[args.length - opti]; 10845 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10846 } 10847 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10848 pw.println("No providers match: " + name); 10849 pw.println("Use -h for help."); 10850 } 10851 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10852 synchronized (this) { 10853 dumpProvidersLocked(fd, pw, args, opti, true, null); 10854 } 10855 } else if ("service".equals(cmd)) { 10856 String[] newArgs; 10857 String name; 10858 if (opti >= args.length) { 10859 name = null; 10860 newArgs = EMPTY_STRING_ARRAY; 10861 } else { 10862 name = args[opti]; 10863 opti++; 10864 newArgs = new String[args.length - opti]; 10865 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10866 args.length - opti); 10867 } 10868 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10869 pw.println("No services match: " + name); 10870 pw.println("Use -h for help."); 10871 } 10872 } else if ("package".equals(cmd)) { 10873 String[] newArgs; 10874 if (opti >= args.length) { 10875 pw.println("package: no package name specified"); 10876 pw.println("Use -h for help."); 10877 } else { 10878 dumpPackage = args[opti]; 10879 opti++; 10880 newArgs = new String[args.length - opti]; 10881 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10882 args.length - opti); 10883 args = newArgs; 10884 opti = 0; 10885 more = true; 10886 } 10887 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10888 synchronized (this) { 10889 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10890 } 10891 } else { 10892 // Dumping a single activity? 10893 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10894 pw.println("Bad activity command, or no activities match: " + cmd); 10895 pw.println("Use -h for help."); 10896 } 10897 } 10898 if (!more) { 10899 Binder.restoreCallingIdentity(origId); 10900 return; 10901 } 10902 } 10903 10904 // No piece of data specified, dump everything. 10905 synchronized (this) { 10906 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10907 pw.println(); 10908 if (dumpAll) { 10909 pw.println("-------------------------------------------------------------------------------"); 10910 } 10911 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10912 pw.println(); 10913 if (dumpAll) { 10914 pw.println("-------------------------------------------------------------------------------"); 10915 } 10916 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10917 pw.println(); 10918 if (dumpAll) { 10919 pw.println("-------------------------------------------------------------------------------"); 10920 } 10921 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10922 pw.println(); 10923 if (dumpAll) { 10924 pw.println("-------------------------------------------------------------------------------"); 10925 } 10926 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10927 pw.println(); 10928 if (dumpAll) { 10929 pw.println("-------------------------------------------------------------------------------"); 10930 } 10931 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10932 } 10933 Binder.restoreCallingIdentity(origId); 10934 } 10935 10936 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10937 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10938 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10939 10940 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10941 dumpPackage); 10942 boolean needSep = printedAnything; 10943 10944 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10945 dumpPackage, needSep, " mFocusedActivity: "); 10946 if (printed) { 10947 printedAnything = true; 10948 needSep = false; 10949 } 10950 10951 if (dumpPackage == null) { 10952 if (needSep) { 10953 pw.println(); 10954 } 10955 needSep = true; 10956 printedAnything = true; 10957 mStackSupervisor.dump(pw, " "); 10958 } 10959 10960 if (mRecentTasks.size() > 0) { 10961 boolean printedHeader = false; 10962 10963 final int N = mRecentTasks.size(); 10964 for (int i=0; i<N; i++) { 10965 TaskRecord tr = mRecentTasks.get(i); 10966 if (dumpPackage != null) { 10967 if (tr.realActivity == null || 10968 !dumpPackage.equals(tr.realActivity)) { 10969 continue; 10970 } 10971 } 10972 if (!printedHeader) { 10973 if (needSep) { 10974 pw.println(); 10975 } 10976 pw.println(" Recent tasks:"); 10977 printedHeader = true; 10978 printedAnything = true; 10979 } 10980 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10981 pw.println(tr); 10982 if (dumpAll) { 10983 mRecentTasks.get(i).dump(pw, " "); 10984 } 10985 } 10986 } 10987 10988 if (!printedAnything) { 10989 pw.println(" (nothing)"); 10990 } 10991 } 10992 10993 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10994 int opti, boolean dumpAll, String dumpPackage) { 10995 boolean needSep = false; 10996 boolean printedAnything = false; 10997 int numPers = 0; 10998 10999 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11000 11001 if (dumpAll) { 11002 final int NP = mProcessNames.getMap().size(); 11003 for (int ip=0; ip<NP; ip++) { 11004 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11005 final int NA = procs.size(); 11006 for (int ia=0; ia<NA; ia++) { 11007 ProcessRecord r = procs.valueAt(ia); 11008 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11009 continue; 11010 } 11011 if (!needSep) { 11012 pw.println(" All known processes:"); 11013 needSep = true; 11014 printedAnything = true; 11015 } 11016 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11017 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11018 pw.print(" "); pw.println(r); 11019 r.dump(pw, " "); 11020 if (r.persistent) { 11021 numPers++; 11022 } 11023 } 11024 } 11025 } 11026 11027 if (mIsolatedProcesses.size() > 0) { 11028 boolean printed = false; 11029 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11030 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11031 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11032 continue; 11033 } 11034 if (!printed) { 11035 if (needSep) { 11036 pw.println(); 11037 } 11038 pw.println(" Isolated process list (sorted by uid):"); 11039 printedAnything = true; 11040 printed = true; 11041 needSep = true; 11042 } 11043 pw.println(String.format("%sIsolated #%2d: %s", 11044 " ", i, r.toString())); 11045 } 11046 } 11047 11048 if (mLruProcesses.size() > 0) { 11049 if (needSep) { 11050 pw.println(); 11051 } 11052 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11053 pw.print(" total, non-act at "); 11054 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11055 pw.print(", non-svc at "); 11056 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11057 pw.println("):"); 11058 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11059 needSep = true; 11060 printedAnything = true; 11061 } 11062 11063 if (dumpAll || dumpPackage != null) { 11064 synchronized (mPidsSelfLocked) { 11065 boolean printed = false; 11066 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11067 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11068 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11069 continue; 11070 } 11071 if (!printed) { 11072 if (needSep) pw.println(); 11073 needSep = true; 11074 pw.println(" PID mappings:"); 11075 printed = true; 11076 printedAnything = true; 11077 } 11078 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11079 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11080 } 11081 } 11082 } 11083 11084 if (mForegroundProcesses.size() > 0) { 11085 synchronized (mPidsSelfLocked) { 11086 boolean printed = false; 11087 for (int i=0; i<mForegroundProcesses.size(); i++) { 11088 ProcessRecord r = mPidsSelfLocked.get( 11089 mForegroundProcesses.valueAt(i).pid); 11090 if (dumpPackage != null && (r == null 11091 || !r.pkgList.containsKey(dumpPackage))) { 11092 continue; 11093 } 11094 if (!printed) { 11095 if (needSep) pw.println(); 11096 needSep = true; 11097 pw.println(" Foreground Processes:"); 11098 printed = true; 11099 printedAnything = true; 11100 } 11101 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11102 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11103 } 11104 } 11105 } 11106 11107 if (mPersistentStartingProcesses.size() > 0) { 11108 if (needSep) pw.println(); 11109 needSep = true; 11110 printedAnything = true; 11111 pw.println(" Persisent processes that are starting:"); 11112 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11113 "Starting Norm", "Restarting PERS", dumpPackage); 11114 } 11115 11116 if (mRemovedProcesses.size() > 0) { 11117 if (needSep) pw.println(); 11118 needSep = true; 11119 printedAnything = true; 11120 pw.println(" Processes that are being removed:"); 11121 dumpProcessList(pw, this, mRemovedProcesses, " ", 11122 "Removed Norm", "Removed PERS", dumpPackage); 11123 } 11124 11125 if (mProcessesOnHold.size() > 0) { 11126 if (needSep) pw.println(); 11127 needSep = true; 11128 printedAnything = true; 11129 pw.println(" Processes that are on old until the system is ready:"); 11130 dumpProcessList(pw, this, mProcessesOnHold, " ", 11131 "OnHold Norm", "OnHold PERS", dumpPackage); 11132 } 11133 11134 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11135 11136 if (mProcessCrashTimes.getMap().size() > 0) { 11137 boolean printed = false; 11138 long now = SystemClock.uptimeMillis(); 11139 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11140 final int NP = pmap.size(); 11141 for (int ip=0; ip<NP; ip++) { 11142 String pname = pmap.keyAt(ip); 11143 SparseArray<Long> uids = pmap.valueAt(ip); 11144 final int N = uids.size(); 11145 for (int i=0; i<N; i++) { 11146 int puid = uids.keyAt(i); 11147 ProcessRecord r = mProcessNames.get(pname, puid); 11148 if (dumpPackage != null && (r == null 11149 || !r.pkgList.containsKey(dumpPackage))) { 11150 continue; 11151 } 11152 if (!printed) { 11153 if (needSep) pw.println(); 11154 needSep = true; 11155 pw.println(" Time since processes crashed:"); 11156 printed = true; 11157 printedAnything = true; 11158 } 11159 pw.print(" Process "); pw.print(pname); 11160 pw.print(" uid "); pw.print(puid); 11161 pw.print(": last crashed "); 11162 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11163 pw.println(" ago"); 11164 } 11165 } 11166 } 11167 11168 if (mBadProcesses.getMap().size() > 0) { 11169 boolean printed = false; 11170 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11171 final int NP = pmap.size(); 11172 for (int ip=0; ip<NP; ip++) { 11173 String pname = pmap.keyAt(ip); 11174 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11175 final int N = uids.size(); 11176 for (int i=0; i<N; i++) { 11177 int puid = uids.keyAt(i); 11178 ProcessRecord r = mProcessNames.get(pname, puid); 11179 if (dumpPackage != null && (r == null 11180 || !r.pkgList.containsKey(dumpPackage))) { 11181 continue; 11182 } 11183 if (!printed) { 11184 if (needSep) pw.println(); 11185 needSep = true; 11186 pw.println(" Bad processes:"); 11187 printedAnything = true; 11188 } 11189 BadProcessInfo info = uids.valueAt(i); 11190 pw.print(" Bad process "); pw.print(pname); 11191 pw.print(" uid "); pw.print(puid); 11192 pw.print(": crashed at time "); pw.println(info.time); 11193 if (info.shortMsg != null) { 11194 pw.print(" Short msg: "); pw.println(info.shortMsg); 11195 } 11196 if (info.longMsg != null) { 11197 pw.print(" Long msg: "); pw.println(info.longMsg); 11198 } 11199 if (info.stack != null) { 11200 pw.println(" Stack:"); 11201 int lastPos = 0; 11202 for (int pos=0; pos<info.stack.length(); pos++) { 11203 if (info.stack.charAt(pos) == '\n') { 11204 pw.print(" "); 11205 pw.write(info.stack, lastPos, pos-lastPos); 11206 pw.println(); 11207 lastPos = pos+1; 11208 } 11209 } 11210 if (lastPos < info.stack.length()) { 11211 pw.print(" "); 11212 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11213 pw.println(); 11214 } 11215 } 11216 } 11217 } 11218 } 11219 11220 if (dumpPackage == null) { 11221 pw.println(); 11222 needSep = false; 11223 pw.println(" mStartedUsers:"); 11224 for (int i=0; i<mStartedUsers.size(); i++) { 11225 UserStartedState uss = mStartedUsers.valueAt(i); 11226 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11227 pw.print(": "); uss.dump("", pw); 11228 } 11229 pw.print(" mStartedUserArray: ["); 11230 for (int i=0; i<mStartedUserArray.length; i++) { 11231 if (i > 0) pw.print(", "); 11232 pw.print(mStartedUserArray[i]); 11233 } 11234 pw.println("]"); 11235 pw.print(" mUserLru: ["); 11236 for (int i=0; i<mUserLru.size(); i++) { 11237 if (i > 0) pw.print(", "); 11238 pw.print(mUserLru.get(i)); 11239 } 11240 pw.println("]"); 11241 if (dumpAll) { 11242 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11243 } 11244 } 11245 if (mHomeProcess != null && (dumpPackage == null 11246 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11247 if (needSep) { 11248 pw.println(); 11249 needSep = false; 11250 } 11251 pw.println(" mHomeProcess: " + mHomeProcess); 11252 } 11253 if (mPreviousProcess != null && (dumpPackage == null 11254 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11255 if (needSep) { 11256 pw.println(); 11257 needSep = false; 11258 } 11259 pw.println(" mPreviousProcess: " + mPreviousProcess); 11260 } 11261 if (dumpAll) { 11262 StringBuilder sb = new StringBuilder(128); 11263 sb.append(" mPreviousProcessVisibleTime: "); 11264 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11265 pw.println(sb); 11266 } 11267 if (mHeavyWeightProcess != null && (dumpPackage == null 11268 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11269 if (needSep) { 11270 pw.println(); 11271 needSep = false; 11272 } 11273 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11274 } 11275 if (dumpPackage == null) { 11276 pw.println(" mConfiguration: " + mConfiguration); 11277 } 11278 if (dumpAll) { 11279 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11280 if (mCompatModePackages.getPackages().size() > 0) { 11281 boolean printed = false; 11282 for (Map.Entry<String, Integer> entry 11283 : mCompatModePackages.getPackages().entrySet()) { 11284 String pkg = entry.getKey(); 11285 int mode = entry.getValue(); 11286 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11287 continue; 11288 } 11289 if (!printed) { 11290 pw.println(" mScreenCompatPackages:"); 11291 printed = true; 11292 } 11293 pw.print(" "); pw.print(pkg); pw.print(": "); 11294 pw.print(mode); pw.println(); 11295 } 11296 } 11297 } 11298 if (dumpPackage == null) { 11299 if (mSleeping || mWentToSleep || mLockScreenShown) { 11300 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11301 + " mLockScreenShown " + mLockScreenShown); 11302 } 11303 if (mShuttingDown || mRunningVoice) { 11304 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11305 } 11306 } 11307 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11308 || mOrigWaitForDebugger) { 11309 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11310 || dumpPackage.equals(mOrigDebugApp)) { 11311 if (needSep) { 11312 pw.println(); 11313 needSep = false; 11314 } 11315 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11316 + " mDebugTransient=" + mDebugTransient 11317 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11318 } 11319 } 11320 if (mOpenGlTraceApp != null) { 11321 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11322 if (needSep) { 11323 pw.println(); 11324 needSep = false; 11325 } 11326 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11327 } 11328 } 11329 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11330 || mProfileFd != null) { 11331 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11332 if (needSep) { 11333 pw.println(); 11334 needSep = false; 11335 } 11336 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11337 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11338 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11339 + mAutoStopProfiler); 11340 } 11341 } 11342 if (dumpPackage == null) { 11343 if (mAlwaysFinishActivities || mController != null) { 11344 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11345 + " mController=" + mController); 11346 } 11347 if (dumpAll) { 11348 pw.println(" Total persistent processes: " + numPers); 11349 pw.println(" mProcessesReady=" + mProcessesReady 11350 + " mSystemReady=" + mSystemReady); 11351 pw.println(" mBooting=" + mBooting 11352 + " mBooted=" + mBooted 11353 + " mFactoryTest=" + mFactoryTest); 11354 pw.print(" mLastPowerCheckRealtime="); 11355 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11356 pw.println(""); 11357 pw.print(" mLastPowerCheckUptime="); 11358 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11359 pw.println(""); 11360 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11361 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11362 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11363 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11364 + " (" + mLruProcesses.size() + " total)" 11365 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11366 + " mNumServiceProcs=" + mNumServiceProcs 11367 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11368 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11369 + " mLastMemoryLevel" + mLastMemoryLevel 11370 + " mLastNumProcesses" + mLastNumProcesses); 11371 long now = SystemClock.uptimeMillis(); 11372 pw.print(" mLastIdleTime="); 11373 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11374 pw.print(" mLowRamSinceLastIdle="); 11375 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11376 pw.println(); 11377 } 11378 } 11379 11380 if (!printedAnything) { 11381 pw.println(" (nothing)"); 11382 } 11383 } 11384 11385 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11386 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11387 if (mProcessesToGc.size() > 0) { 11388 boolean printed = false; 11389 long now = SystemClock.uptimeMillis(); 11390 for (int i=0; i<mProcessesToGc.size(); i++) { 11391 ProcessRecord proc = mProcessesToGc.get(i); 11392 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11393 continue; 11394 } 11395 if (!printed) { 11396 if (needSep) pw.println(); 11397 needSep = true; 11398 pw.println(" Processes that are waiting to GC:"); 11399 printed = true; 11400 } 11401 pw.print(" Process "); pw.println(proc); 11402 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11403 pw.print(", last gced="); 11404 pw.print(now-proc.lastRequestedGc); 11405 pw.print(" ms ago, last lowMem="); 11406 pw.print(now-proc.lastLowMemory); 11407 pw.println(" ms ago"); 11408 11409 } 11410 } 11411 return needSep; 11412 } 11413 11414 void printOomLevel(PrintWriter pw, String name, int adj) { 11415 pw.print(" "); 11416 if (adj >= 0) { 11417 pw.print(' '); 11418 if (adj < 10) pw.print(' '); 11419 } else { 11420 if (adj > -10) pw.print(' '); 11421 } 11422 pw.print(adj); 11423 pw.print(": "); 11424 pw.print(name); 11425 pw.print(" ("); 11426 pw.print(mProcessList.getMemLevel(adj)/1024); 11427 pw.println(" kB)"); 11428 } 11429 11430 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11431 int opti, boolean dumpAll) { 11432 boolean needSep = false; 11433 11434 if (mLruProcesses.size() > 0) { 11435 if (needSep) pw.println(); 11436 needSep = true; 11437 pw.println(" OOM levels:"); 11438 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11439 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11440 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11441 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11442 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11443 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11444 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11445 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11446 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11447 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11448 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11449 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11450 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11451 11452 if (needSep) pw.println(); 11453 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11454 pw.print(" total, non-act at "); 11455 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11456 pw.print(", non-svc at "); 11457 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11458 pw.println("):"); 11459 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11460 needSep = true; 11461 } 11462 11463 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11464 11465 pw.println(); 11466 pw.println(" mHomeProcess: " + mHomeProcess); 11467 pw.println(" mPreviousProcess: " + mPreviousProcess); 11468 if (mHeavyWeightProcess != null) { 11469 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11470 } 11471 11472 return true; 11473 } 11474 11475 /** 11476 * There are three ways to call this: 11477 * - no provider specified: dump all the providers 11478 * - a flattened component name that matched an existing provider was specified as the 11479 * first arg: dump that one provider 11480 * - the first arg isn't the flattened component name of an existing provider: 11481 * dump all providers whose component contains the first arg as a substring 11482 */ 11483 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11484 int opti, boolean dumpAll) { 11485 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11486 } 11487 11488 static class ItemMatcher { 11489 ArrayList<ComponentName> components; 11490 ArrayList<String> strings; 11491 ArrayList<Integer> objects; 11492 boolean all; 11493 11494 ItemMatcher() { 11495 all = true; 11496 } 11497 11498 void build(String name) { 11499 ComponentName componentName = ComponentName.unflattenFromString(name); 11500 if (componentName != null) { 11501 if (components == null) { 11502 components = new ArrayList<ComponentName>(); 11503 } 11504 components.add(componentName); 11505 all = false; 11506 } else { 11507 int objectId = 0; 11508 // Not a '/' separated full component name; maybe an object ID? 11509 try { 11510 objectId = Integer.parseInt(name, 16); 11511 if (objects == null) { 11512 objects = new ArrayList<Integer>(); 11513 } 11514 objects.add(objectId); 11515 all = false; 11516 } catch (RuntimeException e) { 11517 // Not an integer; just do string match. 11518 if (strings == null) { 11519 strings = new ArrayList<String>(); 11520 } 11521 strings.add(name); 11522 all = false; 11523 } 11524 } 11525 } 11526 11527 int build(String[] args, int opti) { 11528 for (; opti<args.length; opti++) { 11529 String name = args[opti]; 11530 if ("--".equals(name)) { 11531 return opti+1; 11532 } 11533 build(name); 11534 } 11535 return opti; 11536 } 11537 11538 boolean match(Object object, ComponentName comp) { 11539 if (all) { 11540 return true; 11541 } 11542 if (components != null) { 11543 for (int i=0; i<components.size(); i++) { 11544 if (components.get(i).equals(comp)) { 11545 return true; 11546 } 11547 } 11548 } 11549 if (objects != null) { 11550 for (int i=0; i<objects.size(); i++) { 11551 if (System.identityHashCode(object) == objects.get(i)) { 11552 return true; 11553 } 11554 } 11555 } 11556 if (strings != null) { 11557 String flat = comp.flattenToString(); 11558 for (int i=0; i<strings.size(); i++) { 11559 if (flat.contains(strings.get(i))) { 11560 return true; 11561 } 11562 } 11563 } 11564 return false; 11565 } 11566 } 11567 11568 /** 11569 * There are three things that cmd can be: 11570 * - a flattened component name that matches an existing activity 11571 * - the cmd arg isn't the flattened component name of an existing activity: 11572 * dump all activity whose component contains the cmd as a substring 11573 * - A hex number of the ActivityRecord object instance. 11574 */ 11575 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11576 int opti, boolean dumpAll) { 11577 ArrayList<ActivityRecord> activities; 11578 11579 synchronized (this) { 11580 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11581 } 11582 11583 if (activities.size() <= 0) { 11584 return false; 11585 } 11586 11587 String[] newArgs = new String[args.length - opti]; 11588 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11589 11590 TaskRecord lastTask = null; 11591 boolean needSep = false; 11592 for (int i=activities.size()-1; i>=0; i--) { 11593 ActivityRecord r = activities.get(i); 11594 if (needSep) { 11595 pw.println(); 11596 } 11597 needSep = true; 11598 synchronized (this) { 11599 if (lastTask != r.task) { 11600 lastTask = r.task; 11601 pw.print("TASK "); pw.print(lastTask.affinity); 11602 pw.print(" id="); pw.println(lastTask.taskId); 11603 if (dumpAll) { 11604 lastTask.dump(pw, " "); 11605 } 11606 } 11607 } 11608 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11609 } 11610 return true; 11611 } 11612 11613 /** 11614 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11615 * there is a thread associated with the activity. 11616 */ 11617 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11618 final ActivityRecord r, String[] args, boolean dumpAll) { 11619 String innerPrefix = prefix + " "; 11620 synchronized (this) { 11621 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11622 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11623 pw.print(" pid="); 11624 if (r.app != null) pw.println(r.app.pid); 11625 else pw.println("(not running)"); 11626 if (dumpAll) { 11627 r.dump(pw, innerPrefix); 11628 } 11629 } 11630 if (r.app != null && r.app.thread != null) { 11631 // flush anything that is already in the PrintWriter since the thread is going 11632 // to write to the file descriptor directly 11633 pw.flush(); 11634 try { 11635 TransferPipe tp = new TransferPipe(); 11636 try { 11637 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11638 r.appToken, innerPrefix, args); 11639 tp.go(fd); 11640 } finally { 11641 tp.kill(); 11642 } 11643 } catch (IOException e) { 11644 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11645 } catch (RemoteException e) { 11646 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11647 } 11648 } 11649 } 11650 11651 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11652 int opti, boolean dumpAll, String dumpPackage) { 11653 boolean needSep = false; 11654 boolean onlyHistory = false; 11655 boolean printedAnything = false; 11656 11657 if ("history".equals(dumpPackage)) { 11658 if (opti < args.length && "-s".equals(args[opti])) { 11659 dumpAll = false; 11660 } 11661 onlyHistory = true; 11662 dumpPackage = null; 11663 } 11664 11665 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11666 if (!onlyHistory && dumpAll) { 11667 if (mRegisteredReceivers.size() > 0) { 11668 boolean printed = false; 11669 Iterator it = mRegisteredReceivers.values().iterator(); 11670 while (it.hasNext()) { 11671 ReceiverList r = (ReceiverList)it.next(); 11672 if (dumpPackage != null && (r.app == null || 11673 !dumpPackage.equals(r.app.info.packageName))) { 11674 continue; 11675 } 11676 if (!printed) { 11677 pw.println(" Registered Receivers:"); 11678 needSep = true; 11679 printed = true; 11680 printedAnything = true; 11681 } 11682 pw.print(" * "); pw.println(r); 11683 r.dump(pw, " "); 11684 } 11685 } 11686 11687 if (mReceiverResolver.dump(pw, needSep ? 11688 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11689 " ", dumpPackage, false)) { 11690 needSep = true; 11691 printedAnything = true; 11692 } 11693 } 11694 11695 for (BroadcastQueue q : mBroadcastQueues) { 11696 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11697 printedAnything |= needSep; 11698 } 11699 11700 needSep = true; 11701 11702 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11703 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11704 if (needSep) { 11705 pw.println(); 11706 } 11707 needSep = true; 11708 printedAnything = true; 11709 pw.print(" Sticky broadcasts for user "); 11710 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11711 StringBuilder sb = new StringBuilder(128); 11712 for (Map.Entry<String, ArrayList<Intent>> ent 11713 : mStickyBroadcasts.valueAt(user).entrySet()) { 11714 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11715 if (dumpAll) { 11716 pw.println(":"); 11717 ArrayList<Intent> intents = ent.getValue(); 11718 final int N = intents.size(); 11719 for (int i=0; i<N; i++) { 11720 sb.setLength(0); 11721 sb.append(" Intent: "); 11722 intents.get(i).toShortString(sb, false, true, false, false); 11723 pw.println(sb.toString()); 11724 Bundle bundle = intents.get(i).getExtras(); 11725 if (bundle != null) { 11726 pw.print(" "); 11727 pw.println(bundle.toString()); 11728 } 11729 } 11730 } else { 11731 pw.println(""); 11732 } 11733 } 11734 } 11735 } 11736 11737 if (!onlyHistory && dumpAll) { 11738 pw.println(); 11739 for (BroadcastQueue queue : mBroadcastQueues) { 11740 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11741 + queue.mBroadcastsScheduled); 11742 } 11743 pw.println(" mHandler:"); 11744 mHandler.dump(new PrintWriterPrinter(pw), " "); 11745 needSep = true; 11746 printedAnything = true; 11747 } 11748 11749 if (!printedAnything) { 11750 pw.println(" (nothing)"); 11751 } 11752 } 11753 11754 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11755 int opti, boolean dumpAll, String dumpPackage) { 11756 boolean needSep; 11757 boolean printedAnything = false; 11758 11759 ItemMatcher matcher = new ItemMatcher(); 11760 matcher.build(args, opti); 11761 11762 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11763 11764 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11765 printedAnything |= needSep; 11766 11767 if (mLaunchingProviders.size() > 0) { 11768 boolean printed = false; 11769 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11770 ContentProviderRecord r = mLaunchingProviders.get(i); 11771 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11772 continue; 11773 } 11774 if (!printed) { 11775 if (needSep) pw.println(); 11776 needSep = true; 11777 pw.println(" Launching content providers:"); 11778 printed = true; 11779 printedAnything = true; 11780 } 11781 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11782 pw.println(r); 11783 } 11784 } 11785 11786 if (mGrantedUriPermissions.size() > 0) { 11787 boolean printed = false; 11788 int dumpUid = -2; 11789 if (dumpPackage != null) { 11790 try { 11791 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11792 } catch (NameNotFoundException e) { 11793 dumpUid = -1; 11794 } 11795 } 11796 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11797 int uid = mGrantedUriPermissions.keyAt(i); 11798 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11799 continue; 11800 } 11801 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11802 if (!printed) { 11803 if (needSep) pw.println(); 11804 needSep = true; 11805 pw.println(" Granted Uri Permissions:"); 11806 printed = true; 11807 printedAnything = true; 11808 } 11809 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11810 for (UriPermission perm : perms.values()) { 11811 pw.print(" "); pw.println(perm); 11812 if (dumpAll) { 11813 perm.dump(pw, " "); 11814 } 11815 } 11816 } 11817 } 11818 11819 if (!printedAnything) { 11820 pw.println(" (nothing)"); 11821 } 11822 } 11823 11824 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11825 int opti, boolean dumpAll, String dumpPackage) { 11826 boolean printed = false; 11827 11828 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11829 11830 if (mIntentSenderRecords.size() > 0) { 11831 Iterator<WeakReference<PendingIntentRecord>> it 11832 = mIntentSenderRecords.values().iterator(); 11833 while (it.hasNext()) { 11834 WeakReference<PendingIntentRecord> ref = it.next(); 11835 PendingIntentRecord rec = ref != null ? ref.get(): null; 11836 if (dumpPackage != null && (rec == null 11837 || !dumpPackage.equals(rec.key.packageName))) { 11838 continue; 11839 } 11840 printed = true; 11841 if (rec != null) { 11842 pw.print(" * "); pw.println(rec); 11843 if (dumpAll) { 11844 rec.dump(pw, " "); 11845 } 11846 } else { 11847 pw.print(" * "); pw.println(ref); 11848 } 11849 } 11850 } 11851 11852 if (!printed) { 11853 pw.println(" (nothing)"); 11854 } 11855 } 11856 11857 private static final int dumpProcessList(PrintWriter pw, 11858 ActivityManagerService service, List list, 11859 String prefix, String normalLabel, String persistentLabel, 11860 String dumpPackage) { 11861 int numPers = 0; 11862 final int N = list.size()-1; 11863 for (int i=N; i>=0; i--) { 11864 ProcessRecord r = (ProcessRecord)list.get(i); 11865 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11866 continue; 11867 } 11868 pw.println(String.format("%s%s #%2d: %s", 11869 prefix, (r.persistent ? persistentLabel : normalLabel), 11870 i, r.toString())); 11871 if (r.persistent) { 11872 numPers++; 11873 } 11874 } 11875 return numPers; 11876 } 11877 11878 private static final boolean dumpProcessOomList(PrintWriter pw, 11879 ActivityManagerService service, List<ProcessRecord> origList, 11880 String prefix, String normalLabel, String persistentLabel, 11881 boolean inclDetails, String dumpPackage) { 11882 11883 ArrayList<Pair<ProcessRecord, Integer>> list 11884 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11885 for (int i=0; i<origList.size(); i++) { 11886 ProcessRecord r = origList.get(i); 11887 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11888 continue; 11889 } 11890 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11891 } 11892 11893 if (list.size() <= 0) { 11894 return false; 11895 } 11896 11897 Comparator<Pair<ProcessRecord, Integer>> comparator 11898 = new Comparator<Pair<ProcessRecord, Integer>>() { 11899 @Override 11900 public int compare(Pair<ProcessRecord, Integer> object1, 11901 Pair<ProcessRecord, Integer> object2) { 11902 if (object1.first.setAdj != object2.first.setAdj) { 11903 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11904 } 11905 if (object1.second.intValue() != object2.second.intValue()) { 11906 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11907 } 11908 return 0; 11909 } 11910 }; 11911 11912 Collections.sort(list, comparator); 11913 11914 final long curRealtime = SystemClock.elapsedRealtime(); 11915 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11916 final long curUptime = SystemClock.uptimeMillis(); 11917 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11918 11919 for (int i=list.size()-1; i>=0; i--) { 11920 ProcessRecord r = list.get(i).first; 11921 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11922 char schedGroup; 11923 switch (r.setSchedGroup) { 11924 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11925 schedGroup = 'B'; 11926 break; 11927 case Process.THREAD_GROUP_DEFAULT: 11928 schedGroup = 'F'; 11929 break; 11930 default: 11931 schedGroup = '?'; 11932 break; 11933 } 11934 char foreground; 11935 if (r.foregroundActivities) { 11936 foreground = 'A'; 11937 } else if (r.foregroundServices) { 11938 foreground = 'S'; 11939 } else { 11940 foreground = ' '; 11941 } 11942 String procState = ProcessList.makeProcStateString(r.curProcState); 11943 pw.print(prefix); 11944 pw.print(r.persistent ? persistentLabel : normalLabel); 11945 pw.print(" #"); 11946 int num = (origList.size()-1)-list.get(i).second; 11947 if (num < 10) pw.print(' '); 11948 pw.print(num); 11949 pw.print(": "); 11950 pw.print(oomAdj); 11951 pw.print(' '); 11952 pw.print(schedGroup); 11953 pw.print('/'); 11954 pw.print(foreground); 11955 pw.print('/'); 11956 pw.print(procState); 11957 pw.print(" trm:"); 11958 if (r.trimMemoryLevel < 10) pw.print(' '); 11959 pw.print(r.trimMemoryLevel); 11960 pw.print(' '); 11961 pw.print(r.toShortString()); 11962 pw.print(" ("); 11963 pw.print(r.adjType); 11964 pw.println(')'); 11965 if (r.adjSource != null || r.adjTarget != null) { 11966 pw.print(prefix); 11967 pw.print(" "); 11968 if (r.adjTarget instanceof ComponentName) { 11969 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11970 } else if (r.adjTarget != null) { 11971 pw.print(r.adjTarget.toString()); 11972 } else { 11973 pw.print("{null}"); 11974 } 11975 pw.print("<="); 11976 if (r.adjSource instanceof ProcessRecord) { 11977 pw.print("Proc{"); 11978 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11979 pw.println("}"); 11980 } else if (r.adjSource != null) { 11981 pw.println(r.adjSource.toString()); 11982 } else { 11983 pw.println("{null}"); 11984 } 11985 } 11986 if (inclDetails) { 11987 pw.print(prefix); 11988 pw.print(" "); 11989 pw.print("oom: max="); pw.print(r.maxAdj); 11990 pw.print(" curRaw="); pw.print(r.curRawAdj); 11991 pw.print(" setRaw="); pw.print(r.setRawAdj); 11992 pw.print(" cur="); pw.print(r.curAdj); 11993 pw.print(" set="); pw.println(r.setAdj); 11994 pw.print(prefix); 11995 pw.print(" "); 11996 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11997 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11998 pw.print(" lastPss="); pw.print(r.lastPss); 11999 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12000 pw.print(prefix); 12001 pw.print(" "); 12002 pw.print("keeping="); pw.print(r.keeping); 12003 pw.print(" cached="); pw.print(r.cached); 12004 pw.print(" empty="); pw.print(r.empty); 12005 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12006 12007 if (!r.keeping) { 12008 if (r.lastWakeTime != 0) { 12009 long wtime; 12010 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12011 synchronized (stats) { 12012 wtime = stats.getProcessWakeTime(r.info.uid, 12013 r.pid, curRealtime); 12014 } 12015 long timeUsed = wtime - r.lastWakeTime; 12016 pw.print(prefix); 12017 pw.print(" "); 12018 pw.print("keep awake over "); 12019 TimeUtils.formatDuration(realtimeSince, pw); 12020 pw.print(" used "); 12021 TimeUtils.formatDuration(timeUsed, pw); 12022 pw.print(" ("); 12023 pw.print((timeUsed*100)/realtimeSince); 12024 pw.println("%)"); 12025 } 12026 if (r.lastCpuTime != 0) { 12027 long timeUsed = r.curCpuTime - r.lastCpuTime; 12028 pw.print(prefix); 12029 pw.print(" "); 12030 pw.print("run cpu over "); 12031 TimeUtils.formatDuration(uptimeSince, pw); 12032 pw.print(" used "); 12033 TimeUtils.formatDuration(timeUsed, pw); 12034 pw.print(" ("); 12035 pw.print((timeUsed*100)/uptimeSince); 12036 pw.println("%)"); 12037 } 12038 } 12039 } 12040 } 12041 return true; 12042 } 12043 12044 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12045 ArrayList<ProcessRecord> procs; 12046 synchronized (this) { 12047 if (args != null && args.length > start 12048 && args[start].charAt(0) != '-') { 12049 procs = new ArrayList<ProcessRecord>(); 12050 int pid = -1; 12051 try { 12052 pid = Integer.parseInt(args[start]); 12053 } catch (NumberFormatException e) { 12054 } 12055 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12056 ProcessRecord proc = mLruProcesses.get(i); 12057 if (proc.pid == pid) { 12058 procs.add(proc); 12059 } else if (proc.processName.equals(args[start])) { 12060 procs.add(proc); 12061 } 12062 } 12063 if (procs.size() <= 0) { 12064 return null; 12065 } 12066 } else { 12067 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12068 } 12069 } 12070 return procs; 12071 } 12072 12073 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12074 PrintWriter pw, String[] args) { 12075 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12076 if (procs == null) { 12077 pw.println("No process found for: " + args[0]); 12078 return; 12079 } 12080 12081 long uptime = SystemClock.uptimeMillis(); 12082 long realtime = SystemClock.elapsedRealtime(); 12083 pw.println("Applications Graphics Acceleration Info:"); 12084 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12085 12086 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12087 ProcessRecord r = procs.get(i); 12088 if (r.thread != null) { 12089 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12090 pw.flush(); 12091 try { 12092 TransferPipe tp = new TransferPipe(); 12093 try { 12094 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12095 tp.go(fd); 12096 } finally { 12097 tp.kill(); 12098 } 12099 } catch (IOException e) { 12100 pw.println("Failure while dumping the app: " + r); 12101 pw.flush(); 12102 } catch (RemoteException e) { 12103 pw.println("Got a RemoteException while dumping the app " + r); 12104 pw.flush(); 12105 } 12106 } 12107 } 12108 } 12109 12110 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12111 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12112 if (procs == null) { 12113 pw.println("No process found for: " + args[0]); 12114 return; 12115 } 12116 12117 pw.println("Applications Database Info:"); 12118 12119 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12120 ProcessRecord r = procs.get(i); 12121 if (r.thread != null) { 12122 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12123 pw.flush(); 12124 try { 12125 TransferPipe tp = new TransferPipe(); 12126 try { 12127 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12128 tp.go(fd); 12129 } finally { 12130 tp.kill(); 12131 } 12132 } catch (IOException e) { 12133 pw.println("Failure while dumping the app: " + r); 12134 pw.flush(); 12135 } catch (RemoteException e) { 12136 pw.println("Got a RemoteException while dumping the app " + r); 12137 pw.flush(); 12138 } 12139 } 12140 } 12141 } 12142 12143 final static class MemItem { 12144 final boolean isProc; 12145 final String label; 12146 final String shortLabel; 12147 final long pss; 12148 final int id; 12149 final boolean hasActivities; 12150 ArrayList<MemItem> subitems; 12151 12152 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12153 boolean _hasActivities) { 12154 isProc = true; 12155 label = _label; 12156 shortLabel = _shortLabel; 12157 pss = _pss; 12158 id = _id; 12159 hasActivities = _hasActivities; 12160 } 12161 12162 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12163 isProc = false; 12164 label = _label; 12165 shortLabel = _shortLabel; 12166 pss = _pss; 12167 id = _id; 12168 hasActivities = false; 12169 } 12170 } 12171 12172 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12173 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12174 if (sort && !isCompact) { 12175 Collections.sort(items, new Comparator<MemItem>() { 12176 @Override 12177 public int compare(MemItem lhs, MemItem rhs) { 12178 if (lhs.pss < rhs.pss) { 12179 return 1; 12180 } else if (lhs.pss > rhs.pss) { 12181 return -1; 12182 } 12183 return 0; 12184 } 12185 }); 12186 } 12187 12188 for (int i=0; i<items.size(); i++) { 12189 MemItem mi = items.get(i); 12190 if (!isCompact) { 12191 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12192 } else if (mi.isProc) { 12193 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12194 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12195 pw.println(mi.hasActivities ? ",a" : ",e"); 12196 } else { 12197 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12198 pw.println(mi.pss); 12199 } 12200 if (mi.subitems != null) { 12201 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12202 true, isCompact); 12203 } 12204 } 12205 } 12206 12207 // These are in KB. 12208 static final long[] DUMP_MEM_BUCKETS = new long[] { 12209 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12210 120*1024, 160*1024, 200*1024, 12211 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12212 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12213 }; 12214 12215 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12216 boolean stackLike) { 12217 int start = label.lastIndexOf('.'); 12218 if (start >= 0) start++; 12219 else start = 0; 12220 int end = label.length(); 12221 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12222 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12223 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12224 out.append(bucket); 12225 out.append(stackLike ? "MB." : "MB "); 12226 out.append(label, start, end); 12227 return; 12228 } 12229 } 12230 out.append(memKB/1024); 12231 out.append(stackLike ? "MB." : "MB "); 12232 out.append(label, start, end); 12233 } 12234 12235 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12236 ProcessList.NATIVE_ADJ, 12237 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12238 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12239 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12240 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12241 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12242 }; 12243 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12244 "Native", 12245 "System", "Persistent", "Foreground", 12246 "Visible", "Perceptible", 12247 "Heavy Weight", "Backup", 12248 "A Services", "Home", 12249 "Previous", "B Services", "Cached" 12250 }; 12251 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12252 "native", 12253 "sys", "pers", "fore", 12254 "vis", "percept", 12255 "heavy", "backup", 12256 "servicea", "home", 12257 "prev", "serviceb", "cached" 12258 }; 12259 12260 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12261 long realtime, boolean isCheckinRequest, boolean isCompact) { 12262 if (isCheckinRequest || isCompact) { 12263 // short checkin version 12264 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12265 } else { 12266 pw.println("Applications Memory Usage (kB):"); 12267 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12268 } 12269 } 12270 12271 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12272 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12273 boolean dumpDetails = false; 12274 boolean dumpFullDetails = false; 12275 boolean dumpDalvik = false; 12276 boolean oomOnly = false; 12277 boolean isCompact = false; 12278 boolean localOnly = false; 12279 12280 int opti = 0; 12281 while (opti < args.length) { 12282 String opt = args[opti]; 12283 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12284 break; 12285 } 12286 opti++; 12287 if ("-a".equals(opt)) { 12288 dumpDetails = true; 12289 dumpFullDetails = true; 12290 dumpDalvik = true; 12291 } else if ("-d".equals(opt)) { 12292 dumpDalvik = true; 12293 } else if ("-c".equals(opt)) { 12294 isCompact = true; 12295 } else if ("--oom".equals(opt)) { 12296 oomOnly = true; 12297 } else if ("--local".equals(opt)) { 12298 localOnly = true; 12299 } else if ("-h".equals(opt)) { 12300 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12301 pw.println(" -a: include all available information for each process."); 12302 pw.println(" -d: include dalvik details when dumping process details."); 12303 pw.println(" -c: dump in a compact machine-parseable representation."); 12304 pw.println(" --oom: only show processes organized by oom adj."); 12305 pw.println(" --local: only collect details locally, don't call process."); 12306 pw.println("If [process] is specified it can be the name or "); 12307 pw.println("pid of a specific process to dump."); 12308 return; 12309 } else { 12310 pw.println("Unknown argument: " + opt + "; use -h for help"); 12311 } 12312 } 12313 12314 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12315 long uptime = SystemClock.uptimeMillis(); 12316 long realtime = SystemClock.elapsedRealtime(); 12317 final long[] tmpLong = new long[1]; 12318 12319 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12320 if (procs == null) { 12321 // No Java processes. Maybe they want to print a native process. 12322 if (args != null && args.length > opti 12323 && args[opti].charAt(0) != '-') { 12324 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12325 = new ArrayList<ProcessCpuTracker.Stats>(); 12326 updateCpuStatsNow(); 12327 int findPid = -1; 12328 try { 12329 findPid = Integer.parseInt(args[opti]); 12330 } catch (NumberFormatException e) { 12331 } 12332 synchronized (mProcessCpuThread) { 12333 final int N = mProcessCpuTracker.countStats(); 12334 for (int i=0; i<N; i++) { 12335 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12336 if (st.pid == findPid || (st.baseName != null 12337 && st.baseName.equals(args[opti]))) { 12338 nativeProcs.add(st); 12339 } 12340 } 12341 } 12342 if (nativeProcs.size() > 0) { 12343 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12344 isCompact); 12345 Debug.MemoryInfo mi = null; 12346 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12347 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12348 final int pid = r.pid; 12349 if (!isCheckinRequest && dumpDetails) { 12350 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12351 } 12352 if (mi == null) { 12353 mi = new Debug.MemoryInfo(); 12354 } 12355 if (dumpDetails || (!brief && !oomOnly)) { 12356 Debug.getMemoryInfo(pid, mi); 12357 } else { 12358 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12359 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12360 } 12361 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12362 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12363 if (isCheckinRequest) { 12364 pw.println(); 12365 } 12366 } 12367 return; 12368 } 12369 } 12370 pw.println("No process found for: " + args[opti]); 12371 return; 12372 } 12373 12374 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12375 dumpDetails = true; 12376 } 12377 12378 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12379 12380 String[] innerArgs = new String[args.length-opti]; 12381 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12382 12383 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12384 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12385 long nativePss=0, dalvikPss=0, otherPss=0; 12386 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12387 12388 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12389 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12390 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12391 12392 long totalPss = 0; 12393 long cachedPss = 0; 12394 12395 Debug.MemoryInfo mi = null; 12396 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12397 final ProcessRecord r = procs.get(i); 12398 final IApplicationThread thread; 12399 final int pid; 12400 final int oomAdj; 12401 final boolean hasActivities; 12402 synchronized (this) { 12403 thread = r.thread; 12404 pid = r.pid; 12405 oomAdj = r.getSetAdjWithServices(); 12406 hasActivities = r.activities.size() > 0; 12407 } 12408 if (thread != null) { 12409 if (!isCheckinRequest && dumpDetails) { 12410 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12411 } 12412 if (mi == null) { 12413 mi = new Debug.MemoryInfo(); 12414 } 12415 if (dumpDetails || (!brief && !oomOnly)) { 12416 Debug.getMemoryInfo(pid, mi); 12417 } else { 12418 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12419 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12420 } 12421 if (dumpDetails) { 12422 if (localOnly) { 12423 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12424 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12425 if (isCheckinRequest) { 12426 pw.println(); 12427 } 12428 } else { 12429 try { 12430 pw.flush(); 12431 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12432 dumpDalvik, innerArgs); 12433 } catch (RemoteException e) { 12434 if (!isCheckinRequest) { 12435 pw.println("Got RemoteException!"); 12436 pw.flush(); 12437 } 12438 } 12439 } 12440 } 12441 12442 final long myTotalPss = mi.getTotalPss(); 12443 final long myTotalUss = mi.getTotalUss(); 12444 12445 synchronized (this) { 12446 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12447 // Record this for posterity if the process has been stable. 12448 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12449 } 12450 } 12451 12452 if (!isCheckinRequest && mi != null) { 12453 totalPss += myTotalPss; 12454 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12455 (hasActivities ? " / activities)" : ")"), 12456 r.processName, myTotalPss, pid, hasActivities); 12457 procMems.add(pssItem); 12458 procMemsMap.put(pid, pssItem); 12459 12460 nativePss += mi.nativePss; 12461 dalvikPss += mi.dalvikPss; 12462 otherPss += mi.otherPss; 12463 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12464 long mem = mi.getOtherPss(j); 12465 miscPss[j] += mem; 12466 otherPss -= mem; 12467 } 12468 12469 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12470 cachedPss += myTotalPss; 12471 } 12472 12473 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12474 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12475 || oomIndex == (oomPss.length-1)) { 12476 oomPss[oomIndex] += myTotalPss; 12477 if (oomProcs[oomIndex] == null) { 12478 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12479 } 12480 oomProcs[oomIndex].add(pssItem); 12481 break; 12482 } 12483 } 12484 } 12485 } 12486 } 12487 12488 if (!isCheckinRequest && procs.size() > 1) { 12489 // If we are showing aggregations, also look for native processes to 12490 // include so that our aggregations are more accurate. 12491 updateCpuStatsNow(); 12492 synchronized (mProcessCpuThread) { 12493 final int N = mProcessCpuTracker.countStats(); 12494 for (int i=0; i<N; i++) { 12495 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12496 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12497 if (mi == null) { 12498 mi = new Debug.MemoryInfo(); 12499 } 12500 if (!brief && !oomOnly) { 12501 Debug.getMemoryInfo(st.pid, mi); 12502 } else { 12503 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12504 mi.nativePrivateDirty = (int)tmpLong[0]; 12505 } 12506 12507 final long myTotalPss = mi.getTotalPss(); 12508 totalPss += myTotalPss; 12509 12510 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12511 st.name, myTotalPss, st.pid, false); 12512 procMems.add(pssItem); 12513 12514 nativePss += mi.nativePss; 12515 dalvikPss += mi.dalvikPss; 12516 otherPss += mi.otherPss; 12517 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12518 long mem = mi.getOtherPss(j); 12519 miscPss[j] += mem; 12520 otherPss -= mem; 12521 } 12522 oomPss[0] += myTotalPss; 12523 if (oomProcs[0] == null) { 12524 oomProcs[0] = new ArrayList<MemItem>(); 12525 } 12526 oomProcs[0].add(pssItem); 12527 } 12528 } 12529 } 12530 12531 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12532 12533 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12534 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12535 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12536 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12537 String label = Debug.MemoryInfo.getOtherLabel(j); 12538 catMems.add(new MemItem(label, label, miscPss[j], j)); 12539 } 12540 12541 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12542 for (int j=0; j<oomPss.length; j++) { 12543 if (oomPss[j] != 0) { 12544 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12545 : DUMP_MEM_OOM_LABEL[j]; 12546 MemItem item = new MemItem(label, label, oomPss[j], 12547 DUMP_MEM_OOM_ADJ[j]); 12548 item.subitems = oomProcs[j]; 12549 oomMems.add(item); 12550 } 12551 } 12552 12553 if (!brief && !oomOnly && !isCompact) { 12554 pw.println(); 12555 pw.println("Total PSS by process:"); 12556 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12557 pw.println(); 12558 } 12559 if (!isCompact) { 12560 pw.println("Total PSS by OOM adjustment:"); 12561 } 12562 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12563 if (!brief && !oomOnly) { 12564 PrintWriter out = categoryPw != null ? categoryPw : pw; 12565 if (!isCompact) { 12566 out.println(); 12567 out.println("Total PSS by category:"); 12568 } 12569 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12570 } 12571 if (!isCompact) { 12572 pw.println(); 12573 } 12574 MemInfoReader memInfo = new MemInfoReader(); 12575 memInfo.readMemInfo(); 12576 if (!brief) { 12577 if (!isCompact) { 12578 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12579 pw.print(" kB (status "); 12580 switch (mLastMemoryLevel) { 12581 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12582 pw.println("normal)"); 12583 break; 12584 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12585 pw.println("moderate)"); 12586 break; 12587 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12588 pw.println("low)"); 12589 break; 12590 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12591 pw.println("critical)"); 12592 break; 12593 default: 12594 pw.print(mLastMemoryLevel); 12595 pw.println(")"); 12596 break; 12597 } 12598 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12599 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12600 pw.print(cachedPss); pw.print(" cached pss + "); 12601 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12602 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12603 } else { 12604 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12605 pw.print(cachedPss + memInfo.getCachedSizeKb() 12606 + memInfo.getFreeSizeKb()); pw.print(","); 12607 pw.println(totalPss - cachedPss); 12608 } 12609 } 12610 if (!isCompact) { 12611 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12612 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12613 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12614 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12615 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12616 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12617 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12618 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12619 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12620 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12621 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12622 } 12623 if (!brief) { 12624 if (memInfo.getZramTotalSizeKb() != 0) { 12625 if (!isCompact) { 12626 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12627 pw.print(" kB physical used for "); 12628 pw.print(memInfo.getSwapTotalSizeKb() 12629 - memInfo.getSwapFreeSizeKb()); 12630 pw.print(" kB in swap ("); 12631 pw.print(memInfo.getSwapTotalSizeKb()); 12632 pw.println(" kB total swap)"); 12633 } else { 12634 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12635 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12636 pw.println(memInfo.getSwapFreeSizeKb()); 12637 } 12638 } 12639 final int[] SINGLE_LONG_FORMAT = new int[] { 12640 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12641 }; 12642 long[] longOut = new long[1]; 12643 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12644 SINGLE_LONG_FORMAT, null, longOut, null); 12645 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12646 longOut[0] = 0; 12647 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12648 SINGLE_LONG_FORMAT, null, longOut, null); 12649 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12650 longOut[0] = 0; 12651 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12652 SINGLE_LONG_FORMAT, null, longOut, null); 12653 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12654 longOut[0] = 0; 12655 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12656 SINGLE_LONG_FORMAT, null, longOut, null); 12657 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12658 if (!isCompact) { 12659 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12660 pw.print(" KSM: "); pw.print(sharing); 12661 pw.print(" kB saved from shared "); 12662 pw.print(shared); pw.println(" kB"); 12663 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12664 pw.print(voltile); pw.println(" kB volatile"); 12665 } 12666 pw.print(" Tuning: "); 12667 pw.print(ActivityManager.staticGetMemoryClass()); 12668 pw.print(" (large "); 12669 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12670 pw.print("), oom "); 12671 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12672 pw.print(" kB"); 12673 pw.print(", restore limit "); 12674 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12675 pw.print(" kB"); 12676 if (ActivityManager.isLowRamDeviceStatic()) { 12677 pw.print(" (low-ram)"); 12678 } 12679 if (ActivityManager.isHighEndGfx()) { 12680 pw.print(" (high-end-gfx)"); 12681 } 12682 pw.println(); 12683 } else { 12684 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12685 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12686 pw.println(voltile); 12687 pw.print("tuning,"); 12688 pw.print(ActivityManager.staticGetMemoryClass()); 12689 pw.print(','); 12690 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12691 pw.print(','); 12692 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12693 if (ActivityManager.isLowRamDeviceStatic()) { 12694 pw.print(",low-ram"); 12695 } 12696 if (ActivityManager.isHighEndGfx()) { 12697 pw.print(",high-end-gfx"); 12698 } 12699 pw.println(); 12700 } 12701 } 12702 } 12703 } 12704 12705 /** 12706 * Searches array of arguments for the specified string 12707 * @param args array of argument strings 12708 * @param value value to search for 12709 * @return true if the value is contained in the array 12710 */ 12711 private static boolean scanArgs(String[] args, String value) { 12712 if (args != null) { 12713 for (String arg : args) { 12714 if (value.equals(arg)) { 12715 return true; 12716 } 12717 } 12718 } 12719 return false; 12720 } 12721 12722 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12723 ContentProviderRecord cpr, boolean always) { 12724 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12725 12726 if (!inLaunching || always) { 12727 synchronized (cpr) { 12728 cpr.launchingApp = null; 12729 cpr.notifyAll(); 12730 } 12731 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12732 String names[] = cpr.info.authority.split(";"); 12733 for (int j = 0; j < names.length; j++) { 12734 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12735 } 12736 } 12737 12738 for (int i=0; i<cpr.connections.size(); i++) { 12739 ContentProviderConnection conn = cpr.connections.get(i); 12740 if (conn.waiting) { 12741 // If this connection is waiting for the provider, then we don't 12742 // need to mess with its process unless we are always removing 12743 // or for some reason the provider is not currently launching. 12744 if (inLaunching && !always) { 12745 continue; 12746 } 12747 } 12748 ProcessRecord capp = conn.client; 12749 conn.dead = true; 12750 if (conn.stableCount > 0) { 12751 if (!capp.persistent && capp.thread != null 12752 && capp.pid != 0 12753 && capp.pid != MY_PID) { 12754 killUnneededProcessLocked(capp, "depends on provider " 12755 + cpr.name.flattenToShortString() 12756 + " in dying proc " + (proc != null ? proc.processName : "??")); 12757 } 12758 } else if (capp.thread != null && conn.provider.provider != null) { 12759 try { 12760 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12761 } catch (RemoteException e) { 12762 } 12763 // In the protocol here, we don't expect the client to correctly 12764 // clean up this connection, we'll just remove it. 12765 cpr.connections.remove(i); 12766 conn.client.conProviders.remove(conn); 12767 } 12768 } 12769 12770 if (inLaunching && always) { 12771 mLaunchingProviders.remove(cpr); 12772 } 12773 return inLaunching; 12774 } 12775 12776 /** 12777 * Main code for cleaning up a process when it has gone away. This is 12778 * called both as a result of the process dying, or directly when stopping 12779 * a process when running in single process mode. 12780 */ 12781 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12782 boolean restarting, boolean allowRestart, int index) { 12783 if (index >= 0) { 12784 removeLruProcessLocked(app); 12785 ProcessList.remove(app.pid); 12786 } 12787 12788 mProcessesToGc.remove(app); 12789 mPendingPssProcesses.remove(app); 12790 12791 // Dismiss any open dialogs. 12792 if (app.crashDialog != null && !app.forceCrashReport) { 12793 app.crashDialog.dismiss(); 12794 app.crashDialog = null; 12795 } 12796 if (app.anrDialog != null) { 12797 app.anrDialog.dismiss(); 12798 app.anrDialog = null; 12799 } 12800 if (app.waitDialog != null) { 12801 app.waitDialog.dismiss(); 12802 app.waitDialog = null; 12803 } 12804 12805 app.crashing = false; 12806 app.notResponding = false; 12807 12808 app.resetPackageList(mProcessStats); 12809 app.unlinkDeathRecipient(); 12810 app.makeInactive(mProcessStats); 12811 app.forcingToForeground = null; 12812 updateProcessForegroundLocked(app, false, false); 12813 app.foregroundActivities = false; 12814 app.hasShownUi = false; 12815 app.treatLikeActivity = false; 12816 app.hasAboveClient = false; 12817 app.hasClientActivities = false; 12818 12819 mServices.killServicesLocked(app, allowRestart); 12820 12821 boolean restart = false; 12822 12823 // Remove published content providers. 12824 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12825 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12826 final boolean always = app.bad || !allowRestart; 12827 if (removeDyingProviderLocked(app, cpr, always) || always) { 12828 // We left the provider in the launching list, need to 12829 // restart it. 12830 restart = true; 12831 } 12832 12833 cpr.provider = null; 12834 cpr.proc = null; 12835 } 12836 app.pubProviders.clear(); 12837 12838 // Take care of any launching providers waiting for this process. 12839 if (checkAppInLaunchingProvidersLocked(app, false)) { 12840 restart = true; 12841 } 12842 12843 // Unregister from connected content providers. 12844 if (!app.conProviders.isEmpty()) { 12845 for (int i=0; i<app.conProviders.size(); i++) { 12846 ContentProviderConnection conn = app.conProviders.get(i); 12847 conn.provider.connections.remove(conn); 12848 } 12849 app.conProviders.clear(); 12850 } 12851 12852 // At this point there may be remaining entries in mLaunchingProviders 12853 // where we were the only one waiting, so they are no longer of use. 12854 // Look for these and clean up if found. 12855 // XXX Commented out for now. Trying to figure out a way to reproduce 12856 // the actual situation to identify what is actually going on. 12857 if (false) { 12858 for (int i=0; i<mLaunchingProviders.size(); i++) { 12859 ContentProviderRecord cpr = (ContentProviderRecord) 12860 mLaunchingProviders.get(i); 12861 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12862 synchronized (cpr) { 12863 cpr.launchingApp = null; 12864 cpr.notifyAll(); 12865 } 12866 } 12867 } 12868 } 12869 12870 skipCurrentReceiverLocked(app); 12871 12872 // Unregister any receivers. 12873 for (int i=app.receivers.size()-1; i>=0; i--) { 12874 removeReceiverLocked(app.receivers.valueAt(i)); 12875 } 12876 app.receivers.clear(); 12877 12878 // If the app is undergoing backup, tell the backup manager about it 12879 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12880 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12881 + mBackupTarget.appInfo + " died during backup"); 12882 try { 12883 IBackupManager bm = IBackupManager.Stub.asInterface( 12884 ServiceManager.getService(Context.BACKUP_SERVICE)); 12885 bm.agentDisconnected(app.info.packageName); 12886 } catch (RemoteException e) { 12887 // can't happen; backup manager is local 12888 } 12889 } 12890 12891 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12892 ProcessChangeItem item = mPendingProcessChanges.get(i); 12893 if (item.pid == app.pid) { 12894 mPendingProcessChanges.remove(i); 12895 mAvailProcessChanges.add(item); 12896 } 12897 } 12898 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12899 12900 // If the caller is restarting this app, then leave it in its 12901 // current lists and let the caller take care of it. 12902 if (restarting) { 12903 return; 12904 } 12905 12906 if (!app.persistent || app.isolated) { 12907 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12908 "Removing non-persistent process during cleanup: " + app); 12909 mProcessNames.remove(app.processName, app.uid); 12910 mIsolatedProcesses.remove(app.uid); 12911 if (mHeavyWeightProcess == app) { 12912 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12913 mHeavyWeightProcess.userId, 0)); 12914 mHeavyWeightProcess = null; 12915 } 12916 } else if (!app.removed) { 12917 // This app is persistent, so we need to keep its record around. 12918 // If it is not already on the pending app list, add it there 12919 // and start a new process for it. 12920 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12921 mPersistentStartingProcesses.add(app); 12922 restart = true; 12923 } 12924 } 12925 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12926 "Clean-up removing on hold: " + app); 12927 mProcessesOnHold.remove(app); 12928 12929 if (app == mHomeProcess) { 12930 mHomeProcess = null; 12931 } 12932 if (app == mPreviousProcess) { 12933 mPreviousProcess = null; 12934 } 12935 12936 if (restart && !app.isolated) { 12937 // We have components that still need to be running in the 12938 // process, so re-launch it. 12939 mProcessNames.put(app.processName, app.uid, app); 12940 startProcessLocked(app, "restart", app.processName); 12941 } else if (app.pid > 0 && app.pid != MY_PID) { 12942 // Goodbye! 12943 boolean removed; 12944 synchronized (mPidsSelfLocked) { 12945 mPidsSelfLocked.remove(app.pid); 12946 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12947 } 12948 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12949 app.processName, app.info.uid); 12950 if (app.isolated) { 12951 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12952 } 12953 app.setPid(0); 12954 } 12955 } 12956 12957 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12958 // Look through the content providers we are waiting to have launched, 12959 // and if any run in this process then either schedule a restart of 12960 // the process or kill the client waiting for it if this process has 12961 // gone bad. 12962 int NL = mLaunchingProviders.size(); 12963 boolean restart = false; 12964 for (int i=0; i<NL; i++) { 12965 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12966 if (cpr.launchingApp == app) { 12967 if (!alwaysBad && !app.bad) { 12968 restart = true; 12969 } else { 12970 removeDyingProviderLocked(app, cpr, true); 12971 // cpr should have been removed from mLaunchingProviders 12972 NL = mLaunchingProviders.size(); 12973 i--; 12974 } 12975 } 12976 } 12977 return restart; 12978 } 12979 12980 // ========================================================= 12981 // SERVICES 12982 // ========================================================= 12983 12984 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12985 int flags) { 12986 enforceNotIsolatedCaller("getServices"); 12987 synchronized (this) { 12988 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12989 } 12990 } 12991 12992 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12993 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12994 synchronized (this) { 12995 return mServices.getRunningServiceControlPanelLocked(name); 12996 } 12997 } 12998 12999 public ComponentName startService(IApplicationThread caller, Intent service, 13000 String resolvedType, int userId) { 13001 enforceNotIsolatedCaller("startService"); 13002 // Refuse possible leaked file descriptors 13003 if (service != null && service.hasFileDescriptors() == true) { 13004 throw new IllegalArgumentException("File descriptors passed in Intent"); 13005 } 13006 13007 if (DEBUG_SERVICE) 13008 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13009 synchronized(this) { 13010 final int callingPid = Binder.getCallingPid(); 13011 final int callingUid = Binder.getCallingUid(); 13012 final long origId = Binder.clearCallingIdentity(); 13013 ComponentName res = mServices.startServiceLocked(caller, service, 13014 resolvedType, callingPid, callingUid, userId); 13015 Binder.restoreCallingIdentity(origId); 13016 return res; 13017 } 13018 } 13019 13020 ComponentName startServiceInPackage(int uid, 13021 Intent service, String resolvedType, int userId) { 13022 synchronized(this) { 13023 if (DEBUG_SERVICE) 13024 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13025 final long origId = Binder.clearCallingIdentity(); 13026 ComponentName res = mServices.startServiceLocked(null, service, 13027 resolvedType, -1, uid, userId); 13028 Binder.restoreCallingIdentity(origId); 13029 return res; 13030 } 13031 } 13032 13033 public int stopService(IApplicationThread caller, Intent service, 13034 String resolvedType, int userId) { 13035 enforceNotIsolatedCaller("stopService"); 13036 // Refuse possible leaked file descriptors 13037 if (service != null && service.hasFileDescriptors() == true) { 13038 throw new IllegalArgumentException("File descriptors passed in Intent"); 13039 } 13040 13041 synchronized(this) { 13042 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13043 } 13044 } 13045 13046 public IBinder peekService(Intent service, String resolvedType) { 13047 enforceNotIsolatedCaller("peekService"); 13048 // Refuse possible leaked file descriptors 13049 if (service != null && service.hasFileDescriptors() == true) { 13050 throw new IllegalArgumentException("File descriptors passed in Intent"); 13051 } 13052 synchronized(this) { 13053 return mServices.peekServiceLocked(service, resolvedType); 13054 } 13055 } 13056 13057 public boolean stopServiceToken(ComponentName className, IBinder token, 13058 int startId) { 13059 synchronized(this) { 13060 return mServices.stopServiceTokenLocked(className, token, startId); 13061 } 13062 } 13063 13064 public void setServiceForeground(ComponentName className, IBinder token, 13065 int id, Notification notification, boolean removeNotification) { 13066 synchronized(this) { 13067 mServices.setServiceForegroundLocked(className, token, id, notification, 13068 removeNotification); 13069 } 13070 } 13071 13072 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13073 boolean requireFull, String name, String callerPackage) { 13074 final int callingUserId = UserHandle.getUserId(callingUid); 13075 if (callingUserId != userId) { 13076 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13077 if ((requireFull || checkComponentPermission( 13078 android.Manifest.permission.INTERACT_ACROSS_USERS, 13079 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 13080 && checkComponentPermission( 13081 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 13082 callingPid, callingUid, -1, true) 13083 != PackageManager.PERMISSION_GRANTED) { 13084 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13085 // In this case, they would like to just execute as their 13086 // owner user instead of failing. 13087 userId = callingUserId; 13088 } else { 13089 StringBuilder builder = new StringBuilder(128); 13090 builder.append("Permission Denial: "); 13091 builder.append(name); 13092 if (callerPackage != null) { 13093 builder.append(" from "); 13094 builder.append(callerPackage); 13095 } 13096 builder.append(" asks to run as user "); 13097 builder.append(userId); 13098 builder.append(" but is calling from user "); 13099 builder.append(UserHandle.getUserId(callingUid)); 13100 builder.append("; this requires "); 13101 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 13102 if (!requireFull) { 13103 builder.append(" or "); 13104 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13105 } 13106 String msg = builder.toString(); 13107 Slog.w(TAG, msg); 13108 throw new SecurityException(msg); 13109 } 13110 } 13111 } 13112 if (userId == UserHandle.USER_CURRENT 13113 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13114 // Note that we may be accessing this outside of a lock... 13115 // shouldn't be a big deal, if this is being called outside 13116 // of a locked context there is intrinsically a race with 13117 // the value the caller will receive and someone else changing it. 13118 userId = mCurrentUserId; 13119 } 13120 if (!allowAll && userId < 0) { 13121 throw new IllegalArgumentException( 13122 "Call does not support special user #" + userId); 13123 } 13124 } 13125 return userId; 13126 } 13127 13128 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13129 String className, int flags) { 13130 boolean result = false; 13131 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13132 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 13133 if (ActivityManager.checkUidPermission( 13134 android.Manifest.permission.INTERACT_ACROSS_USERS, 13135 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13136 ComponentName comp = new ComponentName(aInfo.packageName, className); 13137 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13138 + " requests FLAG_SINGLE_USER, but app does not hold " 13139 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13140 Slog.w(TAG, msg); 13141 throw new SecurityException(msg); 13142 } 13143 result = true; 13144 } 13145 } else if (componentProcessName == aInfo.packageName) { 13146 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13147 } else if ("system".equals(componentProcessName)) { 13148 result = true; 13149 } 13150 if (DEBUG_MU) { 13151 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13152 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13153 } 13154 return result; 13155 } 13156 13157 public int bindService(IApplicationThread caller, IBinder token, 13158 Intent service, String resolvedType, 13159 IServiceConnection connection, int flags, int userId) { 13160 enforceNotIsolatedCaller("bindService"); 13161 // Refuse possible leaked file descriptors 13162 if (service != null && service.hasFileDescriptors() == true) { 13163 throw new IllegalArgumentException("File descriptors passed in Intent"); 13164 } 13165 13166 synchronized(this) { 13167 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13168 connection, flags, userId); 13169 } 13170 } 13171 13172 public boolean unbindService(IServiceConnection connection) { 13173 synchronized (this) { 13174 return mServices.unbindServiceLocked(connection); 13175 } 13176 } 13177 13178 public void publishService(IBinder token, Intent intent, IBinder service) { 13179 // Refuse possible leaked file descriptors 13180 if (intent != null && intent.hasFileDescriptors() == true) { 13181 throw new IllegalArgumentException("File descriptors passed in Intent"); 13182 } 13183 13184 synchronized(this) { 13185 if (!(token instanceof ServiceRecord)) { 13186 throw new IllegalArgumentException("Invalid service token"); 13187 } 13188 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13189 } 13190 } 13191 13192 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13193 // Refuse possible leaked file descriptors 13194 if (intent != null && intent.hasFileDescriptors() == true) { 13195 throw new IllegalArgumentException("File descriptors passed in Intent"); 13196 } 13197 13198 synchronized(this) { 13199 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13200 } 13201 } 13202 13203 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13204 synchronized(this) { 13205 if (!(token instanceof ServiceRecord)) { 13206 throw new IllegalArgumentException("Invalid service token"); 13207 } 13208 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13209 } 13210 } 13211 13212 // ========================================================= 13213 // BACKUP AND RESTORE 13214 // ========================================================= 13215 13216 // Cause the target app to be launched if necessary and its backup agent 13217 // instantiated. The backup agent will invoke backupAgentCreated() on the 13218 // activity manager to announce its creation. 13219 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13220 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13221 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13222 13223 synchronized(this) { 13224 // !!! TODO: currently no check here that we're already bound 13225 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13226 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13227 synchronized (stats) { 13228 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13229 } 13230 13231 // Backup agent is now in use, its package can't be stopped. 13232 try { 13233 AppGlobals.getPackageManager().setPackageStoppedState( 13234 app.packageName, false, UserHandle.getUserId(app.uid)); 13235 } catch (RemoteException e) { 13236 } catch (IllegalArgumentException e) { 13237 Slog.w(TAG, "Failed trying to unstop package " 13238 + app.packageName + ": " + e); 13239 } 13240 13241 BackupRecord r = new BackupRecord(ss, app, backupMode); 13242 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13243 ? new ComponentName(app.packageName, app.backupAgentName) 13244 : new ComponentName("android", "FullBackupAgent"); 13245 // startProcessLocked() returns existing proc's record if it's already running 13246 ProcessRecord proc = startProcessLocked(app.processName, app, 13247 false, 0, "backup", hostingName, false, false, false); 13248 if (proc == null) { 13249 Slog.e(TAG, "Unable to start backup agent process " + r); 13250 return false; 13251 } 13252 13253 r.app = proc; 13254 mBackupTarget = r; 13255 mBackupAppName = app.packageName; 13256 13257 // Try not to kill the process during backup 13258 updateOomAdjLocked(proc); 13259 13260 // If the process is already attached, schedule the creation of the backup agent now. 13261 // If it is not yet live, this will be done when it attaches to the framework. 13262 if (proc.thread != null) { 13263 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13264 try { 13265 proc.thread.scheduleCreateBackupAgent(app, 13266 compatibilityInfoForPackageLocked(app), backupMode); 13267 } catch (RemoteException e) { 13268 // Will time out on the backup manager side 13269 } 13270 } else { 13271 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13272 } 13273 // Invariants: at this point, the target app process exists and the application 13274 // is either already running or in the process of coming up. mBackupTarget and 13275 // mBackupAppName describe the app, so that when it binds back to the AM we 13276 // know that it's scheduled for a backup-agent operation. 13277 } 13278 13279 return true; 13280 } 13281 13282 @Override 13283 public void clearPendingBackup() { 13284 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13285 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13286 13287 synchronized (this) { 13288 mBackupTarget = null; 13289 mBackupAppName = null; 13290 } 13291 } 13292 13293 // A backup agent has just come up 13294 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13295 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13296 + " = " + agent); 13297 13298 synchronized(this) { 13299 if (!agentPackageName.equals(mBackupAppName)) { 13300 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13301 return; 13302 } 13303 } 13304 13305 long oldIdent = Binder.clearCallingIdentity(); 13306 try { 13307 IBackupManager bm = IBackupManager.Stub.asInterface( 13308 ServiceManager.getService(Context.BACKUP_SERVICE)); 13309 bm.agentConnected(agentPackageName, agent); 13310 } catch (RemoteException e) { 13311 // can't happen; the backup manager service is local 13312 } catch (Exception e) { 13313 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13314 e.printStackTrace(); 13315 } finally { 13316 Binder.restoreCallingIdentity(oldIdent); 13317 } 13318 } 13319 13320 // done with this agent 13321 public void unbindBackupAgent(ApplicationInfo appInfo) { 13322 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13323 if (appInfo == null) { 13324 Slog.w(TAG, "unbind backup agent for null app"); 13325 return; 13326 } 13327 13328 synchronized(this) { 13329 try { 13330 if (mBackupAppName == null) { 13331 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13332 return; 13333 } 13334 13335 if (!mBackupAppName.equals(appInfo.packageName)) { 13336 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13337 return; 13338 } 13339 13340 // Not backing this app up any more; reset its OOM adjustment 13341 final ProcessRecord proc = mBackupTarget.app; 13342 updateOomAdjLocked(proc); 13343 13344 // If the app crashed during backup, 'thread' will be null here 13345 if (proc.thread != null) { 13346 try { 13347 proc.thread.scheduleDestroyBackupAgent(appInfo, 13348 compatibilityInfoForPackageLocked(appInfo)); 13349 } catch (Exception e) { 13350 Slog.e(TAG, "Exception when unbinding backup agent:"); 13351 e.printStackTrace(); 13352 } 13353 } 13354 } finally { 13355 mBackupTarget = null; 13356 mBackupAppName = null; 13357 } 13358 } 13359 } 13360 // ========================================================= 13361 // BROADCASTS 13362 // ========================================================= 13363 13364 private final List getStickiesLocked(String action, IntentFilter filter, 13365 List cur, int userId) { 13366 final ContentResolver resolver = mContext.getContentResolver(); 13367 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13368 if (stickies == null) { 13369 return cur; 13370 } 13371 final ArrayList<Intent> list = stickies.get(action); 13372 if (list == null) { 13373 return cur; 13374 } 13375 int N = list.size(); 13376 for (int i=0; i<N; i++) { 13377 Intent intent = list.get(i); 13378 if (filter.match(resolver, intent, true, TAG) >= 0) { 13379 if (cur == null) { 13380 cur = new ArrayList<Intent>(); 13381 } 13382 cur.add(intent); 13383 } 13384 } 13385 return cur; 13386 } 13387 13388 boolean isPendingBroadcastProcessLocked(int pid) { 13389 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13390 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13391 } 13392 13393 void skipPendingBroadcastLocked(int pid) { 13394 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13395 for (BroadcastQueue queue : mBroadcastQueues) { 13396 queue.skipPendingBroadcastLocked(pid); 13397 } 13398 } 13399 13400 // The app just attached; send any pending broadcasts that it should receive 13401 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13402 boolean didSomething = false; 13403 for (BroadcastQueue queue : mBroadcastQueues) { 13404 didSomething |= queue.sendPendingBroadcastsLocked(app); 13405 } 13406 return didSomething; 13407 } 13408 13409 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13410 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13411 enforceNotIsolatedCaller("registerReceiver"); 13412 int callingUid; 13413 int callingPid; 13414 synchronized(this) { 13415 ProcessRecord callerApp = null; 13416 if (caller != null) { 13417 callerApp = getRecordForAppLocked(caller); 13418 if (callerApp == null) { 13419 throw new SecurityException( 13420 "Unable to find app for caller " + caller 13421 + " (pid=" + Binder.getCallingPid() 13422 + ") when registering receiver " + receiver); 13423 } 13424 if (callerApp.info.uid != Process.SYSTEM_UID && 13425 !callerApp.pkgList.containsKey(callerPackage) && 13426 !"android".equals(callerPackage)) { 13427 throw new SecurityException("Given caller package " + callerPackage 13428 + " is not running in process " + callerApp); 13429 } 13430 callingUid = callerApp.info.uid; 13431 callingPid = callerApp.pid; 13432 } else { 13433 callerPackage = null; 13434 callingUid = Binder.getCallingUid(); 13435 callingPid = Binder.getCallingPid(); 13436 } 13437 13438 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13439 true, true, "registerReceiver", callerPackage); 13440 13441 List allSticky = null; 13442 13443 // Look for any matching sticky broadcasts... 13444 Iterator actions = filter.actionsIterator(); 13445 if (actions != null) { 13446 while (actions.hasNext()) { 13447 String action = (String)actions.next(); 13448 allSticky = getStickiesLocked(action, filter, allSticky, 13449 UserHandle.USER_ALL); 13450 allSticky = getStickiesLocked(action, filter, allSticky, 13451 UserHandle.getUserId(callingUid)); 13452 } 13453 } else { 13454 allSticky = getStickiesLocked(null, filter, allSticky, 13455 UserHandle.USER_ALL); 13456 allSticky = getStickiesLocked(null, filter, allSticky, 13457 UserHandle.getUserId(callingUid)); 13458 } 13459 13460 // The first sticky in the list is returned directly back to 13461 // the client. 13462 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13463 13464 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13465 + ": " + sticky); 13466 13467 if (receiver == null) { 13468 return sticky; 13469 } 13470 13471 ReceiverList rl 13472 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13473 if (rl == null) { 13474 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13475 userId, receiver); 13476 if (rl.app != null) { 13477 rl.app.receivers.add(rl); 13478 } else { 13479 try { 13480 receiver.asBinder().linkToDeath(rl, 0); 13481 } catch (RemoteException e) { 13482 return sticky; 13483 } 13484 rl.linkedToDeath = true; 13485 } 13486 mRegisteredReceivers.put(receiver.asBinder(), rl); 13487 } else if (rl.uid != callingUid) { 13488 throw new IllegalArgumentException( 13489 "Receiver requested to register for uid " + callingUid 13490 + " was previously registered for uid " + rl.uid); 13491 } else if (rl.pid != callingPid) { 13492 throw new IllegalArgumentException( 13493 "Receiver requested to register for pid " + callingPid 13494 + " was previously registered for pid " + rl.pid); 13495 } else if (rl.userId != userId) { 13496 throw new IllegalArgumentException( 13497 "Receiver requested to register for user " + userId 13498 + " was previously registered for user " + rl.userId); 13499 } 13500 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13501 permission, callingUid, userId); 13502 rl.add(bf); 13503 if (!bf.debugCheck()) { 13504 Slog.w(TAG, "==> For Dynamic broadast"); 13505 } 13506 mReceiverResolver.addFilter(bf); 13507 13508 // Enqueue broadcasts for all existing stickies that match 13509 // this filter. 13510 if (allSticky != null) { 13511 ArrayList receivers = new ArrayList(); 13512 receivers.add(bf); 13513 13514 int N = allSticky.size(); 13515 for (int i=0; i<N; i++) { 13516 Intent intent = (Intent)allSticky.get(i); 13517 BroadcastQueue queue = broadcastQueueForIntent(intent); 13518 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13519 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13520 null, null, false, true, true, -1); 13521 queue.enqueueParallelBroadcastLocked(r); 13522 queue.scheduleBroadcastsLocked(); 13523 } 13524 } 13525 13526 return sticky; 13527 } 13528 } 13529 13530 public void unregisterReceiver(IIntentReceiver receiver) { 13531 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13532 13533 final long origId = Binder.clearCallingIdentity(); 13534 try { 13535 boolean doTrim = false; 13536 13537 synchronized(this) { 13538 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13539 if (rl != null) { 13540 if (rl.curBroadcast != null) { 13541 BroadcastRecord r = rl.curBroadcast; 13542 final boolean doNext = finishReceiverLocked( 13543 receiver.asBinder(), r.resultCode, r.resultData, 13544 r.resultExtras, r.resultAbort); 13545 if (doNext) { 13546 doTrim = true; 13547 r.queue.processNextBroadcast(false); 13548 } 13549 } 13550 13551 if (rl.app != null) { 13552 rl.app.receivers.remove(rl); 13553 } 13554 removeReceiverLocked(rl); 13555 if (rl.linkedToDeath) { 13556 rl.linkedToDeath = false; 13557 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13558 } 13559 } 13560 } 13561 13562 // If we actually concluded any broadcasts, we might now be able 13563 // to trim the recipients' apps from our working set 13564 if (doTrim) { 13565 trimApplications(); 13566 return; 13567 } 13568 13569 } finally { 13570 Binder.restoreCallingIdentity(origId); 13571 } 13572 } 13573 13574 void removeReceiverLocked(ReceiverList rl) { 13575 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13576 int N = rl.size(); 13577 for (int i=0; i<N; i++) { 13578 mReceiverResolver.removeFilter(rl.get(i)); 13579 } 13580 } 13581 13582 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13583 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13584 ProcessRecord r = mLruProcesses.get(i); 13585 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13586 try { 13587 r.thread.dispatchPackageBroadcast(cmd, packages); 13588 } catch (RemoteException ex) { 13589 } 13590 } 13591 } 13592 } 13593 13594 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13595 int[] users) { 13596 List<ResolveInfo> receivers = null; 13597 try { 13598 HashSet<ComponentName> singleUserReceivers = null; 13599 boolean scannedFirstReceivers = false; 13600 for (int user : users) { 13601 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13602 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13603 if (user != 0 && newReceivers != null) { 13604 // If this is not the primary user, we need to check for 13605 // any receivers that should be filtered out. 13606 for (int i=0; i<newReceivers.size(); i++) { 13607 ResolveInfo ri = newReceivers.get(i); 13608 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13609 newReceivers.remove(i); 13610 i--; 13611 } 13612 } 13613 } 13614 if (newReceivers != null && newReceivers.size() == 0) { 13615 newReceivers = null; 13616 } 13617 if (receivers == null) { 13618 receivers = newReceivers; 13619 } else if (newReceivers != null) { 13620 // We need to concatenate the additional receivers 13621 // found with what we have do far. This would be easy, 13622 // but we also need to de-dup any receivers that are 13623 // singleUser. 13624 if (!scannedFirstReceivers) { 13625 // Collect any single user receivers we had already retrieved. 13626 scannedFirstReceivers = true; 13627 for (int i=0; i<receivers.size(); i++) { 13628 ResolveInfo ri = receivers.get(i); 13629 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13630 ComponentName cn = new ComponentName( 13631 ri.activityInfo.packageName, ri.activityInfo.name); 13632 if (singleUserReceivers == null) { 13633 singleUserReceivers = new HashSet<ComponentName>(); 13634 } 13635 singleUserReceivers.add(cn); 13636 } 13637 } 13638 } 13639 // Add the new results to the existing results, tracking 13640 // and de-dupping single user receivers. 13641 for (int i=0; i<newReceivers.size(); i++) { 13642 ResolveInfo ri = newReceivers.get(i); 13643 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13644 ComponentName cn = new ComponentName( 13645 ri.activityInfo.packageName, ri.activityInfo.name); 13646 if (singleUserReceivers == null) { 13647 singleUserReceivers = new HashSet<ComponentName>(); 13648 } 13649 if (!singleUserReceivers.contains(cn)) { 13650 singleUserReceivers.add(cn); 13651 receivers.add(ri); 13652 } 13653 } else { 13654 receivers.add(ri); 13655 } 13656 } 13657 } 13658 } 13659 } catch (RemoteException ex) { 13660 // pm is in same process, this will never happen. 13661 } 13662 return receivers; 13663 } 13664 13665 private final int broadcastIntentLocked(ProcessRecord callerApp, 13666 String callerPackage, Intent intent, String resolvedType, 13667 IIntentReceiver resultTo, int resultCode, String resultData, 13668 Bundle map, String requiredPermission, int appOp, 13669 boolean ordered, boolean sticky, int callingPid, int callingUid, 13670 int userId) { 13671 intent = new Intent(intent); 13672 13673 // By default broadcasts do not go to stopped apps. 13674 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13675 13676 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13677 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13678 + " ordered=" + ordered + " userid=" + userId); 13679 if ((resultTo != null) && !ordered) { 13680 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13681 } 13682 13683 userId = handleIncomingUser(callingPid, callingUid, userId, 13684 true, false, "broadcast", callerPackage); 13685 13686 // Make sure that the user who is receiving this broadcast is started. 13687 // If not, we will just skip it. 13688 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13689 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13690 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13691 Slog.w(TAG, "Skipping broadcast of " + intent 13692 + ": user " + userId + " is stopped"); 13693 return ActivityManager.BROADCAST_SUCCESS; 13694 } 13695 } 13696 13697 /* 13698 * Prevent non-system code (defined here to be non-persistent 13699 * processes) from sending protected broadcasts. 13700 */ 13701 int callingAppId = UserHandle.getAppId(callingUid); 13702 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13703 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13704 callingUid == 0) { 13705 // Always okay. 13706 } else if (callerApp == null || !callerApp.persistent) { 13707 try { 13708 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13709 intent.getAction())) { 13710 String msg = "Permission Denial: not allowed to send broadcast " 13711 + intent.getAction() + " from pid=" 13712 + callingPid + ", uid=" + callingUid; 13713 Slog.w(TAG, msg); 13714 throw new SecurityException(msg); 13715 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13716 // Special case for compatibility: we don't want apps to send this, 13717 // but historically it has not been protected and apps may be using it 13718 // to poke their own app widget. So, instead of making it protected, 13719 // just limit it to the caller. 13720 if (callerApp == null) { 13721 String msg = "Permission Denial: not allowed to send broadcast " 13722 + intent.getAction() + " from unknown caller."; 13723 Slog.w(TAG, msg); 13724 throw new SecurityException(msg); 13725 } else if (intent.getComponent() != null) { 13726 // They are good enough to send to an explicit component... verify 13727 // it is being sent to the calling app. 13728 if (!intent.getComponent().getPackageName().equals( 13729 callerApp.info.packageName)) { 13730 String msg = "Permission Denial: not allowed to send broadcast " 13731 + intent.getAction() + " to " 13732 + intent.getComponent().getPackageName() + " from " 13733 + callerApp.info.packageName; 13734 Slog.w(TAG, msg); 13735 throw new SecurityException(msg); 13736 } 13737 } else { 13738 // Limit broadcast to their own package. 13739 intent.setPackage(callerApp.info.packageName); 13740 } 13741 } 13742 } catch (RemoteException e) { 13743 Slog.w(TAG, "Remote exception", e); 13744 return ActivityManager.BROADCAST_SUCCESS; 13745 } 13746 } 13747 13748 // Handle special intents: if this broadcast is from the package 13749 // manager about a package being removed, we need to remove all of 13750 // its activities from the history stack. 13751 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13752 intent.getAction()); 13753 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13754 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13755 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13756 || uidRemoved) { 13757 if (checkComponentPermission( 13758 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13759 callingPid, callingUid, -1, true) 13760 == PackageManager.PERMISSION_GRANTED) { 13761 if (uidRemoved) { 13762 final Bundle intentExtras = intent.getExtras(); 13763 final int uid = intentExtras != null 13764 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13765 if (uid >= 0) { 13766 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13767 synchronized (bs) { 13768 bs.removeUidStatsLocked(uid); 13769 } 13770 mAppOpsService.uidRemoved(uid); 13771 } 13772 } else { 13773 // If resources are unavailable just force stop all 13774 // those packages and flush the attribute cache as well. 13775 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13776 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13777 if (list != null && (list.length > 0)) { 13778 for (String pkg : list) { 13779 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13780 "storage unmount"); 13781 } 13782 sendPackageBroadcastLocked( 13783 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13784 } 13785 } else { 13786 Uri data = intent.getData(); 13787 String ssp; 13788 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13789 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13790 intent.getAction()); 13791 boolean fullUninstall = removed && 13792 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13793 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13794 forceStopPackageLocked(ssp, UserHandle.getAppId( 13795 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13796 false, fullUninstall, userId, 13797 removed ? "pkg removed" : "pkg changed"); 13798 } 13799 if (removed) { 13800 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13801 new String[] {ssp}, userId); 13802 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13803 mAppOpsService.packageRemoved( 13804 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13805 13806 // Remove all permissions granted from/to this package 13807 removeUriPermissionsForPackageLocked(ssp, userId, true); 13808 } 13809 } 13810 } 13811 } 13812 } 13813 } else { 13814 String msg = "Permission Denial: " + intent.getAction() 13815 + " broadcast from " + callerPackage + " (pid=" + callingPid 13816 + ", uid=" + callingUid + ")" 13817 + " requires " 13818 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13819 Slog.w(TAG, msg); 13820 throw new SecurityException(msg); 13821 } 13822 13823 // Special case for adding a package: by default turn on compatibility 13824 // mode. 13825 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13826 Uri data = intent.getData(); 13827 String ssp; 13828 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13829 mCompatModePackages.handlePackageAddedLocked(ssp, 13830 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13831 } 13832 } 13833 13834 /* 13835 * If this is the time zone changed action, queue up a message that will reset the timezone 13836 * of all currently running processes. This message will get queued up before the broadcast 13837 * happens. 13838 */ 13839 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13840 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13841 } 13842 13843 /* 13844 * If the user set the time, let all running processes know. 13845 */ 13846 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13847 final int is24Hour = intent.getBooleanExtra( 13848 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13849 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13850 } 13851 13852 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13853 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13854 } 13855 13856 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13857 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 13858 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13859 } 13860 13861 // Add to the sticky list if requested. 13862 if (sticky) { 13863 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13864 callingPid, callingUid) 13865 != PackageManager.PERMISSION_GRANTED) { 13866 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13867 + callingPid + ", uid=" + callingUid 13868 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13869 Slog.w(TAG, msg); 13870 throw new SecurityException(msg); 13871 } 13872 if (requiredPermission != null) { 13873 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13874 + " and enforce permission " + requiredPermission); 13875 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13876 } 13877 if (intent.getComponent() != null) { 13878 throw new SecurityException( 13879 "Sticky broadcasts can't target a specific component"); 13880 } 13881 // We use userId directly here, since the "all" target is maintained 13882 // as a separate set of sticky broadcasts. 13883 if (userId != UserHandle.USER_ALL) { 13884 // But first, if this is not a broadcast to all users, then 13885 // make sure it doesn't conflict with an existing broadcast to 13886 // all users. 13887 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13888 UserHandle.USER_ALL); 13889 if (stickies != null) { 13890 ArrayList<Intent> list = stickies.get(intent.getAction()); 13891 if (list != null) { 13892 int N = list.size(); 13893 int i; 13894 for (i=0; i<N; i++) { 13895 if (intent.filterEquals(list.get(i))) { 13896 throw new IllegalArgumentException( 13897 "Sticky broadcast " + intent + " for user " 13898 + userId + " conflicts with existing global broadcast"); 13899 } 13900 } 13901 } 13902 } 13903 } 13904 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13905 if (stickies == null) { 13906 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13907 mStickyBroadcasts.put(userId, stickies); 13908 } 13909 ArrayList<Intent> list = stickies.get(intent.getAction()); 13910 if (list == null) { 13911 list = new ArrayList<Intent>(); 13912 stickies.put(intent.getAction(), list); 13913 } 13914 int N = list.size(); 13915 int i; 13916 for (i=0; i<N; i++) { 13917 if (intent.filterEquals(list.get(i))) { 13918 // This sticky already exists, replace it. 13919 list.set(i, new Intent(intent)); 13920 break; 13921 } 13922 } 13923 if (i >= N) { 13924 list.add(new Intent(intent)); 13925 } 13926 } 13927 13928 int[] users; 13929 if (userId == UserHandle.USER_ALL) { 13930 // Caller wants broadcast to go to all started users. 13931 users = mStartedUserArray; 13932 } else { 13933 // Caller wants broadcast to go to one specific user. 13934 users = new int[] {userId}; 13935 } 13936 13937 // Figure out who all will receive this broadcast. 13938 List receivers = null; 13939 List<BroadcastFilter> registeredReceivers = null; 13940 // Need to resolve the intent to interested receivers... 13941 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13942 == 0) { 13943 receivers = collectReceiverComponents(intent, resolvedType, users); 13944 } 13945 if (intent.getComponent() == null) { 13946 registeredReceivers = mReceiverResolver.queryIntent(intent, 13947 resolvedType, false, userId); 13948 } 13949 13950 final boolean replacePending = 13951 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13952 13953 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13954 + " replacePending=" + replacePending); 13955 13956 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13957 if (!ordered && NR > 0) { 13958 // If we are not serializing this broadcast, then send the 13959 // registered receivers separately so they don't wait for the 13960 // components to be launched. 13961 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13962 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13963 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13964 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13965 ordered, sticky, false, userId); 13966 if (DEBUG_BROADCAST) Slog.v( 13967 TAG, "Enqueueing parallel broadcast " + r); 13968 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13969 if (!replaced) { 13970 queue.enqueueParallelBroadcastLocked(r); 13971 queue.scheduleBroadcastsLocked(); 13972 } 13973 registeredReceivers = null; 13974 NR = 0; 13975 } 13976 13977 // Merge into one list. 13978 int ir = 0; 13979 if (receivers != null) { 13980 // A special case for PACKAGE_ADDED: do not allow the package 13981 // being added to see this broadcast. This prevents them from 13982 // using this as a back door to get run as soon as they are 13983 // installed. Maybe in the future we want to have a special install 13984 // broadcast or such for apps, but we'd like to deliberately make 13985 // this decision. 13986 String skipPackages[] = null; 13987 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13988 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13989 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13990 Uri data = intent.getData(); 13991 if (data != null) { 13992 String pkgName = data.getSchemeSpecificPart(); 13993 if (pkgName != null) { 13994 skipPackages = new String[] { pkgName }; 13995 } 13996 } 13997 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13998 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13999 } 14000 if (skipPackages != null && (skipPackages.length > 0)) { 14001 for (String skipPackage : skipPackages) { 14002 if (skipPackage != null) { 14003 int NT = receivers.size(); 14004 for (int it=0; it<NT; it++) { 14005 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14006 if (curt.activityInfo.packageName.equals(skipPackage)) { 14007 receivers.remove(it); 14008 it--; 14009 NT--; 14010 } 14011 } 14012 } 14013 } 14014 } 14015 14016 int NT = receivers != null ? receivers.size() : 0; 14017 int it = 0; 14018 ResolveInfo curt = null; 14019 BroadcastFilter curr = null; 14020 while (it < NT && ir < NR) { 14021 if (curt == null) { 14022 curt = (ResolveInfo)receivers.get(it); 14023 } 14024 if (curr == null) { 14025 curr = registeredReceivers.get(ir); 14026 } 14027 if (curr.getPriority() >= curt.priority) { 14028 // Insert this broadcast record into the final list. 14029 receivers.add(it, curr); 14030 ir++; 14031 curr = null; 14032 it++; 14033 NT++; 14034 } else { 14035 // Skip to the next ResolveInfo in the final list. 14036 it++; 14037 curt = null; 14038 } 14039 } 14040 } 14041 while (ir < NR) { 14042 if (receivers == null) { 14043 receivers = new ArrayList(); 14044 } 14045 receivers.add(registeredReceivers.get(ir)); 14046 ir++; 14047 } 14048 14049 if ((receivers != null && receivers.size() > 0) 14050 || resultTo != null) { 14051 BroadcastQueue queue = broadcastQueueForIntent(intent); 14052 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14053 callerPackage, callingPid, callingUid, resolvedType, 14054 requiredPermission, appOp, receivers, resultTo, resultCode, 14055 resultData, map, ordered, sticky, false, userId); 14056 if (DEBUG_BROADCAST) Slog.v( 14057 TAG, "Enqueueing ordered broadcast " + r 14058 + ": prev had " + queue.mOrderedBroadcasts.size()); 14059 if (DEBUG_BROADCAST) { 14060 int seq = r.intent.getIntExtra("seq", -1); 14061 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14062 } 14063 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14064 if (!replaced) { 14065 queue.enqueueOrderedBroadcastLocked(r); 14066 queue.scheduleBroadcastsLocked(); 14067 } 14068 } 14069 14070 return ActivityManager.BROADCAST_SUCCESS; 14071 } 14072 14073 final Intent verifyBroadcastLocked(Intent intent) { 14074 // Refuse possible leaked file descriptors 14075 if (intent != null && intent.hasFileDescriptors() == true) { 14076 throw new IllegalArgumentException("File descriptors passed in Intent"); 14077 } 14078 14079 int flags = intent.getFlags(); 14080 14081 if (!mProcessesReady) { 14082 // if the caller really truly claims to know what they're doing, go 14083 // ahead and allow the broadcast without launching any receivers 14084 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14085 intent = new Intent(intent); 14086 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14087 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14088 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14089 + " before boot completion"); 14090 throw new IllegalStateException("Cannot broadcast before boot completed"); 14091 } 14092 } 14093 14094 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14095 throw new IllegalArgumentException( 14096 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14097 } 14098 14099 return intent; 14100 } 14101 14102 public final int broadcastIntent(IApplicationThread caller, 14103 Intent intent, String resolvedType, IIntentReceiver resultTo, 14104 int resultCode, String resultData, Bundle map, 14105 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14106 enforceNotIsolatedCaller("broadcastIntent"); 14107 synchronized(this) { 14108 intent = verifyBroadcastLocked(intent); 14109 14110 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14111 final int callingPid = Binder.getCallingPid(); 14112 final int callingUid = Binder.getCallingUid(); 14113 final long origId = Binder.clearCallingIdentity(); 14114 int res = broadcastIntentLocked(callerApp, 14115 callerApp != null ? callerApp.info.packageName : null, 14116 intent, resolvedType, resultTo, 14117 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14118 callingPid, callingUid, userId); 14119 Binder.restoreCallingIdentity(origId); 14120 return res; 14121 } 14122 } 14123 14124 int broadcastIntentInPackage(String packageName, int uid, 14125 Intent intent, String resolvedType, IIntentReceiver resultTo, 14126 int resultCode, String resultData, Bundle map, 14127 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14128 synchronized(this) { 14129 intent = verifyBroadcastLocked(intent); 14130 14131 final long origId = Binder.clearCallingIdentity(); 14132 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14133 resultTo, resultCode, resultData, map, requiredPermission, 14134 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14135 Binder.restoreCallingIdentity(origId); 14136 return res; 14137 } 14138 } 14139 14140 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14141 // Refuse possible leaked file descriptors 14142 if (intent != null && intent.hasFileDescriptors() == true) { 14143 throw new IllegalArgumentException("File descriptors passed in Intent"); 14144 } 14145 14146 userId = handleIncomingUser(Binder.getCallingPid(), 14147 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14148 14149 synchronized(this) { 14150 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14151 != PackageManager.PERMISSION_GRANTED) { 14152 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14153 + Binder.getCallingPid() 14154 + ", uid=" + Binder.getCallingUid() 14155 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14156 Slog.w(TAG, msg); 14157 throw new SecurityException(msg); 14158 } 14159 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14160 if (stickies != null) { 14161 ArrayList<Intent> list = stickies.get(intent.getAction()); 14162 if (list != null) { 14163 int N = list.size(); 14164 int i; 14165 for (i=0; i<N; i++) { 14166 if (intent.filterEquals(list.get(i))) { 14167 list.remove(i); 14168 break; 14169 } 14170 } 14171 if (list.size() <= 0) { 14172 stickies.remove(intent.getAction()); 14173 } 14174 } 14175 if (stickies.size() <= 0) { 14176 mStickyBroadcasts.remove(userId); 14177 } 14178 } 14179 } 14180 } 14181 14182 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14183 String resultData, Bundle resultExtras, boolean resultAbort) { 14184 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14185 if (r == null) { 14186 Slog.w(TAG, "finishReceiver called but not found on queue"); 14187 return false; 14188 } 14189 14190 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14191 } 14192 14193 void backgroundServicesFinishedLocked(int userId) { 14194 for (BroadcastQueue queue : mBroadcastQueues) { 14195 queue.backgroundServicesFinishedLocked(userId); 14196 } 14197 } 14198 14199 public void finishReceiver(IBinder who, int resultCode, String resultData, 14200 Bundle resultExtras, boolean resultAbort) { 14201 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14202 14203 // Refuse possible leaked file descriptors 14204 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14205 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14206 } 14207 14208 final long origId = Binder.clearCallingIdentity(); 14209 try { 14210 boolean doNext = false; 14211 BroadcastRecord r; 14212 14213 synchronized(this) { 14214 r = broadcastRecordForReceiverLocked(who); 14215 if (r != null) { 14216 doNext = r.queue.finishReceiverLocked(r, resultCode, 14217 resultData, resultExtras, resultAbort, true); 14218 } 14219 } 14220 14221 if (doNext) { 14222 r.queue.processNextBroadcast(false); 14223 } 14224 trimApplications(); 14225 } finally { 14226 Binder.restoreCallingIdentity(origId); 14227 } 14228 } 14229 14230 // ========================================================= 14231 // INSTRUMENTATION 14232 // ========================================================= 14233 14234 public boolean startInstrumentation(ComponentName className, 14235 String profileFile, int flags, Bundle arguments, 14236 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14237 int userId) { 14238 enforceNotIsolatedCaller("startInstrumentation"); 14239 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14240 userId, false, true, "startInstrumentation", null); 14241 // Refuse possible leaked file descriptors 14242 if (arguments != null && arguments.hasFileDescriptors()) { 14243 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14244 } 14245 14246 synchronized(this) { 14247 InstrumentationInfo ii = null; 14248 ApplicationInfo ai = null; 14249 try { 14250 ii = mContext.getPackageManager().getInstrumentationInfo( 14251 className, STOCK_PM_FLAGS); 14252 ai = AppGlobals.getPackageManager().getApplicationInfo( 14253 ii.targetPackage, STOCK_PM_FLAGS, userId); 14254 } catch (PackageManager.NameNotFoundException e) { 14255 } catch (RemoteException e) { 14256 } 14257 if (ii == null) { 14258 reportStartInstrumentationFailure(watcher, className, 14259 "Unable to find instrumentation info for: " + className); 14260 return false; 14261 } 14262 if (ai == null) { 14263 reportStartInstrumentationFailure(watcher, className, 14264 "Unable to find instrumentation target package: " + ii.targetPackage); 14265 return false; 14266 } 14267 14268 int match = mContext.getPackageManager().checkSignatures( 14269 ii.targetPackage, ii.packageName); 14270 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14271 String msg = "Permission Denial: starting instrumentation " 14272 + className + " from pid=" 14273 + Binder.getCallingPid() 14274 + ", uid=" + Binder.getCallingPid() 14275 + " not allowed because package " + ii.packageName 14276 + " does not have a signature matching the target " 14277 + ii.targetPackage; 14278 reportStartInstrumentationFailure(watcher, className, msg); 14279 throw new SecurityException(msg); 14280 } 14281 14282 final long origId = Binder.clearCallingIdentity(); 14283 // Instrumentation can kill and relaunch even persistent processes 14284 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14285 "start instr"); 14286 ProcessRecord app = addAppLocked(ai, false); 14287 app.instrumentationClass = className; 14288 app.instrumentationInfo = ai; 14289 app.instrumentationProfileFile = profileFile; 14290 app.instrumentationArguments = arguments; 14291 app.instrumentationWatcher = watcher; 14292 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14293 app.instrumentationResultClass = className; 14294 Binder.restoreCallingIdentity(origId); 14295 } 14296 14297 return true; 14298 } 14299 14300 /** 14301 * Report errors that occur while attempting to start Instrumentation. Always writes the 14302 * error to the logs, but if somebody is watching, send the report there too. This enables 14303 * the "am" command to report errors with more information. 14304 * 14305 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14306 * @param cn The component name of the instrumentation. 14307 * @param report The error report. 14308 */ 14309 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14310 ComponentName cn, String report) { 14311 Slog.w(TAG, report); 14312 try { 14313 if (watcher != null) { 14314 Bundle results = new Bundle(); 14315 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14316 results.putString("Error", report); 14317 watcher.instrumentationStatus(cn, -1, results); 14318 } 14319 } catch (RemoteException e) { 14320 Slog.w(TAG, e); 14321 } 14322 } 14323 14324 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14325 if (app.instrumentationWatcher != null) { 14326 try { 14327 // NOTE: IInstrumentationWatcher *must* be oneway here 14328 app.instrumentationWatcher.instrumentationFinished( 14329 app.instrumentationClass, 14330 resultCode, 14331 results); 14332 } catch (RemoteException e) { 14333 } 14334 } 14335 if (app.instrumentationUiAutomationConnection != null) { 14336 try { 14337 app.instrumentationUiAutomationConnection.shutdown(); 14338 } catch (RemoteException re) { 14339 /* ignore */ 14340 } 14341 // Only a UiAutomation can set this flag and now that 14342 // it is finished we make sure it is reset to its default. 14343 mUserIsMonkey = false; 14344 } 14345 app.instrumentationWatcher = null; 14346 app.instrumentationUiAutomationConnection = null; 14347 app.instrumentationClass = null; 14348 app.instrumentationInfo = null; 14349 app.instrumentationProfileFile = null; 14350 app.instrumentationArguments = null; 14351 14352 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14353 "finished inst"); 14354 } 14355 14356 public void finishInstrumentation(IApplicationThread target, 14357 int resultCode, Bundle results) { 14358 int userId = UserHandle.getCallingUserId(); 14359 // Refuse possible leaked file descriptors 14360 if (results != null && results.hasFileDescriptors()) { 14361 throw new IllegalArgumentException("File descriptors passed in Intent"); 14362 } 14363 14364 synchronized(this) { 14365 ProcessRecord app = getRecordForAppLocked(target); 14366 if (app == null) { 14367 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14368 return; 14369 } 14370 final long origId = Binder.clearCallingIdentity(); 14371 finishInstrumentationLocked(app, resultCode, results); 14372 Binder.restoreCallingIdentity(origId); 14373 } 14374 } 14375 14376 // ========================================================= 14377 // CONFIGURATION 14378 // ========================================================= 14379 14380 public ConfigurationInfo getDeviceConfigurationInfo() { 14381 ConfigurationInfo config = new ConfigurationInfo(); 14382 synchronized (this) { 14383 config.reqTouchScreen = mConfiguration.touchscreen; 14384 config.reqKeyboardType = mConfiguration.keyboard; 14385 config.reqNavigation = mConfiguration.navigation; 14386 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14387 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14388 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14389 } 14390 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14391 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14392 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14393 } 14394 config.reqGlEsVersion = GL_ES_VERSION; 14395 } 14396 return config; 14397 } 14398 14399 ActivityStack getFocusedStack() { 14400 return mStackSupervisor.getFocusedStack(); 14401 } 14402 14403 public Configuration getConfiguration() { 14404 Configuration ci; 14405 synchronized(this) { 14406 ci = new Configuration(mConfiguration); 14407 } 14408 return ci; 14409 } 14410 14411 public void updatePersistentConfiguration(Configuration values) { 14412 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14413 "updateConfiguration()"); 14414 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14415 "updateConfiguration()"); 14416 if (values == null) { 14417 throw new NullPointerException("Configuration must not be null"); 14418 } 14419 14420 synchronized(this) { 14421 final long origId = Binder.clearCallingIdentity(); 14422 updateConfigurationLocked(values, null, true, false); 14423 Binder.restoreCallingIdentity(origId); 14424 } 14425 } 14426 14427 public void updateConfiguration(Configuration values) { 14428 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14429 "updateConfiguration()"); 14430 14431 synchronized(this) { 14432 if (values == null && mWindowManager != null) { 14433 // sentinel: fetch the current configuration from the window manager 14434 values = mWindowManager.computeNewConfiguration(); 14435 } 14436 14437 if (mWindowManager != null) { 14438 mProcessList.applyDisplaySize(mWindowManager); 14439 } 14440 14441 final long origId = Binder.clearCallingIdentity(); 14442 if (values != null) { 14443 Settings.System.clearConfiguration(values); 14444 } 14445 updateConfigurationLocked(values, null, false, false); 14446 Binder.restoreCallingIdentity(origId); 14447 } 14448 } 14449 14450 /** 14451 * Do either or both things: (1) change the current configuration, and (2) 14452 * make sure the given activity is running with the (now) current 14453 * configuration. Returns true if the activity has been left running, or 14454 * false if <var>starting</var> is being destroyed to match the new 14455 * configuration. 14456 * @param persistent TODO 14457 */ 14458 boolean updateConfigurationLocked(Configuration values, 14459 ActivityRecord starting, boolean persistent, boolean initLocale) { 14460 int changes = 0; 14461 14462 if (values != null) { 14463 Configuration newConfig = new Configuration(mConfiguration); 14464 changes = newConfig.updateFrom(values); 14465 if (changes != 0) { 14466 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14467 Slog.i(TAG, "Updating configuration to: " + values); 14468 } 14469 14470 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14471 14472 if (values.locale != null && !initLocale) { 14473 saveLocaleLocked(values.locale, 14474 !values.locale.equals(mConfiguration.locale), 14475 values.userSetLocale); 14476 } 14477 14478 mConfigurationSeq++; 14479 if (mConfigurationSeq <= 0) { 14480 mConfigurationSeq = 1; 14481 } 14482 newConfig.seq = mConfigurationSeq; 14483 mConfiguration = newConfig; 14484 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14485 mUsageStatsService.noteStartConfig(newConfig); 14486 14487 final Configuration configCopy = new Configuration(mConfiguration); 14488 14489 // TODO: If our config changes, should we auto dismiss any currently 14490 // showing dialogs? 14491 mShowDialogs = shouldShowDialogs(newConfig); 14492 14493 AttributeCache ac = AttributeCache.instance(); 14494 if (ac != null) { 14495 ac.updateConfiguration(configCopy); 14496 } 14497 14498 // Make sure all resources in our process are updated 14499 // right now, so that anyone who is going to retrieve 14500 // resource values after we return will be sure to get 14501 // the new ones. This is especially important during 14502 // boot, where the first config change needs to guarantee 14503 // all resources have that config before following boot 14504 // code is executed. 14505 mSystemThread.applyConfigurationToResources(configCopy); 14506 14507 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14508 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14509 msg.obj = new Configuration(configCopy); 14510 mHandler.sendMessage(msg); 14511 } 14512 14513 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14514 ProcessRecord app = mLruProcesses.get(i); 14515 try { 14516 if (app.thread != null) { 14517 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14518 + app.processName + " new config " + mConfiguration); 14519 app.thread.scheduleConfigurationChanged(configCopy); 14520 } 14521 } catch (Exception e) { 14522 } 14523 } 14524 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14525 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14526 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14527 | Intent.FLAG_RECEIVER_FOREGROUND); 14528 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14529 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14530 Process.SYSTEM_UID, UserHandle.USER_ALL); 14531 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14532 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14533 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14534 broadcastIntentLocked(null, null, intent, 14535 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14536 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14537 } 14538 } 14539 } 14540 14541 boolean kept = true; 14542 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14543 // mainStack is null during startup. 14544 if (mainStack != null) { 14545 if (changes != 0 && starting == null) { 14546 // If the configuration changed, and the caller is not already 14547 // in the process of starting an activity, then find the top 14548 // activity to check if its configuration needs to change. 14549 starting = mainStack.topRunningActivityLocked(null); 14550 } 14551 14552 if (starting != null) { 14553 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14554 // And we need to make sure at this point that all other activities 14555 // are made visible with the correct configuration. 14556 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14557 } 14558 } 14559 14560 if (values != null && mWindowManager != null) { 14561 mWindowManager.setNewConfiguration(mConfiguration); 14562 } 14563 14564 return kept; 14565 } 14566 14567 /** 14568 * Decide based on the configuration whether we should shouw the ANR, 14569 * crash, etc dialogs. The idea is that if there is no affordnace to 14570 * press the on-screen buttons, we shouldn't show the dialog. 14571 * 14572 * A thought: SystemUI might also want to get told about this, the Power 14573 * dialog / global actions also might want different behaviors. 14574 */ 14575 private static final boolean shouldShowDialogs(Configuration config) { 14576 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14577 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14578 } 14579 14580 /** 14581 * Save the locale. You must be inside a synchronized (this) block. 14582 */ 14583 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14584 if(isDiff) { 14585 SystemProperties.set("user.language", l.getLanguage()); 14586 SystemProperties.set("user.region", l.getCountry()); 14587 } 14588 14589 if(isPersist) { 14590 SystemProperties.set("persist.sys.language", l.getLanguage()); 14591 SystemProperties.set("persist.sys.country", l.getCountry()); 14592 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14593 } 14594 } 14595 14596 @Override 14597 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14598 ActivityRecord srec = ActivityRecord.forToken(token); 14599 return srec != null && srec.task.affinity != null && 14600 srec.task.affinity.equals(destAffinity); 14601 } 14602 14603 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14604 Intent resultData) { 14605 14606 synchronized (this) { 14607 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14608 if (stack != null) { 14609 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14610 } 14611 return false; 14612 } 14613 } 14614 14615 public int getLaunchedFromUid(IBinder activityToken) { 14616 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14617 if (srec == null) { 14618 return -1; 14619 } 14620 return srec.launchedFromUid; 14621 } 14622 14623 public String getLaunchedFromPackage(IBinder activityToken) { 14624 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14625 if (srec == null) { 14626 return null; 14627 } 14628 return srec.launchedFromPackage; 14629 } 14630 14631 // ========================================================= 14632 // LIFETIME MANAGEMENT 14633 // ========================================================= 14634 14635 // Returns which broadcast queue the app is the current [or imminent] receiver 14636 // on, or 'null' if the app is not an active broadcast recipient. 14637 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14638 BroadcastRecord r = app.curReceiver; 14639 if (r != null) { 14640 return r.queue; 14641 } 14642 14643 // It's not the current receiver, but it might be starting up to become one 14644 synchronized (this) { 14645 for (BroadcastQueue queue : mBroadcastQueues) { 14646 r = queue.mPendingBroadcast; 14647 if (r != null && r.curApp == app) { 14648 // found it; report which queue it's in 14649 return queue; 14650 } 14651 } 14652 } 14653 14654 return null; 14655 } 14656 14657 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14658 boolean doingAll, long now) { 14659 if (mAdjSeq == app.adjSeq) { 14660 // This adjustment has already been computed. 14661 return app.curRawAdj; 14662 } 14663 14664 if (app.thread == null) { 14665 app.adjSeq = mAdjSeq; 14666 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14667 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14668 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14669 } 14670 14671 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14672 app.adjSource = null; 14673 app.adjTarget = null; 14674 app.empty = false; 14675 app.cached = false; 14676 14677 final int activitiesSize = app.activities.size(); 14678 14679 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14680 // The max adjustment doesn't allow this app to be anything 14681 // below foreground, so it is not worth doing work for it. 14682 app.adjType = "fixed"; 14683 app.adjSeq = mAdjSeq; 14684 app.curRawAdj = app.maxAdj; 14685 app.foregroundActivities = false; 14686 app.keeping = true; 14687 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14688 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14689 // System processes can do UI, and when they do we want to have 14690 // them trim their memory after the user leaves the UI. To 14691 // facilitate this, here we need to determine whether or not it 14692 // is currently showing UI. 14693 app.systemNoUi = true; 14694 if (app == TOP_APP) { 14695 app.systemNoUi = false; 14696 } else if (activitiesSize > 0) { 14697 for (int j = 0; j < activitiesSize; j++) { 14698 final ActivityRecord r = app.activities.get(j); 14699 if (r.visible) { 14700 app.systemNoUi = false; 14701 } 14702 } 14703 } 14704 if (!app.systemNoUi) { 14705 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14706 } 14707 return (app.curAdj=app.maxAdj); 14708 } 14709 14710 app.keeping = false; 14711 app.systemNoUi = false; 14712 14713 // Determine the importance of the process, starting with most 14714 // important to least, and assign an appropriate OOM adjustment. 14715 int adj; 14716 int schedGroup; 14717 int procState; 14718 boolean foregroundActivities = false; 14719 boolean interesting = false; 14720 BroadcastQueue queue; 14721 if (app == TOP_APP) { 14722 // The last app on the list is the foreground app. 14723 adj = ProcessList.FOREGROUND_APP_ADJ; 14724 schedGroup = Process.THREAD_GROUP_DEFAULT; 14725 app.adjType = "top-activity"; 14726 foregroundActivities = true; 14727 interesting = true; 14728 procState = ActivityManager.PROCESS_STATE_TOP; 14729 } else if (app.instrumentationClass != null) { 14730 // Don't want to kill running instrumentation. 14731 adj = ProcessList.FOREGROUND_APP_ADJ; 14732 schedGroup = Process.THREAD_GROUP_DEFAULT; 14733 app.adjType = "instrumentation"; 14734 interesting = true; 14735 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14736 } else if ((queue = isReceivingBroadcast(app)) != null) { 14737 // An app that is currently receiving a broadcast also 14738 // counts as being in the foreground for OOM killer purposes. 14739 // It's placed in a sched group based on the nature of the 14740 // broadcast as reflected by which queue it's active in. 14741 adj = ProcessList.FOREGROUND_APP_ADJ; 14742 schedGroup = (queue == mFgBroadcastQueue) 14743 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14744 app.adjType = "broadcast"; 14745 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14746 } else if (app.executingServices.size() > 0) { 14747 // An app that is currently executing a service callback also 14748 // counts as being in the foreground. 14749 adj = ProcessList.FOREGROUND_APP_ADJ; 14750 schedGroup = app.execServicesFg ? 14751 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14752 app.adjType = "exec-service"; 14753 procState = ActivityManager.PROCESS_STATE_SERVICE; 14754 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14755 } else { 14756 // As far as we know the process is empty. We may change our mind later. 14757 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14758 // At this point we don't actually know the adjustment. Use the cached adj 14759 // value that the caller wants us to. 14760 adj = cachedAdj; 14761 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14762 app.cached = true; 14763 app.empty = true; 14764 app.adjType = "cch-empty"; 14765 } 14766 14767 // Examine all activities if not already foreground. 14768 if (!foregroundActivities && activitiesSize > 0) { 14769 for (int j = 0; j < activitiesSize; j++) { 14770 final ActivityRecord r = app.activities.get(j); 14771 if (r.app != app) { 14772 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14773 + app + "?!?"); 14774 continue; 14775 } 14776 if (r.visible) { 14777 // App has a visible activity; only upgrade adjustment. 14778 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14779 adj = ProcessList.VISIBLE_APP_ADJ; 14780 app.adjType = "visible"; 14781 } 14782 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14783 procState = ActivityManager.PROCESS_STATE_TOP; 14784 } 14785 schedGroup = Process.THREAD_GROUP_DEFAULT; 14786 app.cached = false; 14787 app.empty = false; 14788 foregroundActivities = true; 14789 break; 14790 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14791 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14792 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14793 app.adjType = "pausing"; 14794 } 14795 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14796 procState = ActivityManager.PROCESS_STATE_TOP; 14797 } 14798 schedGroup = Process.THREAD_GROUP_DEFAULT; 14799 app.cached = false; 14800 app.empty = false; 14801 foregroundActivities = true; 14802 } else if (r.state == ActivityState.STOPPING) { 14803 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14804 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14805 app.adjType = "stopping"; 14806 } 14807 // For the process state, we will at this point consider the 14808 // process to be cached. It will be cached either as an activity 14809 // or empty depending on whether the activity is finishing. We do 14810 // this so that we can treat the process as cached for purposes of 14811 // memory trimming (determing current memory level, trim command to 14812 // send to process) since there can be an arbitrary number of stopping 14813 // processes and they should soon all go into the cached state. 14814 if (!r.finishing) { 14815 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14816 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14817 } 14818 } 14819 app.cached = false; 14820 app.empty = false; 14821 foregroundActivities = true; 14822 } else { 14823 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14824 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14825 app.adjType = "cch-act"; 14826 } 14827 } 14828 } 14829 } 14830 14831 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14832 if (app.foregroundServices) { 14833 // The user is aware of this app, so make it visible. 14834 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14835 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14836 app.cached = false; 14837 app.adjType = "fg-service"; 14838 schedGroup = Process.THREAD_GROUP_DEFAULT; 14839 } else if (app.forcingToForeground != null) { 14840 // The user is aware of this app, so make it visible. 14841 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14842 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14843 app.cached = false; 14844 app.adjType = "force-fg"; 14845 app.adjSource = app.forcingToForeground; 14846 schedGroup = Process.THREAD_GROUP_DEFAULT; 14847 } 14848 } 14849 14850 if (app.foregroundServices) { 14851 interesting = true; 14852 } 14853 14854 if (app == mHeavyWeightProcess) { 14855 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14856 // We don't want to kill the current heavy-weight process. 14857 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14858 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14859 app.cached = false; 14860 app.adjType = "heavy"; 14861 } 14862 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14863 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14864 } 14865 } 14866 14867 if (app == mHomeProcess) { 14868 if (adj > ProcessList.HOME_APP_ADJ) { 14869 // This process is hosting what we currently consider to be the 14870 // home app, so we don't want to let it go into the background. 14871 adj = ProcessList.HOME_APP_ADJ; 14872 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14873 app.cached = false; 14874 app.adjType = "home"; 14875 } 14876 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14877 procState = ActivityManager.PROCESS_STATE_HOME; 14878 } 14879 } 14880 14881 if (app == mPreviousProcess && app.activities.size() > 0) { 14882 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14883 // This was the previous process that showed UI to the user. 14884 // We want to try to keep it around more aggressively, to give 14885 // a good experience around switching between two apps. 14886 adj = ProcessList.PREVIOUS_APP_ADJ; 14887 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14888 app.cached = false; 14889 app.adjType = "previous"; 14890 } 14891 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14892 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14893 } 14894 } 14895 14896 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14897 + " reason=" + app.adjType); 14898 14899 // By default, we use the computed adjustment. It may be changed if 14900 // there are applications dependent on our services or providers, but 14901 // this gives us a baseline and makes sure we don't get into an 14902 // infinite recursion. 14903 app.adjSeq = mAdjSeq; 14904 app.curRawAdj = adj; 14905 app.hasStartedServices = false; 14906 14907 if (mBackupTarget != null && app == mBackupTarget.app) { 14908 // If possible we want to avoid killing apps while they're being backed up 14909 if (adj > ProcessList.BACKUP_APP_ADJ) { 14910 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14911 adj = ProcessList.BACKUP_APP_ADJ; 14912 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14913 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14914 } 14915 app.adjType = "backup"; 14916 app.cached = false; 14917 } 14918 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14919 procState = ActivityManager.PROCESS_STATE_BACKUP; 14920 } 14921 } 14922 14923 boolean mayBeTop = false; 14924 14925 for (int is = app.services.size()-1; 14926 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14927 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14928 || procState > ActivityManager.PROCESS_STATE_TOP); 14929 is--) { 14930 ServiceRecord s = app.services.valueAt(is); 14931 if (s.startRequested) { 14932 app.hasStartedServices = true; 14933 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14934 procState = ActivityManager.PROCESS_STATE_SERVICE; 14935 } 14936 if (app.hasShownUi && app != mHomeProcess) { 14937 // If this process has shown some UI, let it immediately 14938 // go to the LRU list because it may be pretty heavy with 14939 // UI stuff. We'll tag it with a label just to help 14940 // debug and understand what is going on. 14941 if (adj > ProcessList.SERVICE_ADJ) { 14942 app.adjType = "cch-started-ui-services"; 14943 } 14944 } else { 14945 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14946 // This service has seen some activity within 14947 // recent memory, so we will keep its process ahead 14948 // of the background processes. 14949 if (adj > ProcessList.SERVICE_ADJ) { 14950 adj = ProcessList.SERVICE_ADJ; 14951 app.adjType = "started-services"; 14952 app.cached = false; 14953 } 14954 } 14955 // If we have let the service slide into the background 14956 // state, still have some text describing what it is doing 14957 // even though the service no longer has an impact. 14958 if (adj > ProcessList.SERVICE_ADJ) { 14959 app.adjType = "cch-started-services"; 14960 } 14961 } 14962 // Don't kill this process because it is doing work; it 14963 // has said it is doing work. 14964 app.keeping = true; 14965 } 14966 for (int conni = s.connections.size()-1; 14967 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14968 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14969 || procState > ActivityManager.PROCESS_STATE_TOP); 14970 conni--) { 14971 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14972 for (int i = 0; 14973 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14974 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14975 || procState > ActivityManager.PROCESS_STATE_TOP); 14976 i++) { 14977 // XXX should compute this based on the max of 14978 // all connected clients. 14979 ConnectionRecord cr = clist.get(i); 14980 if (cr.binding.client == app) { 14981 // Binding to ourself is not interesting. 14982 continue; 14983 } 14984 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14985 ProcessRecord client = cr.binding.client; 14986 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14987 TOP_APP, doingAll, now); 14988 int clientProcState = client.curProcState; 14989 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14990 // If the other app is cached for any reason, for purposes here 14991 // we are going to consider it empty. The specific cached state 14992 // doesn't propagate except under certain conditions. 14993 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14994 } 14995 String adjType = null; 14996 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14997 // Not doing bind OOM management, so treat 14998 // this guy more like a started service. 14999 if (app.hasShownUi && app != mHomeProcess) { 15000 // If this process has shown some UI, let it immediately 15001 // go to the LRU list because it may be pretty heavy with 15002 // UI stuff. We'll tag it with a label just to help 15003 // debug and understand what is going on. 15004 if (adj > clientAdj) { 15005 adjType = "cch-bound-ui-services"; 15006 } 15007 app.cached = false; 15008 clientAdj = adj; 15009 clientProcState = procState; 15010 } else { 15011 if (now >= (s.lastActivity 15012 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15013 // This service has not seen activity within 15014 // recent memory, so allow it to drop to the 15015 // LRU list if there is no other reason to keep 15016 // it around. We'll also tag it with a label just 15017 // to help debug and undertand what is going on. 15018 if (adj > clientAdj) { 15019 adjType = "cch-bound-services"; 15020 } 15021 clientAdj = adj; 15022 } 15023 } 15024 } 15025 if (adj > clientAdj) { 15026 // If this process has recently shown UI, and 15027 // the process that is binding to it is less 15028 // important than being visible, then we don't 15029 // care about the binding as much as we care 15030 // about letting this process get into the LRU 15031 // list to be killed and restarted if needed for 15032 // memory. 15033 if (app.hasShownUi && app != mHomeProcess 15034 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15035 adjType = "cch-bound-ui-services"; 15036 } else { 15037 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15038 |Context.BIND_IMPORTANT)) != 0) { 15039 adj = clientAdj; 15040 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15041 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15042 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15043 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15044 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15045 adj = clientAdj; 15046 } else { 15047 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15048 adj = ProcessList.VISIBLE_APP_ADJ; 15049 } 15050 } 15051 if (!client.cached) { 15052 app.cached = false; 15053 } 15054 if (client.keeping) { 15055 app.keeping = true; 15056 } 15057 adjType = "service"; 15058 } 15059 } 15060 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15061 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15062 schedGroup = Process.THREAD_GROUP_DEFAULT; 15063 } 15064 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15065 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15066 // Special handling of clients who are in the top state. 15067 // We *may* want to consider this process to be in the 15068 // top state as well, but only if there is not another 15069 // reason for it to be running. Being on the top is a 15070 // special state, meaning you are specifically running 15071 // for the current top app. If the process is already 15072 // running in the background for some other reason, it 15073 // is more important to continue considering it to be 15074 // in the background state. 15075 mayBeTop = true; 15076 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15077 } else { 15078 // Special handling for above-top states (persistent 15079 // processes). These should not bring the current process 15080 // into the top state, since they are not on top. Instead 15081 // give them the best state after that. 15082 clientProcState = 15083 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15084 } 15085 } 15086 } else { 15087 if (clientProcState < 15088 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15089 clientProcState = 15090 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15091 } 15092 } 15093 if (procState > clientProcState) { 15094 procState = clientProcState; 15095 } 15096 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15097 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15098 app.pendingUiClean = true; 15099 } 15100 if (adjType != null) { 15101 app.adjType = adjType; 15102 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15103 .REASON_SERVICE_IN_USE; 15104 app.adjSource = cr.binding.client; 15105 app.adjSourceOom = clientAdj; 15106 app.adjTarget = s.name; 15107 } 15108 } 15109 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15110 app.treatLikeActivity = true; 15111 } 15112 final ActivityRecord a = cr.activity; 15113 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15114 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15115 (a.visible || a.state == ActivityState.RESUMED 15116 || a.state == ActivityState.PAUSING)) { 15117 adj = ProcessList.FOREGROUND_APP_ADJ; 15118 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15119 schedGroup = Process.THREAD_GROUP_DEFAULT; 15120 } 15121 app.cached = false; 15122 app.adjType = "service"; 15123 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15124 .REASON_SERVICE_IN_USE; 15125 app.adjSource = a; 15126 app.adjSourceOom = adj; 15127 app.adjTarget = s.name; 15128 } 15129 } 15130 } 15131 } 15132 } 15133 15134 for (int provi = app.pubProviders.size()-1; 15135 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15136 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15137 || procState > ActivityManager.PROCESS_STATE_TOP); 15138 provi--) { 15139 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15140 for (int i = cpr.connections.size()-1; 15141 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15142 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15143 || procState > ActivityManager.PROCESS_STATE_TOP); 15144 i--) { 15145 ContentProviderConnection conn = cpr.connections.get(i); 15146 ProcessRecord client = conn.client; 15147 if (client == app) { 15148 // Being our own client is not interesting. 15149 continue; 15150 } 15151 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15152 int clientProcState = client.curProcState; 15153 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15154 // If the other app is cached for any reason, for purposes here 15155 // we are going to consider it empty. 15156 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15157 } 15158 if (adj > clientAdj) { 15159 if (app.hasShownUi && app != mHomeProcess 15160 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15161 app.adjType = "cch-ui-provider"; 15162 } else { 15163 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15164 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15165 app.adjType = "provider"; 15166 } 15167 app.cached &= client.cached; 15168 app.keeping |= client.keeping; 15169 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15170 .REASON_PROVIDER_IN_USE; 15171 app.adjSource = client; 15172 app.adjSourceOom = clientAdj; 15173 app.adjTarget = cpr.name; 15174 } 15175 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15176 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15177 // Special handling of clients who are in the top state. 15178 // We *may* want to consider this process to be in the 15179 // top state as well, but only if there is not another 15180 // reason for it to be running. Being on the top is a 15181 // special state, meaning you are specifically running 15182 // for the current top app. If the process is already 15183 // running in the background for some other reason, it 15184 // is more important to continue considering it to be 15185 // in the background state. 15186 mayBeTop = true; 15187 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15188 } else { 15189 // Special handling for above-top states (persistent 15190 // processes). These should not bring the current process 15191 // into the top state, since they are not on top. Instead 15192 // give them the best state after that. 15193 clientProcState = 15194 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15195 } 15196 } 15197 if (procState > clientProcState) { 15198 procState = clientProcState; 15199 } 15200 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15201 schedGroup = Process.THREAD_GROUP_DEFAULT; 15202 } 15203 } 15204 // If the provider has external (non-framework) process 15205 // dependencies, ensure that its adjustment is at least 15206 // FOREGROUND_APP_ADJ. 15207 if (cpr.hasExternalProcessHandles()) { 15208 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15209 adj = ProcessList.FOREGROUND_APP_ADJ; 15210 schedGroup = Process.THREAD_GROUP_DEFAULT; 15211 app.cached = false; 15212 app.keeping = true; 15213 app.adjType = "provider"; 15214 app.adjTarget = cpr.name; 15215 } 15216 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15217 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15218 } 15219 } 15220 } 15221 15222 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15223 // A client of one of our services or providers is in the top state. We 15224 // *may* want to be in the top state, but not if we are already running in 15225 // the background for some other reason. For the decision here, we are going 15226 // to pick out a few specific states that we want to remain in when a client 15227 // is top (states that tend to be longer-term) and otherwise allow it to go 15228 // to the top state. 15229 switch (procState) { 15230 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15231 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15232 case ActivityManager.PROCESS_STATE_SERVICE: 15233 // These all are longer-term states, so pull them up to the top 15234 // of the background states, but not all the way to the top state. 15235 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15236 break; 15237 default: 15238 // Otherwise, top is a better choice, so take it. 15239 procState = ActivityManager.PROCESS_STATE_TOP; 15240 break; 15241 } 15242 } 15243 15244 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15245 if (app.hasClientActivities) { 15246 // This is a cached process, but with client activities. Mark it so. 15247 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15248 app.adjType = "cch-client-act"; 15249 } else if (app.treatLikeActivity) { 15250 // This is a cached process, but somebody wants us to treat it like it has 15251 // an activity, okay! 15252 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15253 app.adjType = "cch-as-act"; 15254 } 15255 } 15256 15257 if (adj == ProcessList.SERVICE_ADJ) { 15258 if (doingAll) { 15259 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15260 mNewNumServiceProcs++; 15261 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15262 if (!app.serviceb) { 15263 // This service isn't far enough down on the LRU list to 15264 // normally be a B service, but if we are low on RAM and it 15265 // is large we want to force it down since we would prefer to 15266 // keep launcher over it. 15267 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15268 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15269 app.serviceHighRam = true; 15270 app.serviceb = true; 15271 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15272 } else { 15273 mNewNumAServiceProcs++; 15274 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15275 } 15276 } else { 15277 app.serviceHighRam = false; 15278 } 15279 } 15280 if (app.serviceb) { 15281 adj = ProcessList.SERVICE_B_ADJ; 15282 } 15283 } 15284 15285 app.curRawAdj = adj; 15286 15287 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15288 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15289 if (adj > app.maxAdj) { 15290 adj = app.maxAdj; 15291 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15292 schedGroup = Process.THREAD_GROUP_DEFAULT; 15293 } 15294 } 15295 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15296 app.keeping = true; 15297 } 15298 15299 // Do final modification to adj. Everything we do between here and applying 15300 // the final setAdj must be done in this function, because we will also use 15301 // it when computing the final cached adj later. Note that we don't need to 15302 // worry about this for max adj above, since max adj will always be used to 15303 // keep it out of the cached vaues. 15304 app.curAdj = app.modifyRawOomAdj(adj); 15305 app.curSchedGroup = schedGroup; 15306 app.curProcState = procState; 15307 app.foregroundActivities = foregroundActivities; 15308 15309 return app.curRawAdj; 15310 } 15311 15312 /** 15313 * Schedule PSS collection of a process. 15314 */ 15315 void requestPssLocked(ProcessRecord proc, int procState) { 15316 if (mPendingPssProcesses.contains(proc)) { 15317 return; 15318 } 15319 if (mPendingPssProcesses.size() == 0) { 15320 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15321 } 15322 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15323 proc.pssProcState = procState; 15324 mPendingPssProcesses.add(proc); 15325 } 15326 15327 /** 15328 * Schedule PSS collection of all processes. 15329 */ 15330 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15331 if (!always) { 15332 if (now < (mLastFullPssTime + 15333 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15334 return; 15335 } 15336 } 15337 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15338 mLastFullPssTime = now; 15339 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15340 mPendingPssProcesses.clear(); 15341 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15342 ProcessRecord app = mLruProcesses.get(i); 15343 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15344 app.pssProcState = app.setProcState; 15345 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15346 isSleeping(), now); 15347 mPendingPssProcesses.add(app); 15348 } 15349 } 15350 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15351 } 15352 15353 /** 15354 * Ask a given process to GC right now. 15355 */ 15356 final void performAppGcLocked(ProcessRecord app) { 15357 try { 15358 app.lastRequestedGc = SystemClock.uptimeMillis(); 15359 if (app.thread != null) { 15360 if (app.reportLowMemory) { 15361 app.reportLowMemory = false; 15362 app.thread.scheduleLowMemory(); 15363 } else { 15364 app.thread.processInBackground(); 15365 } 15366 } 15367 } catch (Exception e) { 15368 // whatever. 15369 } 15370 } 15371 15372 /** 15373 * Returns true if things are idle enough to perform GCs. 15374 */ 15375 private final boolean canGcNowLocked() { 15376 boolean processingBroadcasts = false; 15377 for (BroadcastQueue q : mBroadcastQueues) { 15378 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15379 processingBroadcasts = true; 15380 } 15381 } 15382 return !processingBroadcasts 15383 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15384 } 15385 15386 /** 15387 * Perform GCs on all processes that are waiting for it, but only 15388 * if things are idle. 15389 */ 15390 final void performAppGcsLocked() { 15391 final int N = mProcessesToGc.size(); 15392 if (N <= 0) { 15393 return; 15394 } 15395 if (canGcNowLocked()) { 15396 while (mProcessesToGc.size() > 0) { 15397 ProcessRecord proc = mProcessesToGc.remove(0); 15398 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15399 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15400 <= SystemClock.uptimeMillis()) { 15401 // To avoid spamming the system, we will GC processes one 15402 // at a time, waiting a few seconds between each. 15403 performAppGcLocked(proc); 15404 scheduleAppGcsLocked(); 15405 return; 15406 } else { 15407 // It hasn't been long enough since we last GCed this 15408 // process... put it in the list to wait for its time. 15409 addProcessToGcListLocked(proc); 15410 break; 15411 } 15412 } 15413 } 15414 15415 scheduleAppGcsLocked(); 15416 } 15417 } 15418 15419 /** 15420 * If all looks good, perform GCs on all processes waiting for them. 15421 */ 15422 final void performAppGcsIfAppropriateLocked() { 15423 if (canGcNowLocked()) { 15424 performAppGcsLocked(); 15425 return; 15426 } 15427 // Still not idle, wait some more. 15428 scheduleAppGcsLocked(); 15429 } 15430 15431 /** 15432 * Schedule the execution of all pending app GCs. 15433 */ 15434 final void scheduleAppGcsLocked() { 15435 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15436 15437 if (mProcessesToGc.size() > 0) { 15438 // Schedule a GC for the time to the next process. 15439 ProcessRecord proc = mProcessesToGc.get(0); 15440 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15441 15442 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15443 long now = SystemClock.uptimeMillis(); 15444 if (when < (now+GC_TIMEOUT)) { 15445 when = now + GC_TIMEOUT; 15446 } 15447 mHandler.sendMessageAtTime(msg, when); 15448 } 15449 } 15450 15451 /** 15452 * Add a process to the array of processes waiting to be GCed. Keeps the 15453 * list in sorted order by the last GC time. The process can't already be 15454 * on the list. 15455 */ 15456 final void addProcessToGcListLocked(ProcessRecord proc) { 15457 boolean added = false; 15458 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15459 if (mProcessesToGc.get(i).lastRequestedGc < 15460 proc.lastRequestedGc) { 15461 added = true; 15462 mProcessesToGc.add(i+1, proc); 15463 break; 15464 } 15465 } 15466 if (!added) { 15467 mProcessesToGc.add(0, proc); 15468 } 15469 } 15470 15471 /** 15472 * Set up to ask a process to GC itself. This will either do it 15473 * immediately, or put it on the list of processes to gc the next 15474 * time things are idle. 15475 */ 15476 final void scheduleAppGcLocked(ProcessRecord app) { 15477 long now = SystemClock.uptimeMillis(); 15478 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15479 return; 15480 } 15481 if (!mProcessesToGc.contains(app)) { 15482 addProcessToGcListLocked(app); 15483 scheduleAppGcsLocked(); 15484 } 15485 } 15486 15487 final void checkExcessivePowerUsageLocked(boolean doKills) { 15488 updateCpuStatsNow(); 15489 15490 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15491 boolean doWakeKills = doKills; 15492 boolean doCpuKills = doKills; 15493 if (mLastPowerCheckRealtime == 0) { 15494 doWakeKills = false; 15495 } 15496 if (mLastPowerCheckUptime == 0) { 15497 doCpuKills = false; 15498 } 15499 if (stats.isScreenOn()) { 15500 doWakeKills = false; 15501 } 15502 final long curRealtime = SystemClock.elapsedRealtime(); 15503 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15504 final long curUptime = SystemClock.uptimeMillis(); 15505 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15506 mLastPowerCheckRealtime = curRealtime; 15507 mLastPowerCheckUptime = curUptime; 15508 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15509 doWakeKills = false; 15510 } 15511 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15512 doCpuKills = false; 15513 } 15514 int i = mLruProcesses.size(); 15515 while (i > 0) { 15516 i--; 15517 ProcessRecord app = mLruProcesses.get(i); 15518 if (!app.keeping) { 15519 long wtime; 15520 synchronized (stats) { 15521 wtime = stats.getProcessWakeTime(app.info.uid, 15522 app.pid, curRealtime); 15523 } 15524 long wtimeUsed = wtime - app.lastWakeTime; 15525 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15526 if (DEBUG_POWER) { 15527 StringBuilder sb = new StringBuilder(128); 15528 sb.append("Wake for "); 15529 app.toShortString(sb); 15530 sb.append(": over "); 15531 TimeUtils.formatDuration(realtimeSince, sb); 15532 sb.append(" used "); 15533 TimeUtils.formatDuration(wtimeUsed, sb); 15534 sb.append(" ("); 15535 sb.append((wtimeUsed*100)/realtimeSince); 15536 sb.append("%)"); 15537 Slog.i(TAG, sb.toString()); 15538 sb.setLength(0); 15539 sb.append("CPU for "); 15540 app.toShortString(sb); 15541 sb.append(": over "); 15542 TimeUtils.formatDuration(uptimeSince, sb); 15543 sb.append(" used "); 15544 TimeUtils.formatDuration(cputimeUsed, sb); 15545 sb.append(" ("); 15546 sb.append((cputimeUsed*100)/uptimeSince); 15547 sb.append("%)"); 15548 Slog.i(TAG, sb.toString()); 15549 } 15550 // If a process has held a wake lock for more 15551 // than 50% of the time during this period, 15552 // that sounds bad. Kill! 15553 if (doWakeKills && realtimeSince > 0 15554 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15555 synchronized (stats) { 15556 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15557 realtimeSince, wtimeUsed); 15558 } 15559 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15560 + " during " + realtimeSince); 15561 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15562 } else if (doCpuKills && uptimeSince > 0 15563 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15564 synchronized (stats) { 15565 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15566 uptimeSince, cputimeUsed); 15567 } 15568 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15569 + " during " + uptimeSince); 15570 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15571 } else { 15572 app.lastWakeTime = wtime; 15573 app.lastCpuTime = app.curCpuTime; 15574 } 15575 } 15576 } 15577 } 15578 15579 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15580 ProcessRecord TOP_APP, boolean doingAll, long now) { 15581 boolean success = true; 15582 15583 if (app.curRawAdj != app.setRawAdj) { 15584 if (wasKeeping && !app.keeping) { 15585 // This app is no longer something we want to keep. Note 15586 // its current wake lock time to later know to kill it if 15587 // it is not behaving well. 15588 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15589 synchronized (stats) { 15590 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15591 app.pid, SystemClock.elapsedRealtime()); 15592 } 15593 app.lastCpuTime = app.curCpuTime; 15594 } 15595 15596 app.setRawAdj = app.curRawAdj; 15597 } 15598 15599 int changes = 0; 15600 15601 if (app.curAdj != app.setAdj) { 15602 ProcessList.setOomAdj(app.pid, app.curAdj); 15603 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15604 TAG, "Set " + app.pid + " " + app.processName + 15605 " adj " + app.curAdj + ": " + app.adjType); 15606 app.setAdj = app.curAdj; 15607 } 15608 15609 if (app.setSchedGroup != app.curSchedGroup) { 15610 app.setSchedGroup = app.curSchedGroup; 15611 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15612 "Setting process group of " + app.processName 15613 + " to " + app.curSchedGroup); 15614 if (app.waitingToKill != null && 15615 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15616 killUnneededProcessLocked(app, app.waitingToKill); 15617 success = false; 15618 } else { 15619 if (true) { 15620 long oldId = Binder.clearCallingIdentity(); 15621 try { 15622 Process.setProcessGroup(app.pid, app.curSchedGroup); 15623 } catch (Exception e) { 15624 Slog.w(TAG, "Failed setting process group of " + app.pid 15625 + " to " + app.curSchedGroup); 15626 e.printStackTrace(); 15627 } finally { 15628 Binder.restoreCallingIdentity(oldId); 15629 } 15630 } else { 15631 if (app.thread != null) { 15632 try { 15633 app.thread.setSchedulingGroup(app.curSchedGroup); 15634 } catch (RemoteException e) { 15635 } 15636 } 15637 } 15638 Process.setSwappiness(app.pid, 15639 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15640 } 15641 } 15642 if (app.repForegroundActivities != app.foregroundActivities) { 15643 app.repForegroundActivities = app.foregroundActivities; 15644 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15645 } 15646 if (app.repProcState != app.curProcState) { 15647 app.repProcState = app.curProcState; 15648 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15649 if (app.thread != null) { 15650 try { 15651 if (false) { 15652 //RuntimeException h = new RuntimeException("here"); 15653 Slog.i(TAG, "Sending new process state " + app.repProcState 15654 + " to " + app /*, h*/); 15655 } 15656 app.thread.setProcessState(app.repProcState); 15657 } catch (RemoteException e) { 15658 } 15659 } 15660 } 15661 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15662 app.setProcState)) { 15663 app.lastStateTime = now; 15664 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15665 isSleeping(), now); 15666 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15667 + ProcessList.makeProcStateString(app.setProcState) + " to " 15668 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15669 + (app.nextPssTime-now) + ": " + app); 15670 } else { 15671 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15672 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15673 requestPssLocked(app, app.setProcState); 15674 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15675 isSleeping(), now); 15676 } else if (false && DEBUG_PSS) { 15677 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15678 } 15679 } 15680 if (app.setProcState != app.curProcState) { 15681 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15682 "Proc state change of " + app.processName 15683 + " to " + app.curProcState); 15684 app.setProcState = app.curProcState; 15685 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15686 app.notCachedSinceIdle = false; 15687 } 15688 if (!doingAll) { 15689 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15690 } else { 15691 app.procStateChanged = true; 15692 } 15693 } 15694 15695 if (changes != 0) { 15696 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15697 int i = mPendingProcessChanges.size()-1; 15698 ProcessChangeItem item = null; 15699 while (i >= 0) { 15700 item = mPendingProcessChanges.get(i); 15701 if (item.pid == app.pid) { 15702 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15703 break; 15704 } 15705 i--; 15706 } 15707 if (i < 0) { 15708 // No existing item in pending changes; need a new one. 15709 final int NA = mAvailProcessChanges.size(); 15710 if (NA > 0) { 15711 item = mAvailProcessChanges.remove(NA-1); 15712 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15713 } else { 15714 item = new ProcessChangeItem(); 15715 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15716 } 15717 item.changes = 0; 15718 item.pid = app.pid; 15719 item.uid = app.info.uid; 15720 if (mPendingProcessChanges.size() == 0) { 15721 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15722 "*** Enqueueing dispatch processes changed!"); 15723 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15724 } 15725 mPendingProcessChanges.add(item); 15726 } 15727 item.changes |= changes; 15728 item.processState = app.repProcState; 15729 item.foregroundActivities = app.repForegroundActivities; 15730 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15731 + Integer.toHexString(System.identityHashCode(item)) 15732 + " " + app.toShortString() + ": changes=" + item.changes 15733 + " procState=" + item.processState 15734 + " foreground=" + item.foregroundActivities 15735 + " type=" + app.adjType + " source=" + app.adjSource 15736 + " target=" + app.adjTarget); 15737 } 15738 15739 return success; 15740 } 15741 15742 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15743 if (proc.thread != null && proc.baseProcessTracker != null) { 15744 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15745 } 15746 } 15747 15748 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15749 ProcessRecord TOP_APP, boolean doingAll, long now) { 15750 if (app.thread == null) { 15751 return false; 15752 } 15753 15754 final boolean wasKeeping = app.keeping; 15755 15756 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15757 15758 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 15759 } 15760 15761 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15762 boolean oomAdj) { 15763 if (isForeground != proc.foregroundServices) { 15764 proc.foregroundServices = isForeground; 15765 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15766 proc.info.uid); 15767 if (isForeground) { 15768 if (curProcs == null) { 15769 curProcs = new ArrayList<ProcessRecord>(); 15770 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15771 } 15772 if (!curProcs.contains(proc)) { 15773 curProcs.add(proc); 15774 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15775 proc.info.packageName, proc.info.uid); 15776 } 15777 } else { 15778 if (curProcs != null) { 15779 if (curProcs.remove(proc)) { 15780 mBatteryStatsService.noteEvent( 15781 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15782 proc.info.packageName, proc.info.uid); 15783 if (curProcs.size() <= 0) { 15784 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15785 } 15786 } 15787 } 15788 } 15789 if (oomAdj) { 15790 updateOomAdjLocked(); 15791 } 15792 } 15793 } 15794 15795 private final ActivityRecord resumedAppLocked() { 15796 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15797 String pkg; 15798 int uid; 15799 if (act != null && !act.sleeping) { 15800 pkg = act.packageName; 15801 uid = act.info.applicationInfo.uid; 15802 } else { 15803 pkg = null; 15804 uid = -1; 15805 } 15806 // Has the UID or resumed package name changed? 15807 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15808 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15809 if (mCurResumedPackage != null) { 15810 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15811 mCurResumedPackage, mCurResumedUid); 15812 } 15813 mCurResumedPackage = pkg; 15814 mCurResumedUid = uid; 15815 if (mCurResumedPackage != null) { 15816 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15817 mCurResumedPackage, mCurResumedUid); 15818 } 15819 } 15820 return act; 15821 } 15822 15823 final boolean updateOomAdjLocked(ProcessRecord app) { 15824 final ActivityRecord TOP_ACT = resumedAppLocked(); 15825 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15826 final boolean wasCached = app.cached; 15827 15828 mAdjSeq++; 15829 15830 // This is the desired cached adjusment we want to tell it to use. 15831 // If our app is currently cached, we know it, and that is it. Otherwise, 15832 // we don't know it yet, and it needs to now be cached we will then 15833 // need to do a complete oom adj. 15834 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15835 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15836 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 15837 SystemClock.uptimeMillis()); 15838 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15839 // Changed to/from cached state, so apps after it in the LRU 15840 // list may also be changed. 15841 updateOomAdjLocked(); 15842 } 15843 return success; 15844 } 15845 15846 final void updateOomAdjLocked() { 15847 final ActivityRecord TOP_ACT = resumedAppLocked(); 15848 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15849 final long now = SystemClock.uptimeMillis(); 15850 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15851 final int N = mLruProcesses.size(); 15852 15853 if (false) { 15854 RuntimeException e = new RuntimeException(); 15855 e.fillInStackTrace(); 15856 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15857 } 15858 15859 mAdjSeq++; 15860 mNewNumServiceProcs = 0; 15861 mNewNumAServiceProcs = 0; 15862 15863 final int emptyProcessLimit; 15864 final int cachedProcessLimit; 15865 if (mProcessLimit <= 0) { 15866 emptyProcessLimit = cachedProcessLimit = 0; 15867 } else if (mProcessLimit == 1) { 15868 emptyProcessLimit = 1; 15869 cachedProcessLimit = 0; 15870 } else { 15871 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15872 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15873 } 15874 15875 // Let's determine how many processes we have running vs. 15876 // how many slots we have for background processes; we may want 15877 // to put multiple processes in a slot of there are enough of 15878 // them. 15879 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15880 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15881 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15882 if (numEmptyProcs > cachedProcessLimit) { 15883 // If there are more empty processes than our limit on cached 15884 // processes, then use the cached process limit for the factor. 15885 // This ensures that the really old empty processes get pushed 15886 // down to the bottom, so if we are running low on memory we will 15887 // have a better chance at keeping around more cached processes 15888 // instead of a gazillion empty processes. 15889 numEmptyProcs = cachedProcessLimit; 15890 } 15891 int emptyFactor = numEmptyProcs/numSlots; 15892 if (emptyFactor < 1) emptyFactor = 1; 15893 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15894 if (cachedFactor < 1) cachedFactor = 1; 15895 int stepCached = 0; 15896 int stepEmpty = 0; 15897 int numCached = 0; 15898 int numEmpty = 0; 15899 int numTrimming = 0; 15900 15901 mNumNonCachedProcs = 0; 15902 mNumCachedHiddenProcs = 0; 15903 15904 // First update the OOM adjustment for each of the 15905 // application processes based on their current state. 15906 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15907 int nextCachedAdj = curCachedAdj+1; 15908 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15909 int nextEmptyAdj = curEmptyAdj+2; 15910 for (int i=N-1; i>=0; i--) { 15911 ProcessRecord app = mLruProcesses.get(i); 15912 if (!app.killedByAm && app.thread != null) { 15913 app.procStateChanged = false; 15914 final boolean wasKeeping = app.keeping; 15915 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15916 15917 // If we haven't yet assigned the final cached adj 15918 // to the process, do that now. 15919 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15920 switch (app.curProcState) { 15921 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15922 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15923 // This process is a cached process holding activities... 15924 // assign it the next cached value for that type, and then 15925 // step that cached level. 15926 app.curRawAdj = curCachedAdj; 15927 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15928 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15929 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15930 + ")"); 15931 if (curCachedAdj != nextCachedAdj) { 15932 stepCached++; 15933 if (stepCached >= cachedFactor) { 15934 stepCached = 0; 15935 curCachedAdj = nextCachedAdj; 15936 nextCachedAdj += 2; 15937 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15938 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15939 } 15940 } 15941 } 15942 break; 15943 default: 15944 // For everything else, assign next empty cached process 15945 // level and bump that up. Note that this means that 15946 // long-running services that have dropped down to the 15947 // cached level will be treated as empty (since their process 15948 // state is still as a service), which is what we want. 15949 app.curRawAdj = curEmptyAdj; 15950 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15951 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15952 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15953 + ")"); 15954 if (curEmptyAdj != nextEmptyAdj) { 15955 stepEmpty++; 15956 if (stepEmpty >= emptyFactor) { 15957 stepEmpty = 0; 15958 curEmptyAdj = nextEmptyAdj; 15959 nextEmptyAdj += 2; 15960 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15961 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15962 } 15963 } 15964 } 15965 break; 15966 } 15967 } 15968 15969 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 15970 15971 // Count the number of process types. 15972 switch (app.curProcState) { 15973 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15974 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15975 mNumCachedHiddenProcs++; 15976 numCached++; 15977 if (numCached > cachedProcessLimit) { 15978 killUnneededProcessLocked(app, "cached #" + numCached); 15979 } 15980 break; 15981 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15982 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15983 && app.lastActivityTime < oldTime) { 15984 killUnneededProcessLocked(app, "empty for " 15985 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15986 / 1000) + "s"); 15987 } else { 15988 numEmpty++; 15989 if (numEmpty > emptyProcessLimit) { 15990 killUnneededProcessLocked(app, "empty #" + numEmpty); 15991 } 15992 } 15993 break; 15994 default: 15995 mNumNonCachedProcs++; 15996 break; 15997 } 15998 15999 if (app.isolated && app.services.size() <= 0) { 16000 // If this is an isolated process, and there are no 16001 // services running in it, then the process is no longer 16002 // needed. We agressively kill these because we can by 16003 // definition not re-use the same process again, and it is 16004 // good to avoid having whatever code was running in them 16005 // left sitting around after no longer needed. 16006 killUnneededProcessLocked(app, "isolated not needed"); 16007 } 16008 16009 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16010 && !app.killedByAm) { 16011 numTrimming++; 16012 } 16013 } 16014 } 16015 16016 mNumServiceProcs = mNewNumServiceProcs; 16017 16018 // Now determine the memory trimming level of background processes. 16019 // Unfortunately we need to start at the back of the list to do this 16020 // properly. We only do this if the number of background apps we 16021 // are managing to keep around is less than half the maximum we desire; 16022 // if we are keeping a good number around, we'll let them use whatever 16023 // memory they want. 16024 final int numCachedAndEmpty = numCached + numEmpty; 16025 int memFactor; 16026 if (numCached <= ProcessList.TRIM_CACHED_APPS 16027 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16028 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16029 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16030 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16031 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16032 } else { 16033 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16034 } 16035 } else { 16036 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16037 } 16038 // We always allow the memory level to go up (better). We only allow it to go 16039 // down if we are in a state where that is allowed, *and* the total number of processes 16040 // has gone down since last time. 16041 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16042 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16043 + " last=" + mLastNumProcesses); 16044 if (memFactor > mLastMemoryLevel) { 16045 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16046 memFactor = mLastMemoryLevel; 16047 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16048 } 16049 } 16050 mLastMemoryLevel = memFactor; 16051 mLastNumProcesses = mLruProcesses.size(); 16052 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16053 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16054 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16055 if (mLowRamStartTime == 0) { 16056 mLowRamStartTime = now; 16057 } 16058 int step = 0; 16059 int fgTrimLevel; 16060 switch (memFactor) { 16061 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16062 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16063 break; 16064 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16065 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16066 break; 16067 default: 16068 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16069 break; 16070 } 16071 int factor = numTrimming/3; 16072 int minFactor = 2; 16073 if (mHomeProcess != null) minFactor++; 16074 if (mPreviousProcess != null) minFactor++; 16075 if (factor < minFactor) factor = minFactor; 16076 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16077 for (int i=N-1; i>=0; i--) { 16078 ProcessRecord app = mLruProcesses.get(i); 16079 if (allChanged || app.procStateChanged) { 16080 setProcessTrackerState(app, trackerMemFactor, now); 16081 app.procStateChanged = false; 16082 } 16083 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16084 && !app.killedByAm) { 16085 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16086 try { 16087 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16088 "Trimming memory of " + app.processName 16089 + " to " + curLevel); 16090 app.thread.scheduleTrimMemory(curLevel); 16091 } catch (RemoteException e) { 16092 } 16093 if (false) { 16094 // For now we won't do this; our memory trimming seems 16095 // to be good enough at this point that destroying 16096 // activities causes more harm than good. 16097 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16098 && app != mHomeProcess && app != mPreviousProcess) { 16099 // Need to do this on its own message because the stack may not 16100 // be in a consistent state at this point. 16101 // For these apps we will also finish their activities 16102 // to help them free memory. 16103 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16104 } 16105 } 16106 } 16107 app.trimMemoryLevel = curLevel; 16108 step++; 16109 if (step >= factor) { 16110 step = 0; 16111 switch (curLevel) { 16112 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16113 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16114 break; 16115 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16116 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16117 break; 16118 } 16119 } 16120 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16121 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16122 && app.thread != null) { 16123 try { 16124 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16125 "Trimming memory of heavy-weight " + app.processName 16126 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16127 app.thread.scheduleTrimMemory( 16128 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16129 } catch (RemoteException e) { 16130 } 16131 } 16132 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16133 } else { 16134 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16135 || app.systemNoUi) && app.pendingUiClean) { 16136 // If this application is now in the background and it 16137 // had done UI, then give it the special trim level to 16138 // have it free UI resources. 16139 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16140 if (app.trimMemoryLevel < level && app.thread != null) { 16141 try { 16142 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16143 "Trimming memory of bg-ui " + app.processName 16144 + " to " + level); 16145 app.thread.scheduleTrimMemory(level); 16146 } catch (RemoteException e) { 16147 } 16148 } 16149 app.pendingUiClean = false; 16150 } 16151 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16152 try { 16153 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16154 "Trimming memory of fg " + app.processName 16155 + " to " + fgTrimLevel); 16156 app.thread.scheduleTrimMemory(fgTrimLevel); 16157 } catch (RemoteException e) { 16158 } 16159 } 16160 app.trimMemoryLevel = fgTrimLevel; 16161 } 16162 } 16163 } else { 16164 if (mLowRamStartTime != 0) { 16165 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16166 mLowRamStartTime = 0; 16167 } 16168 for (int i=N-1; i>=0; i--) { 16169 ProcessRecord app = mLruProcesses.get(i); 16170 if (allChanged || app.procStateChanged) { 16171 setProcessTrackerState(app, trackerMemFactor, now); 16172 app.procStateChanged = false; 16173 } 16174 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16175 || app.systemNoUi) && app.pendingUiClean) { 16176 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16177 && app.thread != null) { 16178 try { 16179 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16180 "Trimming memory of ui hidden " + app.processName 16181 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16182 app.thread.scheduleTrimMemory( 16183 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16184 } catch (RemoteException e) { 16185 } 16186 } 16187 app.pendingUiClean = false; 16188 } 16189 app.trimMemoryLevel = 0; 16190 } 16191 } 16192 16193 if (mAlwaysFinishActivities) { 16194 // Need to do this on its own message because the stack may not 16195 // be in a consistent state at this point. 16196 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16197 } 16198 16199 if (allChanged) { 16200 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16201 } 16202 16203 if (mProcessStats.shouldWriteNowLocked(now)) { 16204 mHandler.post(new Runnable() { 16205 @Override public void run() { 16206 synchronized (ActivityManagerService.this) { 16207 mProcessStats.writeStateAsyncLocked(); 16208 } 16209 } 16210 }); 16211 } 16212 16213 if (DEBUG_OOM_ADJ) { 16214 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16215 } 16216 } 16217 16218 final void trimApplications() { 16219 synchronized (this) { 16220 int i; 16221 16222 // First remove any unused application processes whose package 16223 // has been removed. 16224 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16225 final ProcessRecord app = mRemovedProcesses.get(i); 16226 if (app.activities.size() == 0 16227 && app.curReceiver == null && app.services.size() == 0) { 16228 Slog.i( 16229 TAG, "Exiting empty application process " 16230 + app.processName + " (" 16231 + (app.thread != null ? app.thread.asBinder() : null) 16232 + ")\n"); 16233 if (app.pid > 0 && app.pid != MY_PID) { 16234 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16235 app.processName, app.setAdj, "empty"); 16236 app.killedByAm = true; 16237 Process.killProcessQuiet(app.pid); 16238 } else { 16239 try { 16240 app.thread.scheduleExit(); 16241 } catch (Exception e) { 16242 // Ignore exceptions. 16243 } 16244 } 16245 cleanUpApplicationRecordLocked(app, false, true, -1); 16246 mRemovedProcesses.remove(i); 16247 16248 if (app.persistent) { 16249 if (app.persistent) { 16250 addAppLocked(app.info, false); 16251 } 16252 } 16253 } 16254 } 16255 16256 // Now update the oom adj for all processes. 16257 updateOomAdjLocked(); 16258 } 16259 } 16260 16261 /** This method sends the specified signal to each of the persistent apps */ 16262 public void signalPersistentProcesses(int sig) throws RemoteException { 16263 if (sig != Process.SIGNAL_USR1) { 16264 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16265 } 16266 16267 synchronized (this) { 16268 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16269 != PackageManager.PERMISSION_GRANTED) { 16270 throw new SecurityException("Requires permission " 16271 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16272 } 16273 16274 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16275 ProcessRecord r = mLruProcesses.get(i); 16276 if (r.thread != null && r.persistent) { 16277 Process.sendSignal(r.pid, sig); 16278 } 16279 } 16280 } 16281 } 16282 16283 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16284 if (proc == null || proc == mProfileProc) { 16285 proc = mProfileProc; 16286 path = mProfileFile; 16287 profileType = mProfileType; 16288 clearProfilerLocked(); 16289 } 16290 if (proc == null) { 16291 return; 16292 } 16293 try { 16294 proc.thread.profilerControl(false, path, null, profileType); 16295 } catch (RemoteException e) { 16296 throw new IllegalStateException("Process disappeared"); 16297 } 16298 } 16299 16300 private void clearProfilerLocked() { 16301 if (mProfileFd != null) { 16302 try { 16303 mProfileFd.close(); 16304 } catch (IOException e) { 16305 } 16306 } 16307 mProfileApp = null; 16308 mProfileProc = null; 16309 mProfileFile = null; 16310 mProfileType = 0; 16311 mAutoStopProfiler = false; 16312 } 16313 16314 public boolean profileControl(String process, int userId, boolean start, 16315 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16316 16317 try { 16318 synchronized (this) { 16319 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16320 // its own permission. 16321 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16322 != PackageManager.PERMISSION_GRANTED) { 16323 throw new SecurityException("Requires permission " 16324 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16325 } 16326 16327 if (start && fd == null) { 16328 throw new IllegalArgumentException("null fd"); 16329 } 16330 16331 ProcessRecord proc = null; 16332 if (process != null) { 16333 proc = findProcessLocked(process, userId, "profileControl"); 16334 } 16335 16336 if (start && (proc == null || proc.thread == null)) { 16337 throw new IllegalArgumentException("Unknown process: " + process); 16338 } 16339 16340 if (start) { 16341 stopProfilerLocked(null, null, 0); 16342 setProfileApp(proc.info, proc.processName, path, fd, false); 16343 mProfileProc = proc; 16344 mProfileType = profileType; 16345 try { 16346 fd = fd.dup(); 16347 } catch (IOException e) { 16348 fd = null; 16349 } 16350 proc.thread.profilerControl(start, path, fd, profileType); 16351 fd = null; 16352 mProfileFd = null; 16353 } else { 16354 stopProfilerLocked(proc, path, profileType); 16355 if (fd != null) { 16356 try { 16357 fd.close(); 16358 } catch (IOException e) { 16359 } 16360 } 16361 } 16362 16363 return true; 16364 } 16365 } catch (RemoteException e) { 16366 throw new IllegalStateException("Process disappeared"); 16367 } finally { 16368 if (fd != null) { 16369 try { 16370 fd.close(); 16371 } catch (IOException e) { 16372 } 16373 } 16374 } 16375 } 16376 16377 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16378 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16379 userId, true, true, callName, null); 16380 ProcessRecord proc = null; 16381 try { 16382 int pid = Integer.parseInt(process); 16383 synchronized (mPidsSelfLocked) { 16384 proc = mPidsSelfLocked.get(pid); 16385 } 16386 } catch (NumberFormatException e) { 16387 } 16388 16389 if (proc == null) { 16390 ArrayMap<String, SparseArray<ProcessRecord>> all 16391 = mProcessNames.getMap(); 16392 SparseArray<ProcessRecord> procs = all.get(process); 16393 if (procs != null && procs.size() > 0) { 16394 proc = procs.valueAt(0); 16395 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16396 for (int i=1; i<procs.size(); i++) { 16397 ProcessRecord thisProc = procs.valueAt(i); 16398 if (thisProc.userId == userId) { 16399 proc = thisProc; 16400 break; 16401 } 16402 } 16403 } 16404 } 16405 } 16406 16407 return proc; 16408 } 16409 16410 public boolean dumpHeap(String process, int userId, boolean managed, 16411 String path, ParcelFileDescriptor fd) throws RemoteException { 16412 16413 try { 16414 synchronized (this) { 16415 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16416 // its own permission (same as profileControl). 16417 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16418 != PackageManager.PERMISSION_GRANTED) { 16419 throw new SecurityException("Requires permission " 16420 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16421 } 16422 16423 if (fd == null) { 16424 throw new IllegalArgumentException("null fd"); 16425 } 16426 16427 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16428 if (proc == null || proc.thread == null) { 16429 throw new IllegalArgumentException("Unknown process: " + process); 16430 } 16431 16432 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16433 if (!isDebuggable) { 16434 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16435 throw new SecurityException("Process not debuggable: " + proc); 16436 } 16437 } 16438 16439 proc.thread.dumpHeap(managed, path, fd); 16440 fd = null; 16441 return true; 16442 } 16443 } catch (RemoteException e) { 16444 throw new IllegalStateException("Process disappeared"); 16445 } finally { 16446 if (fd != null) { 16447 try { 16448 fd.close(); 16449 } catch (IOException e) { 16450 } 16451 } 16452 } 16453 } 16454 16455 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16456 public void monitor() { 16457 synchronized (this) { } 16458 } 16459 16460 void onCoreSettingsChange(Bundle settings) { 16461 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16462 ProcessRecord processRecord = mLruProcesses.get(i); 16463 try { 16464 if (processRecord.thread != null) { 16465 processRecord.thread.setCoreSettings(settings); 16466 } 16467 } catch (RemoteException re) { 16468 /* ignore */ 16469 } 16470 } 16471 } 16472 16473 // Multi-user methods 16474 16475 /** 16476 * Start user, if its not already running, but don't bring it to foreground. 16477 */ 16478 @Override 16479 public boolean startUserInBackground(final int userId) { 16480 return startUser(userId, /* foreground */ false); 16481 } 16482 16483 /** 16484 * Refreshes the list of users related to the current user when either a 16485 * user switch happens or when a new related user is started in the 16486 * background. 16487 */ 16488 private void updateCurrentProfileIdsLocked() { 16489 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16490 mCurrentUserId, false /* enabledOnly */); 16491 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16492 for (int i = 0; i < currentProfileIds.length; i++) { 16493 currentProfileIds[i] = profiles.get(i).id; 16494 } 16495 mCurrentProfileIds = currentProfileIds; 16496 } 16497 16498 private Set getProfileIdsLocked(int userId) { 16499 Set userIds = new HashSet<Integer>(); 16500 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16501 userId, false /* enabledOnly */); 16502 for (UserInfo user : profiles) { 16503 userIds.add(Integer.valueOf(user.id)); 16504 } 16505 return userIds; 16506 } 16507 16508 @Override 16509 public boolean switchUser(final int userId) { 16510 return startUser(userId, /* foregound */ true); 16511 } 16512 16513 private boolean startUser(final int userId, boolean foreground) { 16514 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16515 != PackageManager.PERMISSION_GRANTED) { 16516 String msg = "Permission Denial: switchUser() from pid=" 16517 + Binder.getCallingPid() 16518 + ", uid=" + Binder.getCallingUid() 16519 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16520 Slog.w(TAG, msg); 16521 throw new SecurityException(msg); 16522 } 16523 16524 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16525 16526 final long ident = Binder.clearCallingIdentity(); 16527 try { 16528 synchronized (this) { 16529 final int oldUserId = mCurrentUserId; 16530 if (oldUserId == userId) { 16531 return true; 16532 } 16533 16534 mStackSupervisor.setLockTaskModeLocked(null); 16535 16536 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16537 if (userInfo == null) { 16538 Slog.w(TAG, "No user info for user #" + userId); 16539 return false; 16540 } 16541 16542 if (foreground) { 16543 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16544 R.anim.screen_user_enter); 16545 } 16546 16547 boolean needStart = false; 16548 16549 // If the user we are switching to is not currently started, then 16550 // we need to start it now. 16551 if (mStartedUsers.get(userId) == null) { 16552 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16553 updateStartedUserArrayLocked(); 16554 needStart = true; 16555 } 16556 16557 final Integer userIdInt = Integer.valueOf(userId); 16558 mUserLru.remove(userIdInt); 16559 mUserLru.add(userIdInt); 16560 16561 if (foreground) { 16562 mCurrentUserId = userId; 16563 updateCurrentProfileIdsLocked(); 16564 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16565 // Once the internal notion of the active user has switched, we lock the device 16566 // with the option to show the user switcher on the keyguard. 16567 mWindowManager.lockNow(null); 16568 } else { 16569 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16570 updateCurrentProfileIdsLocked(); 16571 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16572 mUserLru.remove(currentUserIdInt); 16573 mUserLru.add(currentUserIdInt); 16574 } 16575 16576 final UserStartedState uss = mStartedUsers.get(userId); 16577 16578 // Make sure user is in the started state. If it is currently 16579 // stopping, we need to knock that off. 16580 if (uss.mState == UserStartedState.STATE_STOPPING) { 16581 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16582 // so we can just fairly silently bring the user back from 16583 // the almost-dead. 16584 uss.mState = UserStartedState.STATE_RUNNING; 16585 updateStartedUserArrayLocked(); 16586 needStart = true; 16587 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16588 // This means ACTION_SHUTDOWN has been sent, so we will 16589 // need to treat this as a new boot of the user. 16590 uss.mState = UserStartedState.STATE_BOOTING; 16591 updateStartedUserArrayLocked(); 16592 needStart = true; 16593 } 16594 16595 if (uss.mState == UserStartedState.STATE_BOOTING) { 16596 // Booting up a new user, need to tell system services about it. 16597 // Note that this is on the same handler as scheduling of broadcasts, 16598 // which is important because it needs to go first. 16599 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16600 } 16601 16602 if (foreground) { 16603 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16604 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16605 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16606 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16607 oldUserId, userId, uss)); 16608 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16609 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16610 } 16611 16612 if (needStart) { 16613 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16614 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16615 | Intent.FLAG_RECEIVER_FOREGROUND); 16616 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16617 broadcastIntentLocked(null, null, intent, 16618 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16619 false, false, MY_PID, Process.SYSTEM_UID, userId); 16620 } 16621 16622 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16623 if (userId != UserHandle.USER_OWNER) { 16624 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16625 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16626 broadcastIntentLocked(null, null, intent, null, 16627 new IIntentReceiver.Stub() { 16628 public void performReceive(Intent intent, int resultCode, 16629 String data, Bundle extras, boolean ordered, 16630 boolean sticky, int sendingUser) { 16631 userInitialized(uss, userId); 16632 } 16633 }, 0, null, null, null, AppOpsManager.OP_NONE, 16634 true, false, MY_PID, Process.SYSTEM_UID, 16635 userId); 16636 uss.initializing = true; 16637 } else { 16638 getUserManagerLocked().makeInitialized(userInfo.id); 16639 } 16640 } 16641 16642 if (foreground) { 16643 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16644 if (homeInFront) { 16645 startHomeActivityLocked(userId); 16646 } else { 16647 mStackSupervisor.resumeTopActivitiesLocked(); 16648 } 16649 EventLogTags.writeAmSwitchUser(userId); 16650 getUserManagerLocked().userForeground(userId); 16651 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16652 } else { 16653 mStackSupervisor.startBackgroundUserLocked(userId, uss); 16654 } 16655 16656 if (needStart) { 16657 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16658 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16659 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16660 broadcastIntentLocked(null, null, intent, 16661 null, new IIntentReceiver.Stub() { 16662 @Override 16663 public void performReceive(Intent intent, int resultCode, String data, 16664 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16665 throws RemoteException { 16666 } 16667 }, 0, null, null, 16668 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16669 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16670 } 16671 } 16672 } finally { 16673 Binder.restoreCallingIdentity(ident); 16674 } 16675 16676 return true; 16677 } 16678 16679 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16680 long ident = Binder.clearCallingIdentity(); 16681 try { 16682 Intent intent; 16683 if (oldUserId >= 0) { 16684 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16685 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16686 | Intent.FLAG_RECEIVER_FOREGROUND); 16687 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16688 broadcastIntentLocked(null, null, intent, 16689 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16690 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16691 } 16692 if (newUserId >= 0) { 16693 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16694 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16695 | Intent.FLAG_RECEIVER_FOREGROUND); 16696 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16697 broadcastIntentLocked(null, null, intent, 16698 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16699 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16700 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16701 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16702 | Intent.FLAG_RECEIVER_FOREGROUND); 16703 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16704 broadcastIntentLocked(null, null, intent, 16705 null, null, 0, null, null, 16706 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16707 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16708 } 16709 } finally { 16710 Binder.restoreCallingIdentity(ident); 16711 } 16712 } 16713 16714 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16715 final int newUserId) { 16716 final int N = mUserSwitchObservers.beginBroadcast(); 16717 if (N > 0) { 16718 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16719 int mCount = 0; 16720 @Override 16721 public void sendResult(Bundle data) throws RemoteException { 16722 synchronized (ActivityManagerService.this) { 16723 if (mCurUserSwitchCallback == this) { 16724 mCount++; 16725 if (mCount == N) { 16726 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16727 } 16728 } 16729 } 16730 } 16731 }; 16732 synchronized (this) { 16733 uss.switching = true; 16734 mCurUserSwitchCallback = callback; 16735 } 16736 for (int i=0; i<N; i++) { 16737 try { 16738 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16739 newUserId, callback); 16740 } catch (RemoteException e) { 16741 } 16742 } 16743 } else { 16744 synchronized (this) { 16745 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16746 } 16747 } 16748 mUserSwitchObservers.finishBroadcast(); 16749 } 16750 16751 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16752 synchronized (this) { 16753 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16754 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16755 } 16756 } 16757 16758 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16759 mCurUserSwitchCallback = null; 16760 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16761 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16762 oldUserId, newUserId, uss)); 16763 } 16764 16765 void userInitialized(UserStartedState uss, int newUserId) { 16766 completeSwitchAndInitalize(uss, newUserId, true, false); 16767 } 16768 16769 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16770 completeSwitchAndInitalize(uss, newUserId, false, true); 16771 } 16772 16773 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16774 boolean clearInitializing, boolean clearSwitching) { 16775 boolean unfrozen = false; 16776 synchronized (this) { 16777 if (clearInitializing) { 16778 uss.initializing = false; 16779 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16780 } 16781 if (clearSwitching) { 16782 uss.switching = false; 16783 } 16784 if (!uss.switching && !uss.initializing) { 16785 mWindowManager.stopFreezingScreen(); 16786 unfrozen = true; 16787 } 16788 } 16789 if (unfrozen) { 16790 final int N = mUserSwitchObservers.beginBroadcast(); 16791 for (int i=0; i<N; i++) { 16792 try { 16793 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16794 } catch (RemoteException e) { 16795 } 16796 } 16797 mUserSwitchObservers.finishBroadcast(); 16798 } 16799 } 16800 16801 void scheduleStartProfilesLocked() { 16802 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16803 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16804 DateUtils.SECOND_IN_MILLIS); 16805 } 16806 } 16807 16808 void startProfilesLocked() { 16809 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16810 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16811 mCurrentUserId, false /* enabledOnly */); 16812 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16813 for (UserInfo user : profiles) { 16814 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16815 && user.id != mCurrentUserId) { 16816 toStart.add(user); 16817 } 16818 } 16819 final int n = toStart.size(); 16820 int i = 0; 16821 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16822 startUserInBackground(toStart.get(i).id); 16823 } 16824 if (i < n) { 16825 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16826 } 16827 } 16828 16829 void finishUserBoot(UserStartedState uss) { 16830 synchronized (this) { 16831 if (uss.mState == UserStartedState.STATE_BOOTING 16832 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16833 uss.mState = UserStartedState.STATE_RUNNING; 16834 final int userId = uss.mHandle.getIdentifier(); 16835 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16836 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16837 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16838 broadcastIntentLocked(null, null, intent, 16839 null, null, 0, null, null, 16840 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16841 true, false, MY_PID, Process.SYSTEM_UID, userId); 16842 } 16843 } 16844 } 16845 16846 void finishUserSwitch(UserStartedState uss) { 16847 synchronized (this) { 16848 finishUserBoot(uss); 16849 16850 startProfilesLocked(); 16851 16852 int num = mUserLru.size(); 16853 int i = 0; 16854 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16855 Integer oldUserId = mUserLru.get(i); 16856 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16857 if (oldUss == null) { 16858 // Shouldn't happen, but be sane if it does. 16859 mUserLru.remove(i); 16860 num--; 16861 continue; 16862 } 16863 if (oldUss.mState == UserStartedState.STATE_STOPPING 16864 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16865 // This user is already stopping, doesn't count. 16866 num--; 16867 i++; 16868 continue; 16869 } 16870 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16871 // Owner and current can't be stopped, but count as running. 16872 i++; 16873 continue; 16874 } 16875 // This is a user to be stopped. 16876 stopUserLocked(oldUserId, null); 16877 num--; 16878 i++; 16879 } 16880 } 16881 } 16882 16883 @Override 16884 public int stopUser(final int userId, final IStopUserCallback callback) { 16885 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16886 != PackageManager.PERMISSION_GRANTED) { 16887 String msg = "Permission Denial: switchUser() from pid=" 16888 + Binder.getCallingPid() 16889 + ", uid=" + Binder.getCallingUid() 16890 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16891 Slog.w(TAG, msg); 16892 throw new SecurityException(msg); 16893 } 16894 if (userId <= 0) { 16895 throw new IllegalArgumentException("Can't stop primary user " + userId); 16896 } 16897 synchronized (this) { 16898 return stopUserLocked(userId, callback); 16899 } 16900 } 16901 16902 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16903 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16904 if (mCurrentUserId == userId) { 16905 return ActivityManager.USER_OP_IS_CURRENT; 16906 } 16907 16908 final UserStartedState uss = mStartedUsers.get(userId); 16909 if (uss == null) { 16910 // User is not started, nothing to do... but we do need to 16911 // callback if requested. 16912 if (callback != null) { 16913 mHandler.post(new Runnable() { 16914 @Override 16915 public void run() { 16916 try { 16917 callback.userStopped(userId); 16918 } catch (RemoteException e) { 16919 } 16920 } 16921 }); 16922 } 16923 return ActivityManager.USER_OP_SUCCESS; 16924 } 16925 16926 if (callback != null) { 16927 uss.mStopCallbacks.add(callback); 16928 } 16929 16930 if (uss.mState != UserStartedState.STATE_STOPPING 16931 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16932 uss.mState = UserStartedState.STATE_STOPPING; 16933 updateStartedUserArrayLocked(); 16934 16935 long ident = Binder.clearCallingIdentity(); 16936 try { 16937 // We are going to broadcast ACTION_USER_STOPPING and then 16938 // once that is done send a final ACTION_SHUTDOWN and then 16939 // stop the user. 16940 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16941 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16942 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16943 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16944 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16945 // This is the result receiver for the final shutdown broadcast. 16946 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16947 @Override 16948 public void performReceive(Intent intent, int resultCode, String data, 16949 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16950 finishUserStop(uss); 16951 } 16952 }; 16953 // This is the result receiver for the initial stopping broadcast. 16954 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16955 @Override 16956 public void performReceive(Intent intent, int resultCode, String data, 16957 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16958 // On to the next. 16959 synchronized (ActivityManagerService.this) { 16960 if (uss.mState != UserStartedState.STATE_STOPPING) { 16961 // Whoops, we are being started back up. Abort, abort! 16962 return; 16963 } 16964 uss.mState = UserStartedState.STATE_SHUTDOWN; 16965 } 16966 mSystemServiceManager.stopUser(userId); 16967 broadcastIntentLocked(null, null, shutdownIntent, 16968 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16969 true, false, MY_PID, Process.SYSTEM_UID, userId); 16970 } 16971 }; 16972 // Kick things off. 16973 broadcastIntentLocked(null, null, stoppingIntent, 16974 null, stoppingReceiver, 0, null, null, 16975 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16976 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16977 } finally { 16978 Binder.restoreCallingIdentity(ident); 16979 } 16980 } 16981 16982 return ActivityManager.USER_OP_SUCCESS; 16983 } 16984 16985 void finishUserStop(UserStartedState uss) { 16986 final int userId = uss.mHandle.getIdentifier(); 16987 boolean stopped; 16988 ArrayList<IStopUserCallback> callbacks; 16989 synchronized (this) { 16990 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16991 if (mStartedUsers.get(userId) != uss) { 16992 stopped = false; 16993 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16994 stopped = false; 16995 } else { 16996 stopped = true; 16997 // User can no longer run. 16998 mStartedUsers.remove(userId); 16999 mUserLru.remove(Integer.valueOf(userId)); 17000 updateStartedUserArrayLocked(); 17001 17002 // Clean up all state and processes associated with the user. 17003 // Kill all the processes for the user. 17004 forceStopUserLocked(userId, "finish user"); 17005 } 17006 } 17007 17008 for (int i=0; i<callbacks.size(); i++) { 17009 try { 17010 if (stopped) callbacks.get(i).userStopped(userId); 17011 else callbacks.get(i).userStopAborted(userId); 17012 } catch (RemoteException e) { 17013 } 17014 } 17015 17016 if (stopped) { 17017 mSystemServiceManager.cleanupUser(userId); 17018 synchronized (this) { 17019 mStackSupervisor.removeUserLocked(userId); 17020 } 17021 } 17022 } 17023 17024 @Override 17025 public UserInfo getCurrentUser() { 17026 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17027 != PackageManager.PERMISSION_GRANTED) && ( 17028 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17029 != PackageManager.PERMISSION_GRANTED)) { 17030 String msg = "Permission Denial: getCurrentUser() from pid=" 17031 + Binder.getCallingPid() 17032 + ", uid=" + Binder.getCallingUid() 17033 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17034 Slog.w(TAG, msg); 17035 throw new SecurityException(msg); 17036 } 17037 synchronized (this) { 17038 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17039 } 17040 } 17041 17042 int getCurrentUserIdLocked() { 17043 return mCurrentUserId; 17044 } 17045 17046 @Override 17047 public boolean isUserRunning(int userId, boolean orStopped) { 17048 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17049 != PackageManager.PERMISSION_GRANTED) { 17050 String msg = "Permission Denial: isUserRunning() from pid=" 17051 + Binder.getCallingPid() 17052 + ", uid=" + Binder.getCallingUid() 17053 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17054 Slog.w(TAG, msg); 17055 throw new SecurityException(msg); 17056 } 17057 synchronized (this) { 17058 return isUserRunningLocked(userId, orStopped); 17059 } 17060 } 17061 17062 boolean isUserRunningLocked(int userId, boolean orStopped) { 17063 UserStartedState state = mStartedUsers.get(userId); 17064 if (state == null) { 17065 return false; 17066 } 17067 if (orStopped) { 17068 return true; 17069 } 17070 return state.mState != UserStartedState.STATE_STOPPING 17071 && state.mState != UserStartedState.STATE_SHUTDOWN; 17072 } 17073 17074 @Override 17075 public int[] getRunningUserIds() { 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 mStartedUserArray; 17087 } 17088 } 17089 17090 private void updateStartedUserArrayLocked() { 17091 int num = 0; 17092 for (int i=0; i<mStartedUsers.size(); i++) { 17093 UserStartedState uss = mStartedUsers.valueAt(i); 17094 // This list does not include stopping users. 17095 if (uss.mState != UserStartedState.STATE_STOPPING 17096 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17097 num++; 17098 } 17099 } 17100 mStartedUserArray = new int[num]; 17101 num = 0; 17102 for (int i=0; i<mStartedUsers.size(); i++) { 17103 UserStartedState uss = mStartedUsers.valueAt(i); 17104 if (uss.mState != UserStartedState.STATE_STOPPING 17105 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17106 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17107 num++; 17108 } 17109 } 17110 } 17111 17112 @Override 17113 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17114 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17115 != PackageManager.PERMISSION_GRANTED) { 17116 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17117 + Binder.getCallingPid() 17118 + ", uid=" + Binder.getCallingUid() 17119 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 17120 Slog.w(TAG, msg); 17121 throw new SecurityException(msg); 17122 } 17123 17124 mUserSwitchObservers.register(observer); 17125 } 17126 17127 @Override 17128 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17129 mUserSwitchObservers.unregister(observer); 17130 } 17131 17132 private boolean userExists(int userId) { 17133 if (userId == 0) { 17134 return true; 17135 } 17136 UserManagerService ums = getUserManagerLocked(); 17137 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17138 } 17139 17140 int[] getUsersLocked() { 17141 UserManagerService ums = getUserManagerLocked(); 17142 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17143 } 17144 17145 UserManagerService getUserManagerLocked() { 17146 if (mUserManager == null) { 17147 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17148 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17149 } 17150 return mUserManager; 17151 } 17152 17153 private int applyUserId(int uid, int userId) { 17154 return UserHandle.getUid(userId, uid); 17155 } 17156 17157 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17158 if (info == null) return null; 17159 ApplicationInfo newInfo = new ApplicationInfo(info); 17160 newInfo.uid = applyUserId(info.uid, userId); 17161 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17162 + info.packageName; 17163 return newInfo; 17164 } 17165 17166 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17167 if (aInfo == null 17168 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17169 return aInfo; 17170 } 17171 17172 ActivityInfo info = new ActivityInfo(aInfo); 17173 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17174 return info; 17175 } 17176 17177 private final class LocalService extends ActivityManagerInternal { 17178 @Override 17179 public void goingToSleep() { 17180 ActivityManagerService.this.goingToSleep(); 17181 } 17182 17183 @Override 17184 public void wakingUp() { 17185 ActivityManagerService.this.wakingUp(); 17186 } 17187 } 17188 17189 /** 17190 * An implementation of IAppTask, that allows an app to manage its own tasks via 17191 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 17192 * only the process that calls getAppTasks() can call the AppTask methods. 17193 */ 17194 class AppTaskImpl extends IAppTask.Stub { 17195 private int mTaskId; 17196 private int mCallingUid; 17197 17198 public AppTaskImpl(int taskId, int callingUid) { 17199 mTaskId = taskId; 17200 mCallingUid = callingUid; 17201 } 17202 17203 @Override 17204 public void finishAndRemoveTask() { 17205 // Ensure that we are called from the same process that created this AppTask 17206 if (mCallingUid != Binder.getCallingUid()) { 17207 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17208 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17209 return; 17210 } 17211 17212 synchronized (ActivityManagerService.this) { 17213 long origId = Binder.clearCallingIdentity(); 17214 try { 17215 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17216 if (tr != null) { 17217 // Only kill the process if we are not a new document 17218 int flags = tr.getBaseIntent().getFlags(); 17219 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 17220 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 17221 removeTaskByIdLocked(mTaskId, 17222 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 17223 } 17224 } finally { 17225 Binder.restoreCallingIdentity(origId); 17226 } 17227 } 17228 } 17229 17230 @Override 17231 public ActivityManager.RecentTaskInfo getTaskInfo() { 17232 // Ensure that we are called from the same process that created this AppTask 17233 if (mCallingUid != Binder.getCallingUid()) { 17234 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17235 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17236 return null; 17237 } 17238 17239 synchronized (ActivityManagerService.this) { 17240 long origId = Binder.clearCallingIdentity(); 17241 try { 17242 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17243 if (tr != null) { 17244 return createRecentTaskInfoFromTaskRecord(tr); 17245 } 17246 } finally { 17247 Binder.restoreCallingIdentity(origId); 17248 } 17249 return null; 17250 } 17251 } 17252 } 17253} 17254