ActivityManagerService.java revision 21d24a21ea4aaadd78e73de54168e8a8a8973e4d
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.app.admin.DevicePolicyManager; 37import android.appwidget.AppWidgetManager; 38import android.graphics.Rect; 39import android.os.BatteryStats; 40import android.os.PersistableBundle; 41import android.service.voice.IVoiceInteractionSession; 42import android.util.ArrayMap; 43 44import com.android.internal.R; 45import com.android.internal.annotations.GuardedBy; 46import com.android.internal.app.IAppOpsService; 47import com.android.internal.app.IVoiceInteractor; 48import com.android.internal.app.ProcessMap; 49import com.android.internal.app.ProcessStats; 50import com.android.internal.content.PackageMonitor; 51import com.android.internal.os.BackgroundThread; 52import com.android.internal.os.BatteryStatsImpl; 53import com.android.internal.os.ProcessCpuTracker; 54import com.android.internal.os.TransferPipe; 55import com.android.internal.os.Zygote; 56import com.android.internal.util.FastPrintWriter; 57import com.android.internal.util.FastXmlSerializer; 58import com.android.internal.util.MemInfoReader; 59import com.android.internal.util.Preconditions; 60import com.android.server.AppOpsService; 61import com.android.server.AttributeCache; 62import com.android.server.IntentResolver; 63import com.android.server.LocalServices; 64import com.android.server.ServiceThread; 65import com.android.server.SystemService; 66import com.android.server.SystemServiceManager; 67import com.android.server.Watchdog; 68import com.android.server.am.ActivityStack.ActivityState; 69import com.android.server.firewall.IntentFirewall; 70import com.android.server.pm.UserManagerService; 71import com.android.server.wm.AppTransition; 72import com.android.server.wm.WindowManagerService; 73import com.google.android.collect.Lists; 74import com.google.android.collect.Maps; 75 76import libcore.io.IoUtils; 77 78import org.xmlpull.v1.XmlPullParser; 79import org.xmlpull.v1.XmlPullParserException; 80import org.xmlpull.v1.XmlSerializer; 81 82import android.app.Activity; 83import android.app.ActivityManager; 84import android.app.ActivityManager.RunningTaskInfo; 85import android.app.ActivityManager.StackInfo; 86import android.app.ActivityManagerInternal; 87import android.app.ActivityManagerNative; 88import android.app.ActivityOptions; 89import android.app.ActivityThread; 90import android.app.AlertDialog; 91import android.app.AppGlobals; 92import android.app.ApplicationErrorReport; 93import android.app.Dialog; 94import android.app.IActivityController; 95import android.app.IApplicationThread; 96import android.app.IInstrumentationWatcher; 97import android.app.INotificationManager; 98import android.app.IProcessObserver; 99import android.app.IServiceConnection; 100import android.app.IStopUserCallback; 101import android.app.IUiAutomationConnection; 102import android.app.IUserSwitchObserver; 103import android.app.Instrumentation; 104import android.app.Notification; 105import android.app.NotificationManager; 106import android.app.PendingIntent; 107import android.app.backup.IBackupManager; 108import android.content.ActivityNotFoundException; 109import android.content.BroadcastReceiver; 110import android.content.ClipData; 111import android.content.ComponentCallbacks2; 112import android.content.ComponentName; 113import android.content.ContentProvider; 114import android.content.ContentResolver; 115import android.content.Context; 116import android.content.DialogInterface; 117import android.content.IContentProvider; 118import android.content.IIntentReceiver; 119import android.content.IIntentSender; 120import android.content.Intent; 121import android.content.IntentFilter; 122import android.content.IntentSender; 123import android.content.pm.ActivityInfo; 124import android.content.pm.ApplicationInfo; 125import android.content.pm.ConfigurationInfo; 126import android.content.pm.IPackageDataObserver; 127import android.content.pm.IPackageManager; 128import android.content.pm.InstrumentationInfo; 129import android.content.pm.PackageInfo; 130import android.content.pm.PackageManager; 131import android.content.pm.ParceledListSlice; 132import android.content.pm.UserInfo; 133import android.content.pm.PackageManager.NameNotFoundException; 134import android.content.pm.PathPermission; 135import android.content.pm.ProviderInfo; 136import android.content.pm.ResolveInfo; 137import android.content.pm.ServiceInfo; 138import android.content.res.CompatibilityInfo; 139import android.content.res.Configuration; 140import android.graphics.Bitmap; 141import android.net.Proxy; 142import android.net.ProxyInfo; 143import android.net.Uri; 144import android.os.Binder; 145import android.os.Build; 146import android.os.Bundle; 147import android.os.Debug; 148import android.os.DropBoxManager; 149import android.os.Environment; 150import android.os.FactoryTest; 151import android.os.FileObserver; 152import android.os.FileUtils; 153import android.os.Handler; 154import android.os.IBinder; 155import android.os.IPermissionController; 156import android.os.IRemoteCallback; 157import android.os.IUserManager; 158import android.os.Looper; 159import android.os.Message; 160import android.os.Parcel; 161import android.os.ParcelFileDescriptor; 162import android.os.Process; 163import android.os.RemoteCallbackList; 164import android.os.RemoteException; 165import android.os.SELinux; 166import android.os.ServiceManager; 167import android.os.StrictMode; 168import android.os.SystemClock; 169import android.os.SystemProperties; 170import android.os.UpdateLock; 171import android.os.UserHandle; 172import android.provider.Settings; 173import android.text.format.DateUtils; 174import android.text.format.Time; 175import android.util.AtomicFile; 176import android.util.EventLog; 177import android.util.Log; 178import android.util.Pair; 179import android.util.PrintWriterPrinter; 180import android.util.Slog; 181import android.util.SparseArray; 182import android.util.TimeUtils; 183import android.util.Xml; 184import android.view.Gravity; 185import android.view.LayoutInflater; 186import android.view.View; 187import android.view.WindowManager; 188 189import java.io.BufferedInputStream; 190import java.io.BufferedOutputStream; 191import java.io.DataInputStream; 192import java.io.DataOutputStream; 193import java.io.File; 194import java.io.FileDescriptor; 195import java.io.FileInputStream; 196import java.io.FileNotFoundException; 197import java.io.FileOutputStream; 198import java.io.IOException; 199import java.io.InputStreamReader; 200import java.io.PrintWriter; 201import java.io.StringWriter; 202import java.lang.ref.WeakReference; 203import java.util.ArrayList; 204import java.util.Arrays; 205import java.util.Collections; 206import java.util.Comparator; 207import java.util.HashMap; 208import java.util.HashSet; 209import java.util.Iterator; 210import java.util.List; 211import java.util.Locale; 212import java.util.Map; 213import java.util.Set; 214import java.util.concurrent.atomic.AtomicBoolean; 215import java.util.concurrent.atomic.AtomicLong; 216 217public final class ActivityManagerService extends ActivityManagerNative 218 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 219 private static final String USER_DATA_DIR = "/data/user/"; 220 static final String TAG = "ActivityManager"; 221 static final String TAG_MU = "ActivityManagerServiceMU"; 222 static final boolean DEBUG = false; 223 static final boolean localLOGV = DEBUG; 224 static final boolean DEBUG_BACKUP = localLOGV || false; 225 static final boolean DEBUG_BROADCAST = localLOGV || false; 226 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 227 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 228 static final boolean DEBUG_CLEANUP = localLOGV || false; 229 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 230 static final boolean DEBUG_FOCUS = false; 231 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 232 static final boolean DEBUG_MU = localLOGV || false; 233 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 234 static final boolean DEBUG_LRU = localLOGV || false; 235 static final boolean DEBUG_PAUSE = localLOGV || false; 236 static final boolean DEBUG_POWER = localLOGV || false; 237 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 238 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 239 static final boolean DEBUG_PROCESSES = localLOGV || false; 240 static final boolean DEBUG_PROVIDER = localLOGV || false; 241 static final boolean DEBUG_RESULTS = localLOGV || false; 242 static final boolean DEBUG_SERVICE = localLOGV || false; 243 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 244 static final boolean DEBUG_STACK = localLOGV || false; 245 static final boolean DEBUG_SWITCH = localLOGV || false; 246 static final boolean DEBUG_TASKS = localLOGV || false; 247 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 248 static final boolean DEBUG_TRANSITION = localLOGV || false; 249 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 250 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 251 static final boolean DEBUG_VISBILITY = localLOGV || false; 252 static final boolean DEBUG_PSS = localLOGV || false; 253 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 254 static final boolean VALIDATE_TOKENS = false; 255 static final boolean SHOW_ACTIVITY_START_TIME = true; 256 257 // Control over CPU and battery monitoring. 258 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 259 static final boolean MONITOR_CPU_USAGE = true; 260 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 261 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 262 static final boolean MONITOR_THREAD_CPU_USAGE = false; 263 264 // The flags that are set for all calls we make to the package manager. 265 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 266 267 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 268 269 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 270 271 // Maximum number of recent tasks that we can remember. 272 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 273 274 // Amount of time after a call to stopAppSwitches() during which we will 275 // prevent further untrusted switches from happening. 276 static final long APP_SWITCH_DELAY_TIME = 5*1000; 277 278 // How long we wait for a launched process to attach to the activity manager 279 // before we decide it's never going to come up for real. 280 static final int PROC_START_TIMEOUT = 10*1000; 281 282 // How long we wait for a launched process to attach to the activity manager 283 // before we decide it's never going to come up for real, when the process was 284 // started with a wrapper for instrumentation (such as Valgrind) because it 285 // could take much longer than usual. 286 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 287 288 // How long to wait after going idle before forcing apps to GC. 289 static final int GC_TIMEOUT = 5*1000; 290 291 // The minimum amount of time between successive GC requests for a process. 292 static final int GC_MIN_INTERVAL = 60*1000; 293 294 // The minimum amount of time between successive PSS requests for a process. 295 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 296 297 // The minimum amount of time between successive PSS requests for a process 298 // when the request is due to the memory state being lowered. 299 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 300 301 // The rate at which we check for apps using excessive power -- 15 mins. 302 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 303 304 // The minimum sample duration we will allow before deciding we have 305 // enough data on wake locks to start killing things. 306 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 307 308 // The minimum sample duration we will allow before deciding we have 309 // enough data on CPU usage to start killing things. 310 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 311 312 // How long we allow a receiver to run before giving up on it. 313 static final int BROADCAST_FG_TIMEOUT = 10*1000; 314 static final int BROADCAST_BG_TIMEOUT = 60*1000; 315 316 // How long we wait until we timeout on key dispatching. 317 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 318 319 // How long we wait until we timeout on key dispatching during instrumentation. 320 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 321 322 // Amount of time we wait for observers to handle a user switch before 323 // giving up on them and unfreezing the screen. 324 static final int USER_SWITCH_TIMEOUT = 2*1000; 325 326 // Maximum number of users we allow to be running at a time. 327 static final int MAX_RUNNING_USERS = 3; 328 329 // How long to wait in getAssistContextExtras for the activity and foreground services 330 // to respond with the result. 331 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 332 333 // Maximum number of persisted Uri grants a package is allowed 334 static final int MAX_PERSISTED_URI_GRANTS = 128; 335 336 static final int MY_PID = Process.myPid(); 337 338 static final String[] EMPTY_STRING_ARRAY = new String[0]; 339 340 // How many bytes to write into the dropbox log before truncating 341 static final int DROPBOX_MAX_SIZE = 256 * 1024; 342 343 /** All system services */ 344 SystemServiceManager mSystemServiceManager; 345 346 /** Run all ActivityStacks through this */ 347 ActivityStackSupervisor mStackSupervisor; 348 349 public IntentFirewall mIntentFirewall; 350 351 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 352 // default actuion automatically. Important for devices without direct input 353 // devices. 354 private boolean mShowDialogs = true; 355 356 /** 357 * Description of a request to start a new activity, which has been held 358 * due to app switches being disabled. 359 */ 360 static class PendingActivityLaunch { 361 final ActivityRecord r; 362 final ActivityRecord sourceRecord; 363 final int startFlags; 364 final ActivityStack stack; 365 366 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 367 int _startFlags, ActivityStack _stack) { 368 r = _r; 369 sourceRecord = _sourceRecord; 370 startFlags = _startFlags; 371 stack = _stack; 372 } 373 } 374 375 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 376 = new ArrayList<PendingActivityLaunch>(); 377 378 BroadcastQueue mFgBroadcastQueue; 379 BroadcastQueue mBgBroadcastQueue; 380 // Convenient for easy iteration over the queues. Foreground is first 381 // so that dispatch of foreground broadcasts gets precedence. 382 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 383 384 BroadcastQueue broadcastQueueForIntent(Intent intent) { 385 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 386 if (DEBUG_BACKGROUND_BROADCAST) { 387 Slog.i(TAG, "Broadcast intent " + intent + " on " 388 + (isFg ? "foreground" : "background") 389 + " queue"); 390 } 391 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 392 } 393 394 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 395 for (BroadcastQueue queue : mBroadcastQueues) { 396 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 397 if (r != null) { 398 return r; 399 } 400 } 401 return null; 402 } 403 404 /** 405 * Activity we have told the window manager to have key focus. 406 */ 407 ActivityRecord mFocusedActivity = null; 408 409 /** 410 * List of intents that were used to start the most recent tasks. 411 */ 412 ArrayList<TaskRecord> mRecentTasks; 413 414 public class PendingAssistExtras extends Binder implements Runnable { 415 public final ActivityRecord activity; 416 public boolean haveResult = false; 417 public Bundle result = null; 418 public PendingAssistExtras(ActivityRecord _activity) { 419 activity = _activity; 420 } 421 @Override 422 public void run() { 423 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 424 synchronized (this) { 425 haveResult = true; 426 notifyAll(); 427 } 428 } 429 } 430 431 final ArrayList<PendingAssistExtras> mPendingAssistExtras 432 = new ArrayList<PendingAssistExtras>(); 433 434 /** 435 * Process management. 436 */ 437 final ProcessList mProcessList = new ProcessList(); 438 439 /** 440 * All of the applications we currently have running organized by name. 441 * The keys are strings of the application package name (as 442 * returned by the package manager), and the keys are ApplicationRecord 443 * objects. 444 */ 445 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 446 447 /** 448 * Tracking long-term execution of processes to look for abuse and other 449 * bad app behavior. 450 */ 451 final ProcessStatsService mProcessStats; 452 453 /** 454 * The currently running isolated processes. 455 */ 456 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 457 458 /** 459 * Counter for assigning isolated process uids, to avoid frequently reusing the 460 * same ones. 461 */ 462 int mNextIsolatedProcessUid = 0; 463 464 /** 465 * The currently running heavy-weight process, if any. 466 */ 467 ProcessRecord mHeavyWeightProcess = null; 468 469 /** 470 * The last time that various processes have crashed. 471 */ 472 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 473 474 /** 475 * Information about a process that is currently marked as bad. 476 */ 477 static final class BadProcessInfo { 478 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 479 this.time = time; 480 this.shortMsg = shortMsg; 481 this.longMsg = longMsg; 482 this.stack = stack; 483 } 484 485 final long time; 486 final String shortMsg; 487 final String longMsg; 488 final String stack; 489 } 490 491 /** 492 * Set of applications that we consider to be bad, and will reject 493 * incoming broadcasts from (which the user has no control over). 494 * Processes are added to this set when they have crashed twice within 495 * a minimum amount of time; they are removed from it when they are 496 * later restarted (hopefully due to some user action). The value is the 497 * time it was added to the list. 498 */ 499 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 500 501 /** 502 * All of the processes we currently have running organized by pid. 503 * The keys are the pid running the application. 504 * 505 * <p>NOTE: This object is protected by its own lock, NOT the global 506 * activity manager lock! 507 */ 508 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 509 510 /** 511 * All of the processes that have been forced to be foreground. The key 512 * is the pid of the caller who requested it (we hold a death 513 * link on it). 514 */ 515 abstract class ForegroundToken implements IBinder.DeathRecipient { 516 int pid; 517 IBinder token; 518 } 519 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 520 521 /** 522 * List of records for processes that someone had tried to start before the 523 * system was ready. We don't start them at that point, but ensure they 524 * are started by the time booting is complete. 525 */ 526 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 527 528 /** 529 * List of persistent applications that are in the process 530 * of being started. 531 */ 532 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 533 534 /** 535 * Processes that are being forcibly torn down. 536 */ 537 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 538 539 /** 540 * List of running applications, sorted by recent usage. 541 * The first entry in the list is the least recently used. 542 */ 543 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 544 545 /** 546 * Where in mLruProcesses that the processes hosting activities start. 547 */ 548 int mLruProcessActivityStart = 0; 549 550 /** 551 * Where in mLruProcesses that the processes hosting services start. 552 * This is after (lower index) than mLruProcessesActivityStart. 553 */ 554 int mLruProcessServiceStart = 0; 555 556 /** 557 * List of processes that should gc as soon as things are idle. 558 */ 559 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 560 561 /** 562 * Processes we want to collect PSS data from. 563 */ 564 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 565 566 /** 567 * Last time we requested PSS data of all processes. 568 */ 569 long mLastFullPssTime = SystemClock.uptimeMillis(); 570 571 /** 572 * This is the process holding what we currently consider to be 573 * the "home" activity. 574 */ 575 ProcessRecord mHomeProcess; 576 577 /** 578 * This is the process holding the activity the user last visited that 579 * is in a different process from the one they are currently in. 580 */ 581 ProcessRecord mPreviousProcess; 582 583 /** 584 * The time at which the previous process was last visible. 585 */ 586 long mPreviousProcessVisibleTime; 587 588 /** 589 * Which uses have been started, so are allowed to run code. 590 */ 591 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 592 593 /** 594 * LRU list of history of current users. Most recently current is at the end. 595 */ 596 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 597 598 /** 599 * Constant array of the users that are currently started. 600 */ 601 int[] mStartedUserArray = new int[] { 0 }; 602 603 /** 604 * Registered observers of the user switching mechanics. 605 */ 606 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 607 = new RemoteCallbackList<IUserSwitchObserver>(); 608 609 /** 610 * Currently active user switch. 611 */ 612 Object mCurUserSwitchCallback; 613 614 /** 615 * Packages that the user has asked to have run in screen size 616 * compatibility mode instead of filling the screen. 617 */ 618 final CompatModePackages mCompatModePackages; 619 620 /** 621 * Set of IntentSenderRecord objects that are currently active. 622 */ 623 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 624 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 625 626 /** 627 * Fingerprints (hashCode()) of stack traces that we've 628 * already logged DropBox entries for. Guarded by itself. If 629 * something (rogue user app) forces this over 630 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 631 */ 632 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 633 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 634 635 /** 636 * Strict Mode background batched logging state. 637 * 638 * The string buffer is guarded by itself, and its lock is also 639 * used to determine if another batched write is already 640 * in-flight. 641 */ 642 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 643 644 /** 645 * Keeps track of all IIntentReceivers that have been registered for 646 * broadcasts. Hash keys are the receiver IBinder, hash value is 647 * a ReceiverList. 648 */ 649 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 650 new HashMap<IBinder, ReceiverList>(); 651 652 /** 653 * Resolver for broadcast intents to registered receivers. 654 * Holds BroadcastFilter (subclass of IntentFilter). 655 */ 656 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 657 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 658 @Override 659 protected boolean allowFilterResult( 660 BroadcastFilter filter, List<BroadcastFilter> dest) { 661 IBinder target = filter.receiverList.receiver.asBinder(); 662 for (int i=dest.size()-1; i>=0; i--) { 663 if (dest.get(i).receiverList.receiver.asBinder() == target) { 664 return false; 665 } 666 } 667 return true; 668 } 669 670 @Override 671 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 672 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 673 || userId == filter.owningUserId) { 674 return super.newResult(filter, match, userId); 675 } 676 return null; 677 } 678 679 @Override 680 protected BroadcastFilter[] newArray(int size) { 681 return new BroadcastFilter[size]; 682 } 683 684 @Override 685 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 686 return packageName.equals(filter.packageName); 687 } 688 }; 689 690 /** 691 * State of all active sticky broadcasts per user. Keys are the action of the 692 * sticky Intent, values are an ArrayList of all broadcasted intents with 693 * that action (which should usually be one). The SparseArray is keyed 694 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 695 * for stickies that are sent to all users. 696 */ 697 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 698 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 699 700 final ActiveServices mServices; 701 702 /** 703 * Backup/restore process management 704 */ 705 String mBackupAppName = null; 706 BackupRecord mBackupTarget = null; 707 708 final ProviderMap mProviderMap; 709 710 /** 711 * List of content providers who have clients waiting for them. The 712 * application is currently being launched and the provider will be 713 * removed from this list once it is published. 714 */ 715 final ArrayList<ContentProviderRecord> mLaunchingProviders 716 = new ArrayList<ContentProviderRecord>(); 717 718 /** 719 * File storing persisted {@link #mGrantedUriPermissions}. 720 */ 721 private final AtomicFile mGrantFile; 722 723 /** XML constants used in {@link #mGrantFile} */ 724 private static final String TAG_URI_GRANTS = "uri-grants"; 725 private static final String TAG_URI_GRANT = "uri-grant"; 726 private static final String ATTR_USER_HANDLE = "userHandle"; 727 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 728 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 729 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 730 private static final String ATTR_TARGET_PKG = "targetPkg"; 731 private static final String ATTR_URI = "uri"; 732 private static final String ATTR_MODE_FLAGS = "modeFlags"; 733 private static final String ATTR_CREATED_TIME = "createdTime"; 734 private static final String ATTR_PREFIX = "prefix"; 735 736 /** 737 * Global set of specific {@link Uri} permissions that have been granted. 738 * This optimized lookup structure maps from {@link UriPermission#targetUid} 739 * to {@link UriPermission#uri} to {@link UriPermission}. 740 */ 741 @GuardedBy("this") 742 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 743 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 744 745 public static class GrantUri { 746 public final int sourceUserId; 747 public final Uri uri; 748 public boolean prefix; 749 750 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 751 this.sourceUserId = sourceUserId; 752 this.uri = uri; 753 this.prefix = prefix; 754 } 755 756 @Override 757 public int hashCode() { 758 return toString().hashCode(); 759 } 760 761 @Override 762 public boolean equals(Object o) { 763 if (o instanceof GrantUri) { 764 GrantUri other = (GrantUri) o; 765 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 766 && prefix == other.prefix; 767 } 768 return false; 769 } 770 771 @Override 772 public String toString() { 773 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 774 if (prefix) result += " [prefix]"; 775 return result; 776 } 777 778 public String toSafeString() { 779 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 780 if (prefix) result += " [prefix]"; 781 return result; 782 } 783 784 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 785 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 786 ContentProvider.getUriWithoutUserId(uri), false); 787 } 788 } 789 790 CoreSettingsObserver mCoreSettingsObserver; 791 792 /** 793 * Thread-local storage used to carry caller permissions over through 794 * indirect content-provider access. 795 */ 796 private class Identity { 797 public int pid; 798 public int uid; 799 800 Identity(int _pid, int _uid) { 801 pid = _pid; 802 uid = _uid; 803 } 804 } 805 806 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 807 808 /** 809 * All information we have collected about the runtime performance of 810 * any user id that can impact battery performance. 811 */ 812 final BatteryStatsService mBatteryStatsService; 813 814 /** 815 * Information about component usage 816 */ 817 final UsageStatsService mUsageStatsService; 818 819 /** 820 * Information about and control over application operations 821 */ 822 final AppOpsService mAppOpsService; 823 824 /** 825 * Save recent tasks information across reboots. 826 */ 827 final TaskPersister mTaskPersister; 828 829 /** 830 * Current configuration information. HistoryRecord objects are given 831 * a reference to this object to indicate which configuration they are 832 * currently running in, so this object must be kept immutable. 833 */ 834 Configuration mConfiguration = new Configuration(); 835 836 /** 837 * Current sequencing integer of the configuration, for skipping old 838 * configurations. 839 */ 840 int mConfigurationSeq = 0; 841 842 /** 843 * Hardware-reported OpenGLES version. 844 */ 845 final int GL_ES_VERSION; 846 847 /** 848 * List of initialization arguments to pass to all processes when binding applications to them. 849 * For example, references to the commonly used services. 850 */ 851 HashMap<String, IBinder> mAppBindArgs; 852 853 /** 854 * Temporary to avoid allocations. Protected by main lock. 855 */ 856 final StringBuilder mStringBuilder = new StringBuilder(256); 857 858 /** 859 * Used to control how we initialize the service. 860 */ 861 ComponentName mTopComponent; 862 String mTopAction = Intent.ACTION_MAIN; 863 String mTopData; 864 boolean mProcessesReady = false; 865 boolean mSystemReady = false; 866 boolean mBooting = false; 867 boolean mWaitingUpdate = false; 868 boolean mDidUpdate = false; 869 boolean mOnBattery = false; 870 boolean mLaunchWarningShown = false; 871 872 Context mContext; 873 874 int mFactoryTest; 875 876 boolean mCheckedForSetup; 877 878 /** 879 * The time at which we will allow normal application switches again, 880 * after a call to {@link #stopAppSwitches()}. 881 */ 882 long mAppSwitchesAllowedTime; 883 884 /** 885 * This is set to true after the first switch after mAppSwitchesAllowedTime 886 * is set; any switches after that will clear the time. 887 */ 888 boolean mDidAppSwitch; 889 890 /** 891 * Last time (in realtime) at which we checked for power usage. 892 */ 893 long mLastPowerCheckRealtime; 894 895 /** 896 * Last time (in uptime) at which we checked for power usage. 897 */ 898 long mLastPowerCheckUptime; 899 900 /** 901 * Set while we are wanting to sleep, to prevent any 902 * activities from being started/resumed. 903 */ 904 private boolean mSleeping = false; 905 906 /** 907 * Set while we are running a voice interaction. This overrides 908 * sleeping while it is active. 909 */ 910 private boolean mRunningVoice = false; 911 912 /** 913 * State of external calls telling us if the device is asleep. 914 */ 915 private boolean mWentToSleep = false; 916 917 /** 918 * State of external call telling us if the lock screen is shown. 919 */ 920 private boolean mLockScreenShown = false; 921 922 /** 923 * Set if we are shutting down the system, similar to sleeping. 924 */ 925 boolean mShuttingDown = false; 926 927 /** 928 * Current sequence id for oom_adj computation traversal. 929 */ 930 int mAdjSeq = 0; 931 932 /** 933 * Current sequence id for process LRU updating. 934 */ 935 int mLruSeq = 0; 936 937 /** 938 * Keep track of the non-cached/empty process we last found, to help 939 * determine how to distribute cached/empty processes next time. 940 */ 941 int mNumNonCachedProcs = 0; 942 943 /** 944 * Keep track of the number of cached hidden procs, to balance oom adj 945 * distribution between those and empty procs. 946 */ 947 int mNumCachedHiddenProcs = 0; 948 949 /** 950 * Keep track of the number of service processes we last found, to 951 * determine on the next iteration which should be B services. 952 */ 953 int mNumServiceProcs = 0; 954 int mNewNumAServiceProcs = 0; 955 int mNewNumServiceProcs = 0; 956 957 /** 958 * Allow the current computed overall memory level of the system to go down? 959 * This is set to false when we are killing processes for reasons other than 960 * memory management, so that the now smaller process list will not be taken as 961 * an indication that memory is tighter. 962 */ 963 boolean mAllowLowerMemLevel = false; 964 965 /** 966 * The last computed memory level, for holding when we are in a state that 967 * processes are going away for other reasons. 968 */ 969 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 970 971 /** 972 * The last total number of process we have, to determine if changes actually look 973 * like a shrinking number of process due to lower RAM. 974 */ 975 int mLastNumProcesses; 976 977 /** 978 * The uptime of the last time we performed idle maintenance. 979 */ 980 long mLastIdleTime = SystemClock.uptimeMillis(); 981 982 /** 983 * Total time spent with RAM that has been added in the past since the last idle time. 984 */ 985 long mLowRamTimeSinceLastIdle = 0; 986 987 /** 988 * If RAM is currently low, when that horrible situation started. 989 */ 990 long mLowRamStartTime = 0; 991 992 /** 993 * For reporting to battery stats the current top application. 994 */ 995 private String mCurResumedPackage = null; 996 private int mCurResumedUid = -1; 997 998 /** 999 * For reporting to battery stats the apps currently running foreground 1000 * service. The ProcessMap is package/uid tuples; each of these contain 1001 * an array of the currently foreground processes. 1002 */ 1003 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1004 = new ProcessMap<ArrayList<ProcessRecord>>(); 1005 1006 /** 1007 * This is set if we had to do a delayed dexopt of an app before launching 1008 * it, to increase the ANR timeouts in that case. 1009 */ 1010 boolean mDidDexOpt; 1011 1012 /** 1013 * Set if the systemServer made a call to enterSafeMode. 1014 */ 1015 boolean mSafeMode; 1016 1017 String mDebugApp = null; 1018 boolean mWaitForDebugger = false; 1019 boolean mDebugTransient = false; 1020 String mOrigDebugApp = null; 1021 boolean mOrigWaitForDebugger = false; 1022 boolean mAlwaysFinishActivities = false; 1023 IActivityController mController = null; 1024 String mProfileApp = null; 1025 ProcessRecord mProfileProc = null; 1026 String mProfileFile; 1027 ParcelFileDescriptor mProfileFd; 1028 int mProfileType = 0; 1029 boolean mAutoStopProfiler = false; 1030 String mOpenGlTraceApp = null; 1031 1032 static class ProcessChangeItem { 1033 static final int CHANGE_ACTIVITIES = 1<<0; 1034 static final int CHANGE_PROCESS_STATE = 1<<1; 1035 int changes; 1036 int uid; 1037 int pid; 1038 int processState; 1039 boolean foregroundActivities; 1040 } 1041 1042 final RemoteCallbackList<IProcessObserver> mProcessObservers 1043 = new RemoteCallbackList<IProcessObserver>(); 1044 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1045 1046 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1047 = new ArrayList<ProcessChangeItem>(); 1048 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1049 = new ArrayList<ProcessChangeItem>(); 1050 1051 /** 1052 * Runtime CPU use collection thread. This object's lock is used to 1053 * protect all related state. 1054 */ 1055 final Thread mProcessCpuThread; 1056 1057 /** 1058 * Used to collect process stats when showing not responding dialog. 1059 * Protected by mProcessCpuThread. 1060 */ 1061 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1062 MONITOR_THREAD_CPU_USAGE); 1063 final AtomicLong mLastCpuTime = new AtomicLong(0); 1064 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1065 1066 long mLastWriteTime = 0; 1067 1068 /** 1069 * Used to retain an update lock when the foreground activity is in 1070 * immersive mode. 1071 */ 1072 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1073 1074 /** 1075 * Set to true after the system has finished booting. 1076 */ 1077 boolean mBooted = false; 1078 1079 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1080 int mProcessLimitOverride = -1; 1081 1082 WindowManagerService mWindowManager; 1083 1084 final ActivityThread mSystemThread; 1085 1086 int mCurrentUserId = 0; 1087 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1088 private UserManagerService mUserManager; 1089 1090 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1091 final ProcessRecord mApp; 1092 final int mPid; 1093 final IApplicationThread mAppThread; 1094 1095 AppDeathRecipient(ProcessRecord app, int pid, 1096 IApplicationThread thread) { 1097 if (localLOGV) Slog.v( 1098 TAG, "New death recipient " + this 1099 + " for thread " + thread.asBinder()); 1100 mApp = app; 1101 mPid = pid; 1102 mAppThread = thread; 1103 } 1104 1105 @Override 1106 public void binderDied() { 1107 if (localLOGV) Slog.v( 1108 TAG, "Death received in " + this 1109 + " for thread " + mAppThread.asBinder()); 1110 synchronized(ActivityManagerService.this) { 1111 appDiedLocked(mApp, mPid, mAppThread); 1112 } 1113 } 1114 } 1115 1116 static final int SHOW_ERROR_MSG = 1; 1117 static final int SHOW_NOT_RESPONDING_MSG = 2; 1118 static final int SHOW_FACTORY_ERROR_MSG = 3; 1119 static final int UPDATE_CONFIGURATION_MSG = 4; 1120 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1121 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1122 static final int SERVICE_TIMEOUT_MSG = 12; 1123 static final int UPDATE_TIME_ZONE = 13; 1124 static final int SHOW_UID_ERROR_MSG = 14; 1125 static final int IM_FEELING_LUCKY_MSG = 15; 1126 static final int PROC_START_TIMEOUT_MSG = 20; 1127 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1128 static final int KILL_APPLICATION_MSG = 22; 1129 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1130 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1131 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1132 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1133 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1134 static final int CLEAR_DNS_CACHE_MSG = 28; 1135 static final int UPDATE_HTTP_PROXY_MSG = 29; 1136 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1137 static final int DISPATCH_PROCESSES_CHANGED = 31; 1138 static final int DISPATCH_PROCESS_DIED = 32; 1139 static final int REPORT_MEM_USAGE_MSG = 33; 1140 static final int REPORT_USER_SWITCH_MSG = 34; 1141 static final int CONTINUE_USER_SWITCH_MSG = 35; 1142 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1143 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1144 static final int PERSIST_URI_GRANTS_MSG = 38; 1145 static final int REQUEST_ALL_PSS_MSG = 39; 1146 static final int START_PROFILES_MSG = 40; 1147 static final int UPDATE_TIME = 41; 1148 static final int SYSTEM_USER_START_MSG = 42; 1149 static final int SYSTEM_USER_CURRENT_MSG = 43; 1150 1151 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1152 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1153 static final int FIRST_COMPAT_MODE_MSG = 300; 1154 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1155 1156 AlertDialog mUidAlert; 1157 CompatModeDialog mCompatModeDialog; 1158 long mLastMemUsageReportTime = 0; 1159 1160 /** 1161 * Flag whether the current user is a "monkey", i.e. whether 1162 * the UI is driven by a UI automation tool. 1163 */ 1164 private boolean mUserIsMonkey; 1165 1166 final ServiceThread mHandlerThread; 1167 final MainHandler mHandler; 1168 1169 final class MainHandler extends Handler { 1170 public MainHandler(Looper looper) { 1171 super(looper, null, true); 1172 } 1173 1174 @Override 1175 public void handleMessage(Message msg) { 1176 switch (msg.what) { 1177 case SHOW_ERROR_MSG: { 1178 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1179 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1180 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1181 synchronized (ActivityManagerService.this) { 1182 ProcessRecord proc = (ProcessRecord)data.get("app"); 1183 AppErrorResult res = (AppErrorResult) data.get("result"); 1184 if (proc != null && proc.crashDialog != null) { 1185 Slog.e(TAG, "App already has crash dialog: " + proc); 1186 if (res != null) { 1187 res.set(0); 1188 } 1189 return; 1190 } 1191 if (!showBackground && UserHandle.getAppId(proc.uid) 1192 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1193 && proc.pid != MY_PID) { 1194 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1195 if (res != null) { 1196 res.set(0); 1197 } 1198 return; 1199 } 1200 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1201 Dialog d = new AppErrorDialog(mContext, 1202 ActivityManagerService.this, res, proc); 1203 d.show(); 1204 proc.crashDialog = d; 1205 } else { 1206 // The device is asleep, so just pretend that the user 1207 // saw a crash dialog and hit "force quit". 1208 if (res != null) { 1209 res.set(0); 1210 } 1211 } 1212 } 1213 1214 ensureBootCompleted(); 1215 } break; 1216 case SHOW_NOT_RESPONDING_MSG: { 1217 synchronized (ActivityManagerService.this) { 1218 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1219 ProcessRecord proc = (ProcessRecord)data.get("app"); 1220 if (proc != null && proc.anrDialog != null) { 1221 Slog.e(TAG, "App already has anr dialog: " + proc); 1222 return; 1223 } 1224 1225 Intent intent = new Intent("android.intent.action.ANR"); 1226 if (!mProcessesReady) { 1227 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1228 | Intent.FLAG_RECEIVER_FOREGROUND); 1229 } 1230 broadcastIntentLocked(null, null, intent, 1231 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1232 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1233 1234 if (mShowDialogs) { 1235 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1236 mContext, proc, (ActivityRecord)data.get("activity"), 1237 msg.arg1 != 0); 1238 d.show(); 1239 proc.anrDialog = d; 1240 } else { 1241 // Just kill the app if there is no dialog to be shown. 1242 killAppAtUsersRequest(proc, null); 1243 } 1244 } 1245 1246 ensureBootCompleted(); 1247 } break; 1248 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1249 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1250 synchronized (ActivityManagerService.this) { 1251 ProcessRecord proc = (ProcessRecord) data.get("app"); 1252 if (proc == null) { 1253 Slog.e(TAG, "App not found when showing strict mode dialog."); 1254 break; 1255 } 1256 if (proc.crashDialog != null) { 1257 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1258 return; 1259 } 1260 AppErrorResult res = (AppErrorResult) data.get("result"); 1261 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1262 Dialog d = new StrictModeViolationDialog(mContext, 1263 ActivityManagerService.this, res, proc); 1264 d.show(); 1265 proc.crashDialog = d; 1266 } else { 1267 // The device is asleep, so just pretend that the user 1268 // saw a crash dialog and hit "force quit". 1269 res.set(0); 1270 } 1271 } 1272 ensureBootCompleted(); 1273 } break; 1274 case SHOW_FACTORY_ERROR_MSG: { 1275 Dialog d = new FactoryErrorDialog( 1276 mContext, msg.getData().getCharSequence("msg")); 1277 d.show(); 1278 ensureBootCompleted(); 1279 } break; 1280 case UPDATE_CONFIGURATION_MSG: { 1281 final ContentResolver resolver = mContext.getContentResolver(); 1282 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1283 } break; 1284 case GC_BACKGROUND_PROCESSES_MSG: { 1285 synchronized (ActivityManagerService.this) { 1286 performAppGcsIfAppropriateLocked(); 1287 } 1288 } break; 1289 case WAIT_FOR_DEBUGGER_MSG: { 1290 synchronized (ActivityManagerService.this) { 1291 ProcessRecord app = (ProcessRecord)msg.obj; 1292 if (msg.arg1 != 0) { 1293 if (!app.waitedForDebugger) { 1294 Dialog d = new AppWaitingForDebuggerDialog( 1295 ActivityManagerService.this, 1296 mContext, app); 1297 app.waitDialog = d; 1298 app.waitedForDebugger = true; 1299 d.show(); 1300 } 1301 } else { 1302 if (app.waitDialog != null) { 1303 app.waitDialog.dismiss(); 1304 app.waitDialog = null; 1305 } 1306 } 1307 } 1308 } break; 1309 case SERVICE_TIMEOUT_MSG: { 1310 if (mDidDexOpt) { 1311 mDidDexOpt = false; 1312 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1313 nmsg.obj = msg.obj; 1314 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1315 return; 1316 } 1317 mServices.serviceTimeout((ProcessRecord)msg.obj); 1318 } break; 1319 case UPDATE_TIME_ZONE: { 1320 synchronized (ActivityManagerService.this) { 1321 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1322 ProcessRecord r = mLruProcesses.get(i); 1323 if (r.thread != null) { 1324 try { 1325 r.thread.updateTimeZone(); 1326 } catch (RemoteException ex) { 1327 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1328 } 1329 } 1330 } 1331 } 1332 } break; 1333 case CLEAR_DNS_CACHE_MSG: { 1334 synchronized (ActivityManagerService.this) { 1335 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1336 ProcessRecord r = mLruProcesses.get(i); 1337 if (r.thread != null) { 1338 try { 1339 r.thread.clearDnsCache(); 1340 } catch (RemoteException ex) { 1341 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1342 } 1343 } 1344 } 1345 } 1346 } break; 1347 case UPDATE_HTTP_PROXY_MSG: { 1348 ProxyInfo proxy = (ProxyInfo)msg.obj; 1349 String host = ""; 1350 String port = ""; 1351 String exclList = ""; 1352 Uri pacFileUrl = Uri.EMPTY; 1353 if (proxy != null) { 1354 host = proxy.getHost(); 1355 port = Integer.toString(proxy.getPort()); 1356 exclList = proxy.getExclusionListAsString(); 1357 pacFileUrl = proxy.getPacFileUrl(); 1358 } 1359 synchronized (ActivityManagerService.this) { 1360 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1361 ProcessRecord r = mLruProcesses.get(i); 1362 if (r.thread != null) { 1363 try { 1364 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1365 } catch (RemoteException ex) { 1366 Slog.w(TAG, "Failed to update http proxy for: " + 1367 r.info.processName); 1368 } 1369 } 1370 } 1371 } 1372 } break; 1373 case SHOW_UID_ERROR_MSG: { 1374 String title = "System UIDs Inconsistent"; 1375 String text = "UIDs on the system are inconsistent, you need to wipe your" 1376 + " data partition or your device will be unstable."; 1377 Log.e(TAG, title + ": " + text); 1378 if (mShowDialogs) { 1379 // XXX This is a temporary dialog, no need to localize. 1380 AlertDialog d = new BaseErrorDialog(mContext); 1381 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1382 d.setCancelable(false); 1383 d.setTitle(title); 1384 d.setMessage(text); 1385 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1386 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1387 mUidAlert = d; 1388 d.show(); 1389 } 1390 } break; 1391 case IM_FEELING_LUCKY_MSG: { 1392 if (mUidAlert != null) { 1393 mUidAlert.dismiss(); 1394 mUidAlert = null; 1395 } 1396 } break; 1397 case PROC_START_TIMEOUT_MSG: { 1398 if (mDidDexOpt) { 1399 mDidDexOpt = false; 1400 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1401 nmsg.obj = msg.obj; 1402 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1403 return; 1404 } 1405 ProcessRecord app = (ProcessRecord)msg.obj; 1406 synchronized (ActivityManagerService.this) { 1407 processStartTimedOutLocked(app); 1408 } 1409 } break; 1410 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1411 synchronized (ActivityManagerService.this) { 1412 doPendingActivityLaunchesLocked(true); 1413 } 1414 } break; 1415 case KILL_APPLICATION_MSG: { 1416 synchronized (ActivityManagerService.this) { 1417 int appid = msg.arg1; 1418 boolean restart = (msg.arg2 == 1); 1419 Bundle bundle = (Bundle)msg.obj; 1420 String pkg = bundle.getString("pkg"); 1421 String reason = bundle.getString("reason"); 1422 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1423 false, UserHandle.USER_ALL, reason); 1424 } 1425 } break; 1426 case FINALIZE_PENDING_INTENT_MSG: { 1427 ((PendingIntentRecord)msg.obj).completeFinalize(); 1428 } break; 1429 case POST_HEAVY_NOTIFICATION_MSG: { 1430 INotificationManager inm = NotificationManager.getService(); 1431 if (inm == null) { 1432 return; 1433 } 1434 1435 ActivityRecord root = (ActivityRecord)msg.obj; 1436 ProcessRecord process = root.app; 1437 if (process == null) { 1438 return; 1439 } 1440 1441 try { 1442 Context context = mContext.createPackageContext(process.info.packageName, 0); 1443 String text = mContext.getString(R.string.heavy_weight_notification, 1444 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1445 Notification notification = new Notification(); 1446 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1447 notification.when = 0; 1448 notification.flags = Notification.FLAG_ONGOING_EVENT; 1449 notification.tickerText = text; 1450 notification.defaults = 0; // please be quiet 1451 notification.sound = null; 1452 notification.vibrate = null; 1453 notification.setLatestEventInfo(context, text, 1454 mContext.getText(R.string.heavy_weight_notification_detail), 1455 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1456 PendingIntent.FLAG_CANCEL_CURRENT, null, 1457 new UserHandle(root.userId))); 1458 1459 try { 1460 int[] outId = new int[1]; 1461 inm.enqueueNotificationWithTag("android", "android", null, 1462 R.string.heavy_weight_notification, 1463 notification, outId, root.userId); 1464 } catch (RuntimeException e) { 1465 Slog.w(ActivityManagerService.TAG, 1466 "Error showing notification for heavy-weight app", e); 1467 } catch (RemoteException e) { 1468 } 1469 } catch (NameNotFoundException e) { 1470 Slog.w(TAG, "Unable to create context for heavy notification", e); 1471 } 1472 } break; 1473 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1474 INotificationManager inm = NotificationManager.getService(); 1475 if (inm == null) { 1476 return; 1477 } 1478 try { 1479 inm.cancelNotificationWithTag("android", null, 1480 R.string.heavy_weight_notification, msg.arg1); 1481 } catch (RuntimeException e) { 1482 Slog.w(ActivityManagerService.TAG, 1483 "Error canceling notification for service", e); 1484 } catch (RemoteException e) { 1485 } 1486 } break; 1487 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1488 synchronized (ActivityManagerService.this) { 1489 checkExcessivePowerUsageLocked(true); 1490 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1491 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1492 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1493 } 1494 } break; 1495 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1496 synchronized (ActivityManagerService.this) { 1497 ActivityRecord ar = (ActivityRecord)msg.obj; 1498 if (mCompatModeDialog != null) { 1499 if (mCompatModeDialog.mAppInfo.packageName.equals( 1500 ar.info.applicationInfo.packageName)) { 1501 return; 1502 } 1503 mCompatModeDialog.dismiss(); 1504 mCompatModeDialog = null; 1505 } 1506 if (ar != null && false) { 1507 if (mCompatModePackages.getPackageAskCompatModeLocked( 1508 ar.packageName)) { 1509 int mode = mCompatModePackages.computeCompatModeLocked( 1510 ar.info.applicationInfo); 1511 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1512 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1513 mCompatModeDialog = new CompatModeDialog( 1514 ActivityManagerService.this, mContext, 1515 ar.info.applicationInfo); 1516 mCompatModeDialog.show(); 1517 } 1518 } 1519 } 1520 } 1521 break; 1522 } 1523 case DISPATCH_PROCESSES_CHANGED: { 1524 dispatchProcessesChanged(); 1525 break; 1526 } 1527 case DISPATCH_PROCESS_DIED: { 1528 final int pid = msg.arg1; 1529 final int uid = msg.arg2; 1530 dispatchProcessDied(pid, uid); 1531 break; 1532 } 1533 case REPORT_MEM_USAGE_MSG: { 1534 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1535 Thread thread = new Thread() { 1536 @Override public void run() { 1537 final SparseArray<ProcessMemInfo> infoMap 1538 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1539 for (int i=0, N=memInfos.size(); i<N; i++) { 1540 ProcessMemInfo mi = memInfos.get(i); 1541 infoMap.put(mi.pid, mi); 1542 } 1543 updateCpuStatsNow(); 1544 synchronized (mProcessCpuThread) { 1545 final int N = mProcessCpuTracker.countStats(); 1546 for (int i=0; i<N; i++) { 1547 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1548 if (st.vsize > 0) { 1549 long pss = Debug.getPss(st.pid, null); 1550 if (pss > 0) { 1551 if (infoMap.indexOfKey(st.pid) < 0) { 1552 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1553 ProcessList.NATIVE_ADJ, -1, "native", null); 1554 mi.pss = pss; 1555 memInfos.add(mi); 1556 } 1557 } 1558 } 1559 } 1560 } 1561 1562 long totalPss = 0; 1563 for (int i=0, N=memInfos.size(); i<N; i++) { 1564 ProcessMemInfo mi = memInfos.get(i); 1565 if (mi.pss == 0) { 1566 mi.pss = Debug.getPss(mi.pid, null); 1567 } 1568 totalPss += mi.pss; 1569 } 1570 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1571 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1572 if (lhs.oomAdj != rhs.oomAdj) { 1573 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1574 } 1575 if (lhs.pss != rhs.pss) { 1576 return lhs.pss < rhs.pss ? 1 : -1; 1577 } 1578 return 0; 1579 } 1580 }); 1581 1582 StringBuilder tag = new StringBuilder(128); 1583 StringBuilder stack = new StringBuilder(128); 1584 tag.append("Low on memory -- "); 1585 appendMemBucket(tag, totalPss, "total", false); 1586 appendMemBucket(stack, totalPss, "total", true); 1587 1588 StringBuilder logBuilder = new StringBuilder(1024); 1589 logBuilder.append("Low on memory:\n"); 1590 1591 boolean firstLine = true; 1592 int lastOomAdj = Integer.MIN_VALUE; 1593 for (int i=0, N=memInfos.size(); i<N; i++) { 1594 ProcessMemInfo mi = memInfos.get(i); 1595 1596 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1597 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1598 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1599 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1600 if (lastOomAdj != mi.oomAdj) { 1601 lastOomAdj = mi.oomAdj; 1602 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1603 tag.append(" / "); 1604 } 1605 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1606 if (firstLine) { 1607 stack.append(":"); 1608 firstLine = false; 1609 } 1610 stack.append("\n\t at "); 1611 } else { 1612 stack.append("$"); 1613 } 1614 } else { 1615 tag.append(" "); 1616 stack.append("$"); 1617 } 1618 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1619 appendMemBucket(tag, mi.pss, mi.name, false); 1620 } 1621 appendMemBucket(stack, mi.pss, mi.name, true); 1622 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1623 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1624 stack.append("("); 1625 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1626 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1627 stack.append(DUMP_MEM_OOM_LABEL[k]); 1628 stack.append(":"); 1629 stack.append(DUMP_MEM_OOM_ADJ[k]); 1630 } 1631 } 1632 stack.append(")"); 1633 } 1634 } 1635 1636 logBuilder.append(" "); 1637 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1638 logBuilder.append(' '); 1639 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1640 logBuilder.append(' '); 1641 ProcessList.appendRamKb(logBuilder, mi.pss); 1642 logBuilder.append(" kB: "); 1643 logBuilder.append(mi.name); 1644 logBuilder.append(" ("); 1645 logBuilder.append(mi.pid); 1646 logBuilder.append(") "); 1647 logBuilder.append(mi.adjType); 1648 logBuilder.append('\n'); 1649 if (mi.adjReason != null) { 1650 logBuilder.append(" "); 1651 logBuilder.append(mi.adjReason); 1652 logBuilder.append('\n'); 1653 } 1654 } 1655 1656 logBuilder.append(" "); 1657 ProcessList.appendRamKb(logBuilder, totalPss); 1658 logBuilder.append(" kB: TOTAL\n"); 1659 1660 long[] infos = new long[Debug.MEMINFO_COUNT]; 1661 Debug.getMemInfo(infos); 1662 logBuilder.append(" MemInfo: "); 1663 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1664 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1665 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1666 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1667 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1668 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1669 logBuilder.append(" ZRAM: "); 1670 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1671 logBuilder.append(" kB RAM, "); 1672 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1673 logBuilder.append(" kB swap total, "); 1674 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1675 logBuilder.append(" kB swap free\n"); 1676 } 1677 Slog.i(TAG, logBuilder.toString()); 1678 1679 StringBuilder dropBuilder = new StringBuilder(1024); 1680 /* 1681 StringWriter oomSw = new StringWriter(); 1682 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1683 StringWriter catSw = new StringWriter(); 1684 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1685 String[] emptyArgs = new String[] { }; 1686 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1687 oomPw.flush(); 1688 String oomString = oomSw.toString(); 1689 */ 1690 dropBuilder.append(stack); 1691 dropBuilder.append('\n'); 1692 dropBuilder.append('\n'); 1693 dropBuilder.append(logBuilder); 1694 dropBuilder.append('\n'); 1695 /* 1696 dropBuilder.append(oomString); 1697 dropBuilder.append('\n'); 1698 */ 1699 StringWriter catSw = new StringWriter(); 1700 synchronized (ActivityManagerService.this) { 1701 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1702 String[] emptyArgs = new String[] { }; 1703 catPw.println(); 1704 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1705 catPw.println(); 1706 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1707 false, false, null); 1708 catPw.println(); 1709 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1710 catPw.flush(); 1711 } 1712 dropBuilder.append(catSw.toString()); 1713 addErrorToDropBox("lowmem", null, "system_server", null, 1714 null, tag.toString(), dropBuilder.toString(), null, null); 1715 //Slog.i(TAG, "Sent to dropbox:"); 1716 //Slog.i(TAG, dropBuilder.toString()); 1717 synchronized (ActivityManagerService.this) { 1718 long now = SystemClock.uptimeMillis(); 1719 if (mLastMemUsageReportTime < now) { 1720 mLastMemUsageReportTime = now; 1721 } 1722 } 1723 } 1724 }; 1725 thread.start(); 1726 break; 1727 } 1728 case REPORT_USER_SWITCH_MSG: { 1729 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1730 break; 1731 } 1732 case CONTINUE_USER_SWITCH_MSG: { 1733 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1734 break; 1735 } 1736 case USER_SWITCH_TIMEOUT_MSG: { 1737 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1738 break; 1739 } 1740 case IMMERSIVE_MODE_LOCK_MSG: { 1741 final boolean nextState = (msg.arg1 != 0); 1742 if (mUpdateLock.isHeld() != nextState) { 1743 if (DEBUG_IMMERSIVE) { 1744 final ActivityRecord r = (ActivityRecord) msg.obj; 1745 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1746 } 1747 if (nextState) { 1748 mUpdateLock.acquire(); 1749 } else { 1750 mUpdateLock.release(); 1751 } 1752 } 1753 break; 1754 } 1755 case PERSIST_URI_GRANTS_MSG: { 1756 writeGrantedUriPermissions(); 1757 break; 1758 } 1759 case REQUEST_ALL_PSS_MSG: { 1760 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1761 break; 1762 } 1763 case START_PROFILES_MSG: { 1764 synchronized (ActivityManagerService.this) { 1765 startProfilesLocked(); 1766 } 1767 break; 1768 } 1769 case UPDATE_TIME: { 1770 synchronized (ActivityManagerService.this) { 1771 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1772 ProcessRecord r = mLruProcesses.get(i); 1773 if (r.thread != null) { 1774 try { 1775 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1776 } catch (RemoteException ex) { 1777 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1778 } 1779 } 1780 } 1781 } 1782 break; 1783 } 1784 case SYSTEM_USER_START_MSG: { 1785 mSystemServiceManager.startUser(msg.arg1); 1786 break; 1787 } 1788 case SYSTEM_USER_CURRENT_MSG: { 1789 mSystemServiceManager.switchUser(msg.arg1); 1790 break; 1791 } 1792 } 1793 } 1794 }; 1795 1796 static final int COLLECT_PSS_BG_MSG = 1; 1797 1798 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1799 @Override 1800 public void handleMessage(Message msg) { 1801 switch (msg.what) { 1802 case COLLECT_PSS_BG_MSG: { 1803 int i=0, num=0; 1804 long start = SystemClock.uptimeMillis(); 1805 long[] tmp = new long[1]; 1806 do { 1807 ProcessRecord proc; 1808 int procState; 1809 int pid; 1810 synchronized (ActivityManagerService.this) { 1811 if (i >= mPendingPssProcesses.size()) { 1812 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1813 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1814 mPendingPssProcesses.clear(); 1815 return; 1816 } 1817 proc = mPendingPssProcesses.get(i); 1818 procState = proc.pssProcState; 1819 if (proc.thread != null && procState == proc.setProcState) { 1820 pid = proc.pid; 1821 } else { 1822 proc = null; 1823 pid = 0; 1824 } 1825 i++; 1826 } 1827 if (proc != null) { 1828 long pss = Debug.getPss(pid, tmp); 1829 synchronized (ActivityManagerService.this) { 1830 if (proc.thread != null && proc.setProcState == procState 1831 && proc.pid == pid) { 1832 num++; 1833 proc.lastPssTime = SystemClock.uptimeMillis(); 1834 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1835 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1836 + ": " + pss + " lastPss=" + proc.lastPss 1837 + " state=" + ProcessList.makeProcStateString(procState)); 1838 if (proc.initialIdlePss == 0) { 1839 proc.initialIdlePss = pss; 1840 } 1841 proc.lastPss = pss; 1842 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1843 proc.lastCachedPss = pss; 1844 } 1845 } 1846 } 1847 } 1848 } while (true); 1849 } 1850 } 1851 } 1852 }; 1853 1854 /** 1855 * Monitor for package changes and update our internal state. 1856 */ 1857 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1858 @Override 1859 public void onPackageRemoved(String packageName, int uid) { 1860 // Remove all tasks with activities in the specified package from the list of recent tasks 1861 synchronized (ActivityManagerService.this) { 1862 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1863 TaskRecord tr = mRecentTasks.get(i); 1864 ComponentName cn = tr.intent.getComponent(); 1865 if (cn != null && cn.getPackageName().equals(packageName)) { 1866 // If the package name matches, remove the task and kill the process 1867 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1868 } 1869 } 1870 } 1871 } 1872 1873 @Override 1874 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1875 onPackageModified(packageName); 1876 return true; 1877 } 1878 1879 @Override 1880 public void onPackageModified(String packageName) { 1881 final PackageManager pm = mContext.getPackageManager(); 1882 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1883 new ArrayList<Pair<Intent, Integer>>(); 1884 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1885 // Copy the list of recent tasks so that we don't hold onto the lock on 1886 // ActivityManagerService for long periods while checking if components exist. 1887 synchronized (ActivityManagerService.this) { 1888 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1889 TaskRecord tr = mRecentTasks.get(i); 1890 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1891 } 1892 } 1893 // Check the recent tasks and filter out all tasks with components that no longer exist. 1894 Intent tmpI = new Intent(); 1895 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1896 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1897 ComponentName cn = p.first.getComponent(); 1898 if (cn != null && cn.getPackageName().equals(packageName)) { 1899 try { 1900 // Add the task to the list to remove if the component no longer exists 1901 tmpI.setComponent(cn); 1902 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1903 tasksToRemove.add(p.second); 1904 } 1905 } catch (Exception e) {} 1906 } 1907 } 1908 // Prune all the tasks with removed components from the list of recent tasks 1909 synchronized (ActivityManagerService.this) { 1910 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1911 // Remove the task but don't kill the process (since other components in that 1912 // package may still be running and in the background) 1913 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1914 } 1915 } 1916 } 1917 1918 @Override 1919 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1920 // Force stop the specified packages 1921 if (packages != null) { 1922 for (String pkg : packages) { 1923 synchronized (ActivityManagerService.this) { 1924 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1925 "finished booting")) { 1926 return true; 1927 } 1928 } 1929 } 1930 } 1931 return false; 1932 } 1933 }; 1934 1935 public void setSystemProcess() { 1936 try { 1937 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1938 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1939 ServiceManager.addService("meminfo", new MemBinder(this)); 1940 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1941 ServiceManager.addService("dbinfo", new DbBinder(this)); 1942 if (MONITOR_CPU_USAGE) { 1943 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1944 } 1945 ServiceManager.addService("permission", new PermissionController(this)); 1946 1947 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1948 "android", STOCK_PM_FLAGS); 1949 mSystemThread.installSystemApplicationInfo(info); 1950 1951 synchronized (this) { 1952 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1953 app.persistent = true; 1954 app.pid = MY_PID; 1955 app.maxAdj = ProcessList.SYSTEM_ADJ; 1956 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1957 mProcessNames.put(app.processName, app.uid, app); 1958 synchronized (mPidsSelfLocked) { 1959 mPidsSelfLocked.put(app.pid, app); 1960 } 1961 updateLruProcessLocked(app, false, null); 1962 updateOomAdjLocked(); 1963 } 1964 } catch (PackageManager.NameNotFoundException e) { 1965 throw new RuntimeException( 1966 "Unable to find android system package", e); 1967 } 1968 } 1969 1970 public void setWindowManager(WindowManagerService wm) { 1971 mWindowManager = wm; 1972 mStackSupervisor.setWindowManager(wm); 1973 } 1974 1975 public void startObservingNativeCrashes() { 1976 final NativeCrashListener ncl = new NativeCrashListener(this); 1977 ncl.start(); 1978 } 1979 1980 public IAppOpsService getAppOpsService() { 1981 return mAppOpsService; 1982 } 1983 1984 static class MemBinder extends Binder { 1985 ActivityManagerService mActivityManagerService; 1986 MemBinder(ActivityManagerService activityManagerService) { 1987 mActivityManagerService = activityManagerService; 1988 } 1989 1990 @Override 1991 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1992 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1993 != PackageManager.PERMISSION_GRANTED) { 1994 pw.println("Permission Denial: can't dump meminfo from from pid=" 1995 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1996 + " without permission " + android.Manifest.permission.DUMP); 1997 return; 1998 } 1999 2000 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2001 } 2002 } 2003 2004 static class GraphicsBinder extends Binder { 2005 ActivityManagerService mActivityManagerService; 2006 GraphicsBinder(ActivityManagerService activityManagerService) { 2007 mActivityManagerService = activityManagerService; 2008 } 2009 2010 @Override 2011 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2012 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2013 != PackageManager.PERMISSION_GRANTED) { 2014 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2015 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2016 + " without permission " + android.Manifest.permission.DUMP); 2017 return; 2018 } 2019 2020 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2021 } 2022 } 2023 2024 static class DbBinder extends Binder { 2025 ActivityManagerService mActivityManagerService; 2026 DbBinder(ActivityManagerService activityManagerService) { 2027 mActivityManagerService = activityManagerService; 2028 } 2029 2030 @Override 2031 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2032 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2033 != PackageManager.PERMISSION_GRANTED) { 2034 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2035 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2036 + " without permission " + android.Manifest.permission.DUMP); 2037 return; 2038 } 2039 2040 mActivityManagerService.dumpDbInfo(fd, pw, args); 2041 } 2042 } 2043 2044 static class CpuBinder extends Binder { 2045 ActivityManagerService mActivityManagerService; 2046 CpuBinder(ActivityManagerService activityManagerService) { 2047 mActivityManagerService = activityManagerService; 2048 } 2049 2050 @Override 2051 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2052 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2053 != PackageManager.PERMISSION_GRANTED) { 2054 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2055 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2056 + " without permission " + android.Manifest.permission.DUMP); 2057 return; 2058 } 2059 2060 synchronized (mActivityManagerService.mProcessCpuThread) { 2061 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2062 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2063 SystemClock.uptimeMillis())); 2064 } 2065 } 2066 } 2067 2068 public static final class Lifecycle extends SystemService { 2069 private final ActivityManagerService mService; 2070 2071 public Lifecycle(Context context) { 2072 super(context); 2073 mService = new ActivityManagerService(context); 2074 } 2075 2076 @Override 2077 public void onStart() { 2078 mService.start(); 2079 } 2080 2081 public ActivityManagerService getService() { 2082 return mService; 2083 } 2084 } 2085 2086 // Note: This method is invoked on the main thread but may need to attach various 2087 // handlers to other threads. So take care to be explicit about the looper. 2088 public ActivityManagerService(Context systemContext) { 2089 mContext = systemContext; 2090 mFactoryTest = FactoryTest.getMode(); 2091 mSystemThread = ActivityThread.currentActivityThread(); 2092 2093 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2094 2095 mHandlerThread = new ServiceThread(TAG, 2096 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2097 mHandlerThread.start(); 2098 mHandler = new MainHandler(mHandlerThread.getLooper()); 2099 2100 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2101 "foreground", BROADCAST_FG_TIMEOUT, false); 2102 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2103 "background", BROADCAST_BG_TIMEOUT, true); 2104 mBroadcastQueues[0] = mFgBroadcastQueue; 2105 mBroadcastQueues[1] = mBgBroadcastQueue; 2106 2107 mServices = new ActiveServices(this); 2108 mProviderMap = new ProviderMap(this); 2109 2110 // TODO: Move creation of battery stats service outside of activity manager service. 2111 File dataDir = Environment.getDataDirectory(); 2112 File systemDir = new File(dataDir, "system"); 2113 systemDir.mkdirs(); 2114 mBatteryStatsService = new BatteryStatsService(new File( 2115 systemDir, "batterystats.bin").toString(), mHandler); 2116 mBatteryStatsService.getActiveStatistics().readLocked(); 2117 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2118 mOnBattery = DEBUG_POWER ? true 2119 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2120 mBatteryStatsService.getActiveStatistics().setCallback(this); 2121 2122 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2123 2124 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2125 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2126 2127 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2128 2129 // User 0 is the first and only user that runs at boot. 2130 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2131 mUserLru.add(Integer.valueOf(0)); 2132 updateStartedUserArrayLocked(); 2133 2134 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2135 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2136 2137 mConfiguration.setToDefaults(); 2138 mConfiguration.setLocale(Locale.getDefault()); 2139 2140 mConfigurationSeq = mConfiguration.seq = 1; 2141 mProcessCpuTracker.init(); 2142 2143 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2144 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2145 mStackSupervisor = new ActivityStackSupervisor(this); 2146 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2147 2148 mProcessCpuThread = new Thread("CpuTracker") { 2149 @Override 2150 public void run() { 2151 while (true) { 2152 try { 2153 try { 2154 synchronized(this) { 2155 final long now = SystemClock.uptimeMillis(); 2156 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2157 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2158 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2159 // + ", write delay=" + nextWriteDelay); 2160 if (nextWriteDelay < nextCpuDelay) { 2161 nextCpuDelay = nextWriteDelay; 2162 } 2163 if (nextCpuDelay > 0) { 2164 mProcessCpuMutexFree.set(true); 2165 this.wait(nextCpuDelay); 2166 } 2167 } 2168 } catch (InterruptedException e) { 2169 } 2170 updateCpuStatsNow(); 2171 } catch (Exception e) { 2172 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2173 } 2174 } 2175 } 2176 }; 2177 2178 Watchdog.getInstance().addMonitor(this); 2179 Watchdog.getInstance().addThread(mHandler); 2180 } 2181 2182 public void setSystemServiceManager(SystemServiceManager mgr) { 2183 mSystemServiceManager = mgr; 2184 } 2185 2186 private void start() { 2187 mProcessCpuThread.start(); 2188 2189 mBatteryStatsService.publish(mContext); 2190 mUsageStatsService.publish(mContext); 2191 mAppOpsService.publish(mContext); 2192 2193 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2194 } 2195 2196 @Override 2197 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2198 throws RemoteException { 2199 if (code == SYSPROPS_TRANSACTION) { 2200 // We need to tell all apps about the system property change. 2201 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2202 synchronized(this) { 2203 final int NP = mProcessNames.getMap().size(); 2204 for (int ip=0; ip<NP; ip++) { 2205 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2206 final int NA = apps.size(); 2207 for (int ia=0; ia<NA; ia++) { 2208 ProcessRecord app = apps.valueAt(ia); 2209 if (app.thread != null) { 2210 procs.add(app.thread.asBinder()); 2211 } 2212 } 2213 } 2214 } 2215 2216 int N = procs.size(); 2217 for (int i=0; i<N; i++) { 2218 Parcel data2 = Parcel.obtain(); 2219 try { 2220 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2221 } catch (RemoteException e) { 2222 } 2223 data2.recycle(); 2224 } 2225 } 2226 try { 2227 return super.onTransact(code, data, reply, flags); 2228 } catch (RuntimeException e) { 2229 // The activity manager only throws security exceptions, so let's 2230 // log all others. 2231 if (!(e instanceof SecurityException)) { 2232 Slog.wtf(TAG, "Activity Manager Crash", e); 2233 } 2234 throw e; 2235 } 2236 } 2237 2238 void updateCpuStats() { 2239 final long now = SystemClock.uptimeMillis(); 2240 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2241 return; 2242 } 2243 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2244 synchronized (mProcessCpuThread) { 2245 mProcessCpuThread.notify(); 2246 } 2247 } 2248 } 2249 2250 void updateCpuStatsNow() { 2251 synchronized (mProcessCpuThread) { 2252 mProcessCpuMutexFree.set(false); 2253 final long now = SystemClock.uptimeMillis(); 2254 boolean haveNewCpuStats = false; 2255 2256 if (MONITOR_CPU_USAGE && 2257 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2258 mLastCpuTime.set(now); 2259 haveNewCpuStats = true; 2260 mProcessCpuTracker.update(); 2261 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2262 //Slog.i(TAG, "Total CPU usage: " 2263 // + mProcessCpu.getTotalCpuPercent() + "%"); 2264 2265 // Slog the cpu usage if the property is set. 2266 if ("true".equals(SystemProperties.get("events.cpu"))) { 2267 int user = mProcessCpuTracker.getLastUserTime(); 2268 int system = mProcessCpuTracker.getLastSystemTime(); 2269 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2270 int irq = mProcessCpuTracker.getLastIrqTime(); 2271 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2272 int idle = mProcessCpuTracker.getLastIdleTime(); 2273 2274 int total = user + system + iowait + irq + softIrq + idle; 2275 if (total == 0) total = 1; 2276 2277 EventLog.writeEvent(EventLogTags.CPU, 2278 ((user+system+iowait+irq+softIrq) * 100) / total, 2279 (user * 100) / total, 2280 (system * 100) / total, 2281 (iowait * 100) / total, 2282 (irq * 100) / total, 2283 (softIrq * 100) / total); 2284 } 2285 } 2286 2287 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2288 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2289 synchronized(bstats) { 2290 synchronized(mPidsSelfLocked) { 2291 if (haveNewCpuStats) { 2292 if (mOnBattery) { 2293 int perc = bstats.startAddingCpuLocked(); 2294 int totalUTime = 0; 2295 int totalSTime = 0; 2296 final int N = mProcessCpuTracker.countStats(); 2297 for (int i=0; i<N; i++) { 2298 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2299 if (!st.working) { 2300 continue; 2301 } 2302 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2303 int otherUTime = (st.rel_utime*perc)/100; 2304 int otherSTime = (st.rel_stime*perc)/100; 2305 totalUTime += otherUTime; 2306 totalSTime += otherSTime; 2307 if (pr != null) { 2308 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2309 if (ps == null || !ps.isActive()) { 2310 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2311 pr.info.uid, pr.processName); 2312 } 2313 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2314 st.rel_stime-otherSTime); 2315 ps.addSpeedStepTimes(cpuSpeedTimes); 2316 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2317 } else { 2318 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2319 if (ps == null || !ps.isActive()) { 2320 st.batteryStats = ps = bstats.getProcessStatsLocked( 2321 bstats.mapUid(st.uid), st.name); 2322 } 2323 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2324 st.rel_stime-otherSTime); 2325 ps.addSpeedStepTimes(cpuSpeedTimes); 2326 } 2327 } 2328 bstats.finishAddingCpuLocked(perc, totalUTime, 2329 totalSTime, cpuSpeedTimes); 2330 } 2331 } 2332 } 2333 2334 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2335 mLastWriteTime = now; 2336 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2337 } 2338 } 2339 } 2340 } 2341 2342 @Override 2343 public void batteryNeedsCpuUpdate() { 2344 updateCpuStatsNow(); 2345 } 2346 2347 @Override 2348 public void batteryPowerChanged(boolean onBattery) { 2349 // When plugging in, update the CPU stats first before changing 2350 // the plug state. 2351 updateCpuStatsNow(); 2352 synchronized (this) { 2353 synchronized(mPidsSelfLocked) { 2354 mOnBattery = DEBUG_POWER ? true : onBattery; 2355 } 2356 } 2357 } 2358 2359 /** 2360 * Initialize the application bind args. These are passed to each 2361 * process when the bindApplication() IPC is sent to the process. They're 2362 * lazily setup to make sure the services are running when they're asked for. 2363 */ 2364 private HashMap<String, IBinder> getCommonServicesLocked() { 2365 if (mAppBindArgs == null) { 2366 mAppBindArgs = new HashMap<String, IBinder>(); 2367 2368 // Setup the application init args 2369 mAppBindArgs.put("package", ServiceManager.getService("package")); 2370 mAppBindArgs.put("window", ServiceManager.getService("window")); 2371 mAppBindArgs.put(Context.ALARM_SERVICE, 2372 ServiceManager.getService(Context.ALARM_SERVICE)); 2373 } 2374 return mAppBindArgs; 2375 } 2376 2377 final void setFocusedActivityLocked(ActivityRecord r) { 2378 if (mFocusedActivity != r) { 2379 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2380 mFocusedActivity = r; 2381 if (r.task != null && r.task.voiceInteractor != null) { 2382 startRunningVoiceLocked(); 2383 } else { 2384 finishRunningVoiceLocked(); 2385 } 2386 mStackSupervisor.setFocusedStack(r); 2387 if (r != null) { 2388 mWindowManager.setFocusedApp(r.appToken, true); 2389 } 2390 applyUpdateLockStateLocked(r); 2391 } 2392 } 2393 2394 final void clearFocusedActivity(ActivityRecord r) { 2395 if (mFocusedActivity == r) { 2396 mFocusedActivity = null; 2397 } 2398 } 2399 2400 @Override 2401 public void setFocusedStack(int stackId) { 2402 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2403 synchronized (ActivityManagerService.this) { 2404 ActivityStack stack = mStackSupervisor.getStack(stackId); 2405 if (stack != null) { 2406 ActivityRecord r = stack.topRunningActivityLocked(null); 2407 if (r != null) { 2408 setFocusedActivityLocked(r); 2409 } 2410 } 2411 } 2412 } 2413 2414 @Override 2415 public void notifyActivityDrawn(IBinder token) { 2416 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2417 synchronized (this) { 2418 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2419 if (r != null) { 2420 r.task.stack.notifyActivityDrawnLocked(r); 2421 } 2422 } 2423 } 2424 2425 final void applyUpdateLockStateLocked(ActivityRecord r) { 2426 // Modifications to the UpdateLock state are done on our handler, outside 2427 // the activity manager's locks. The new state is determined based on the 2428 // state *now* of the relevant activity record. The object is passed to 2429 // the handler solely for logging detail, not to be consulted/modified. 2430 final boolean nextState = r != null && r.immersive; 2431 mHandler.sendMessage( 2432 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2433 } 2434 2435 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2436 Message msg = Message.obtain(); 2437 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2438 msg.obj = r.task.askedCompatMode ? null : r; 2439 mHandler.sendMessage(msg); 2440 } 2441 2442 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2443 String what, Object obj, ProcessRecord srcApp) { 2444 app.lastActivityTime = now; 2445 2446 if (app.activities.size() > 0) { 2447 // Don't want to touch dependent processes that are hosting activities. 2448 return index; 2449 } 2450 2451 int lrui = mLruProcesses.lastIndexOf(app); 2452 if (lrui < 0) { 2453 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2454 + what + " " + obj + " from " + srcApp); 2455 return index; 2456 } 2457 2458 if (lrui >= index) { 2459 // Don't want to cause this to move dependent processes *back* in the 2460 // list as if they were less frequently used. 2461 return index; 2462 } 2463 2464 if (lrui >= mLruProcessActivityStart) { 2465 // Don't want to touch dependent processes that are hosting activities. 2466 return index; 2467 } 2468 2469 mLruProcesses.remove(lrui); 2470 if (index > 0) { 2471 index--; 2472 } 2473 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2474 + " in LRU list: " + app); 2475 mLruProcesses.add(index, app); 2476 return index; 2477 } 2478 2479 final void removeLruProcessLocked(ProcessRecord app) { 2480 int lrui = mLruProcesses.lastIndexOf(app); 2481 if (lrui >= 0) { 2482 if (lrui <= mLruProcessActivityStart) { 2483 mLruProcessActivityStart--; 2484 } 2485 if (lrui <= mLruProcessServiceStart) { 2486 mLruProcessServiceStart--; 2487 } 2488 mLruProcesses.remove(lrui); 2489 } 2490 } 2491 2492 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2493 ProcessRecord client) { 2494 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2495 || app.treatLikeActivity; 2496 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2497 if (!activityChange && hasActivity) { 2498 // The process has activities, so we are only allowing activity-based adjustments 2499 // to move it. It should be kept in the front of the list with other 2500 // processes that have activities, and we don't want those to change their 2501 // order except due to activity operations. 2502 return; 2503 } 2504 2505 mLruSeq++; 2506 final long now = SystemClock.uptimeMillis(); 2507 app.lastActivityTime = now; 2508 2509 // First a quick reject: if the app is already at the position we will 2510 // put it, then there is nothing to do. 2511 if (hasActivity) { 2512 final int N = mLruProcesses.size(); 2513 if (N > 0 && mLruProcesses.get(N-1) == app) { 2514 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2515 return; 2516 } 2517 } else { 2518 if (mLruProcessServiceStart > 0 2519 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2520 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2521 return; 2522 } 2523 } 2524 2525 int lrui = mLruProcesses.lastIndexOf(app); 2526 2527 if (app.persistent && lrui >= 0) { 2528 // We don't care about the position of persistent processes, as long as 2529 // they are in the list. 2530 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2531 return; 2532 } 2533 2534 /* In progress: compute new position first, so we can avoid doing work 2535 if the process is not actually going to move. Not yet working. 2536 int addIndex; 2537 int nextIndex; 2538 boolean inActivity = false, inService = false; 2539 if (hasActivity) { 2540 // Process has activities, put it at the very tipsy-top. 2541 addIndex = mLruProcesses.size(); 2542 nextIndex = mLruProcessServiceStart; 2543 inActivity = true; 2544 } else if (hasService) { 2545 // Process has services, put it at the top of the service list. 2546 addIndex = mLruProcessActivityStart; 2547 nextIndex = mLruProcessServiceStart; 2548 inActivity = true; 2549 inService = true; 2550 } else { 2551 // Process not otherwise of interest, it goes to the top of the non-service area. 2552 addIndex = mLruProcessServiceStart; 2553 if (client != null) { 2554 int clientIndex = mLruProcesses.lastIndexOf(client); 2555 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2556 + app); 2557 if (clientIndex >= 0 && addIndex > clientIndex) { 2558 addIndex = clientIndex; 2559 } 2560 } 2561 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2562 } 2563 2564 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2565 + mLruProcessActivityStart + "): " + app); 2566 */ 2567 2568 if (lrui >= 0) { 2569 if (lrui < mLruProcessActivityStart) { 2570 mLruProcessActivityStart--; 2571 } 2572 if (lrui < mLruProcessServiceStart) { 2573 mLruProcessServiceStart--; 2574 } 2575 /* 2576 if (addIndex > lrui) { 2577 addIndex--; 2578 } 2579 if (nextIndex > lrui) { 2580 nextIndex--; 2581 } 2582 */ 2583 mLruProcesses.remove(lrui); 2584 } 2585 2586 /* 2587 mLruProcesses.add(addIndex, app); 2588 if (inActivity) { 2589 mLruProcessActivityStart++; 2590 } 2591 if (inService) { 2592 mLruProcessActivityStart++; 2593 } 2594 */ 2595 2596 int nextIndex; 2597 if (hasActivity) { 2598 final int N = mLruProcesses.size(); 2599 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2600 // Process doesn't have activities, but has clients with 2601 // activities... move it up, but one below the top (the top 2602 // should always have a real activity). 2603 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2604 mLruProcesses.add(N-1, app); 2605 // To keep it from spamming the LRU list (by making a bunch of clients), 2606 // we will push down any other entries owned by the app. 2607 final int uid = app.info.uid; 2608 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2609 ProcessRecord subProc = mLruProcesses.get(i); 2610 if (subProc.info.uid == uid) { 2611 // We want to push this one down the list. If the process after 2612 // it is for the same uid, however, don't do so, because we don't 2613 // want them internally to be re-ordered. 2614 if (mLruProcesses.get(i-1).info.uid != uid) { 2615 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2616 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2617 ProcessRecord tmp = mLruProcesses.get(i); 2618 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2619 mLruProcesses.set(i-1, tmp); 2620 i--; 2621 } 2622 } else { 2623 // A gap, we can stop here. 2624 break; 2625 } 2626 } 2627 } else { 2628 // Process has activities, put it at the very tipsy-top. 2629 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2630 mLruProcesses.add(app); 2631 } 2632 nextIndex = mLruProcessServiceStart; 2633 } else if (hasService) { 2634 // Process has services, put it at the top of the service list. 2635 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2636 mLruProcesses.add(mLruProcessActivityStart, app); 2637 nextIndex = mLruProcessServiceStart; 2638 mLruProcessActivityStart++; 2639 } else { 2640 // Process not otherwise of interest, it goes to the top of the non-service area. 2641 int index = mLruProcessServiceStart; 2642 if (client != null) { 2643 // If there is a client, don't allow the process to be moved up higher 2644 // in the list than that client. 2645 int clientIndex = mLruProcesses.lastIndexOf(client); 2646 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2647 + " when updating " + app); 2648 if (clientIndex <= lrui) { 2649 // Don't allow the client index restriction to push it down farther in the 2650 // list than it already is. 2651 clientIndex = lrui; 2652 } 2653 if (clientIndex >= 0 && index > clientIndex) { 2654 index = clientIndex; 2655 } 2656 } 2657 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2658 mLruProcesses.add(index, app); 2659 nextIndex = index-1; 2660 mLruProcessActivityStart++; 2661 mLruProcessServiceStart++; 2662 } 2663 2664 // If the app is currently using a content provider or service, 2665 // bump those processes as well. 2666 for (int j=app.connections.size()-1; j>=0; j--) { 2667 ConnectionRecord cr = app.connections.valueAt(j); 2668 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2669 && cr.binding.service.app != null 2670 && cr.binding.service.app.lruSeq != mLruSeq 2671 && !cr.binding.service.app.persistent) { 2672 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2673 "service connection", cr, app); 2674 } 2675 } 2676 for (int j=app.conProviders.size()-1; j>=0; j--) { 2677 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2678 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2679 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2680 "provider reference", cpr, app); 2681 } 2682 } 2683 } 2684 2685 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2686 if (uid == Process.SYSTEM_UID) { 2687 // The system gets to run in any process. If there are multiple 2688 // processes with the same uid, just pick the first (this 2689 // should never happen). 2690 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2691 if (procs == null) return null; 2692 final int N = procs.size(); 2693 for (int i = 0; i < N; i++) { 2694 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2695 } 2696 } 2697 ProcessRecord proc = mProcessNames.get(processName, uid); 2698 if (false && proc != null && !keepIfLarge 2699 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2700 && proc.lastCachedPss >= 4000) { 2701 // Turn this condition on to cause killing to happen regularly, for testing. 2702 if (proc.baseProcessTracker != null) { 2703 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2704 } 2705 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2706 + "k from cached"); 2707 } else if (proc != null && !keepIfLarge 2708 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2709 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2710 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2711 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2712 if (proc.baseProcessTracker != null) { 2713 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2714 } 2715 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2716 + "k from cached"); 2717 } 2718 } 2719 return proc; 2720 } 2721 2722 void ensurePackageDexOpt(String packageName) { 2723 IPackageManager pm = AppGlobals.getPackageManager(); 2724 try { 2725 if (pm.performDexOpt(packageName)) { 2726 mDidDexOpt = true; 2727 } 2728 } catch (RemoteException e) { 2729 } 2730 } 2731 2732 boolean isNextTransitionForward() { 2733 int transit = mWindowManager.getPendingAppTransition(); 2734 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2735 || transit == AppTransition.TRANSIT_TASK_OPEN 2736 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2737 } 2738 2739 final ProcessRecord startProcessLocked(String processName, 2740 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2741 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2742 boolean isolated, boolean keepIfLarge) { 2743 ProcessRecord app; 2744 if (!isolated) { 2745 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2746 } else { 2747 // If this is an isolated process, it can't re-use an existing process. 2748 app = null; 2749 } 2750 // We don't have to do anything more if: 2751 // (1) There is an existing application record; and 2752 // (2) The caller doesn't think it is dead, OR there is no thread 2753 // object attached to it so we know it couldn't have crashed; and 2754 // (3) There is a pid assigned to it, so it is either starting or 2755 // already running. 2756 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2757 + " app=" + app + " knownToBeDead=" + knownToBeDead 2758 + " thread=" + (app != null ? app.thread : null) 2759 + " pid=" + (app != null ? app.pid : -1)); 2760 if (app != null && app.pid > 0) { 2761 if (!knownToBeDead || app.thread == null) { 2762 // We already have the app running, or are waiting for it to 2763 // come up (we have a pid but not yet its thread), so keep it. 2764 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2765 // If this is a new package in the process, add the package to the list 2766 app.addPackage(info.packageName, mProcessStats); 2767 return app; 2768 } 2769 2770 // An application record is attached to a previous process, 2771 // clean it up now. 2772 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2773 handleAppDiedLocked(app, true, true); 2774 } 2775 2776 String hostingNameStr = hostingName != null 2777 ? hostingName.flattenToShortString() : null; 2778 2779 if (!isolated) { 2780 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2781 // If we are in the background, then check to see if this process 2782 // is bad. If so, we will just silently fail. 2783 if (mBadProcesses.get(info.processName, info.uid) != null) { 2784 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2785 + "/" + info.processName); 2786 return null; 2787 } 2788 } else { 2789 // When the user is explicitly starting a process, then clear its 2790 // crash count so that we won't make it bad until they see at 2791 // least one crash dialog again, and make the process good again 2792 // if it had been bad. 2793 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2794 + "/" + info.processName); 2795 mProcessCrashTimes.remove(info.processName, info.uid); 2796 if (mBadProcesses.get(info.processName, info.uid) != null) { 2797 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2798 UserHandle.getUserId(info.uid), info.uid, 2799 info.processName); 2800 mBadProcesses.remove(info.processName, info.uid); 2801 if (app != null) { 2802 app.bad = false; 2803 } 2804 } 2805 } 2806 } 2807 2808 if (app == null) { 2809 app = newProcessRecordLocked(info, processName, isolated); 2810 if (app == null) { 2811 Slog.w(TAG, "Failed making new process record for " 2812 + processName + "/" + info.uid + " isolated=" + isolated); 2813 return null; 2814 } 2815 mProcessNames.put(processName, app.uid, app); 2816 if (isolated) { 2817 mIsolatedProcesses.put(app.uid, app); 2818 } 2819 } else { 2820 // If this is a new package in the process, add the package to the list 2821 app.addPackage(info.packageName, mProcessStats); 2822 } 2823 2824 // If the system is not ready yet, then hold off on starting this 2825 // process until it is. 2826 if (!mProcessesReady 2827 && !isAllowedWhileBooting(info) 2828 && !allowWhileBooting) { 2829 if (!mProcessesOnHold.contains(app)) { 2830 mProcessesOnHold.add(app); 2831 } 2832 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2833 return app; 2834 } 2835 2836 startProcessLocked(app, hostingType, hostingNameStr); 2837 return (app.pid != 0) ? app : null; 2838 } 2839 2840 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2841 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2842 } 2843 2844 private final void startProcessLocked(ProcessRecord app, 2845 String hostingType, String hostingNameStr) { 2846 if (app.pid > 0 && app.pid != MY_PID) { 2847 synchronized (mPidsSelfLocked) { 2848 mPidsSelfLocked.remove(app.pid); 2849 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2850 } 2851 app.setPid(0); 2852 } 2853 2854 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2855 "startProcessLocked removing on hold: " + app); 2856 mProcessesOnHold.remove(app); 2857 2858 updateCpuStats(); 2859 2860 try { 2861 int uid = app.uid; 2862 2863 int[] gids = null; 2864 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2865 if (!app.isolated) { 2866 int[] permGids = null; 2867 try { 2868 final PackageManager pm = mContext.getPackageManager(); 2869 permGids = pm.getPackageGids(app.info.packageName); 2870 2871 if (Environment.isExternalStorageEmulated()) { 2872 if (pm.checkPermission( 2873 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2874 app.info.packageName) == PERMISSION_GRANTED) { 2875 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2876 } else { 2877 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2878 } 2879 } 2880 } catch (PackageManager.NameNotFoundException e) { 2881 Slog.w(TAG, "Unable to retrieve gids", e); 2882 } 2883 2884 /* 2885 * Add shared application GID so applications can share some 2886 * resources like shared libraries 2887 */ 2888 if (permGids == null) { 2889 gids = new int[1]; 2890 } else { 2891 gids = new int[permGids.length + 1]; 2892 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2893 } 2894 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2895 } 2896 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2897 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2898 && mTopComponent != null 2899 && app.processName.equals(mTopComponent.getPackageName())) { 2900 uid = 0; 2901 } 2902 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2903 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2904 uid = 0; 2905 } 2906 } 2907 int debugFlags = 0; 2908 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2909 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2910 // Also turn on CheckJNI for debuggable apps. It's quite 2911 // awkward to turn on otherwise. 2912 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2913 } 2914 // Run the app in safe mode if its manifest requests so or the 2915 // system is booted in safe mode. 2916 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2917 mSafeMode == true) { 2918 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2919 } 2920 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2921 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2922 } 2923 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2924 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2925 } 2926 if ("1".equals(SystemProperties.get("debug.assert"))) { 2927 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2928 } 2929 2930 String requiredAbi = app.info.cpuAbi; 2931 if (requiredAbi == null) { 2932 requiredAbi = Build.SUPPORTED_ABIS[0]; 2933 } 2934 2935 // Start the process. It will either succeed and return a result containing 2936 // the PID of the new process, or else throw a RuntimeException. 2937 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2938 app.processName, uid, uid, gids, debugFlags, mountExternal, 2939 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2940 2941 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2942 synchronized (bs) { 2943 if (bs.isOnBattery()) { 2944 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2945 } 2946 } 2947 2948 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2949 UserHandle.getUserId(uid), startResult.pid, uid, 2950 app.processName, hostingType, 2951 hostingNameStr != null ? hostingNameStr : ""); 2952 2953 if (app.persistent) { 2954 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2955 } 2956 2957 StringBuilder buf = mStringBuilder; 2958 buf.setLength(0); 2959 buf.append("Start proc "); 2960 buf.append(app.processName); 2961 buf.append(" for "); 2962 buf.append(hostingType); 2963 if (hostingNameStr != null) { 2964 buf.append(" "); 2965 buf.append(hostingNameStr); 2966 } 2967 buf.append(": pid="); 2968 buf.append(startResult.pid); 2969 buf.append(" uid="); 2970 buf.append(uid); 2971 buf.append(" gids={"); 2972 if (gids != null) { 2973 for (int gi=0; gi<gids.length; gi++) { 2974 if (gi != 0) buf.append(", "); 2975 buf.append(gids[gi]); 2976 2977 } 2978 } 2979 buf.append("}"); 2980 Slog.i(TAG, buf.toString()); 2981 app.setPid(startResult.pid); 2982 app.usingWrapper = startResult.usingWrapper; 2983 app.removed = false; 2984 synchronized (mPidsSelfLocked) { 2985 this.mPidsSelfLocked.put(startResult.pid, app); 2986 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2987 msg.obj = app; 2988 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2989 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2990 } 2991 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2992 app.processName, app.info.uid); 2993 if (app.isolated) { 2994 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2995 } 2996 } catch (RuntimeException e) { 2997 // XXX do better error recovery. 2998 app.setPid(0); 2999 Slog.e(TAG, "Failure starting process " + app.processName, e); 3000 } 3001 } 3002 3003 void updateUsageStats(ActivityRecord component, boolean resumed) { 3004 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3005 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3006 if (resumed) { 3007 mUsageStatsService.noteResumeComponent(component.realActivity); 3008 synchronized (stats) { 3009 stats.noteActivityResumedLocked(component.app.uid); 3010 } 3011 } else { 3012 mUsageStatsService.notePauseComponent(component.realActivity); 3013 synchronized (stats) { 3014 stats.noteActivityPausedLocked(component.app.uid); 3015 } 3016 } 3017 } 3018 3019 Intent getHomeIntent() { 3020 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3021 intent.setComponent(mTopComponent); 3022 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3023 intent.addCategory(Intent.CATEGORY_HOME); 3024 } 3025 return intent; 3026 } 3027 3028 boolean startHomeActivityLocked(int userId) { 3029 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3030 && mTopAction == null) { 3031 // We are running in factory test mode, but unable to find 3032 // the factory test app, so just sit around displaying the 3033 // error message and don't try to start anything. 3034 return false; 3035 } 3036 Intent intent = getHomeIntent(); 3037 ActivityInfo aInfo = 3038 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3039 if (aInfo != null) { 3040 intent.setComponent(new ComponentName( 3041 aInfo.applicationInfo.packageName, aInfo.name)); 3042 // Don't do this if the home app is currently being 3043 // instrumented. 3044 aInfo = new ActivityInfo(aInfo); 3045 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3046 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3047 aInfo.applicationInfo.uid, true); 3048 if (app == null || app.instrumentationClass == null) { 3049 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3050 mStackSupervisor.startHomeActivity(intent, aInfo); 3051 } 3052 } 3053 3054 return true; 3055 } 3056 3057 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3058 ActivityInfo ai = null; 3059 ComponentName comp = intent.getComponent(); 3060 try { 3061 if (comp != null) { 3062 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3063 } else { 3064 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3065 intent, 3066 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3067 flags, userId); 3068 3069 if (info != null) { 3070 ai = info.activityInfo; 3071 } 3072 } 3073 } catch (RemoteException e) { 3074 // ignore 3075 } 3076 3077 return ai; 3078 } 3079 3080 /** 3081 * Starts the "new version setup screen" if appropriate. 3082 */ 3083 void startSetupActivityLocked() { 3084 // Only do this once per boot. 3085 if (mCheckedForSetup) { 3086 return; 3087 } 3088 3089 // We will show this screen if the current one is a different 3090 // version than the last one shown, and we are not running in 3091 // low-level factory test mode. 3092 final ContentResolver resolver = mContext.getContentResolver(); 3093 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3094 Settings.Global.getInt(resolver, 3095 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3096 mCheckedForSetup = true; 3097 3098 // See if we should be showing the platform update setup UI. 3099 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3100 List<ResolveInfo> ris = mContext.getPackageManager() 3101 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3102 3103 // We don't allow third party apps to replace this. 3104 ResolveInfo ri = null; 3105 for (int i=0; ris != null && i<ris.size(); i++) { 3106 if ((ris.get(i).activityInfo.applicationInfo.flags 3107 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3108 ri = ris.get(i); 3109 break; 3110 } 3111 } 3112 3113 if (ri != null) { 3114 String vers = ri.activityInfo.metaData != null 3115 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3116 : null; 3117 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3118 vers = ri.activityInfo.applicationInfo.metaData.getString( 3119 Intent.METADATA_SETUP_VERSION); 3120 } 3121 String lastVers = Settings.Secure.getString( 3122 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3123 if (vers != null && !vers.equals(lastVers)) { 3124 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3125 intent.setComponent(new ComponentName( 3126 ri.activityInfo.packageName, ri.activityInfo.name)); 3127 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3128 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3129 } 3130 } 3131 } 3132 } 3133 3134 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3135 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3136 } 3137 3138 void enforceNotIsolatedCaller(String caller) { 3139 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3140 throw new SecurityException("Isolated process not allowed to call " + caller); 3141 } 3142 } 3143 3144 @Override 3145 public int getFrontActivityScreenCompatMode() { 3146 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3147 synchronized (this) { 3148 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3149 } 3150 } 3151 3152 @Override 3153 public void setFrontActivityScreenCompatMode(int mode) { 3154 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3155 "setFrontActivityScreenCompatMode"); 3156 synchronized (this) { 3157 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3158 } 3159 } 3160 3161 @Override 3162 public int getPackageScreenCompatMode(String packageName) { 3163 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3164 synchronized (this) { 3165 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3166 } 3167 } 3168 3169 @Override 3170 public void setPackageScreenCompatMode(String packageName, int mode) { 3171 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3172 "setPackageScreenCompatMode"); 3173 synchronized (this) { 3174 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3175 } 3176 } 3177 3178 @Override 3179 public boolean getPackageAskScreenCompat(String packageName) { 3180 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3181 synchronized (this) { 3182 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3183 } 3184 } 3185 3186 @Override 3187 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3188 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3189 "setPackageAskScreenCompat"); 3190 synchronized (this) { 3191 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3192 } 3193 } 3194 3195 private void dispatchProcessesChanged() { 3196 int N; 3197 synchronized (this) { 3198 N = mPendingProcessChanges.size(); 3199 if (mActiveProcessChanges.length < N) { 3200 mActiveProcessChanges = new ProcessChangeItem[N]; 3201 } 3202 mPendingProcessChanges.toArray(mActiveProcessChanges); 3203 mAvailProcessChanges.addAll(mPendingProcessChanges); 3204 mPendingProcessChanges.clear(); 3205 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3206 } 3207 3208 int i = mProcessObservers.beginBroadcast(); 3209 while (i > 0) { 3210 i--; 3211 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3212 if (observer != null) { 3213 try { 3214 for (int j=0; j<N; j++) { 3215 ProcessChangeItem item = mActiveProcessChanges[j]; 3216 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3217 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3218 + item.pid + " uid=" + item.uid + ": " 3219 + item.foregroundActivities); 3220 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3221 item.foregroundActivities); 3222 } 3223 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3224 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3225 + item.pid + " uid=" + item.uid + ": " + item.processState); 3226 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3227 } 3228 } 3229 } catch (RemoteException e) { 3230 } 3231 } 3232 } 3233 mProcessObservers.finishBroadcast(); 3234 } 3235 3236 private void dispatchProcessDied(int pid, int uid) { 3237 int i = mProcessObservers.beginBroadcast(); 3238 while (i > 0) { 3239 i--; 3240 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3241 if (observer != null) { 3242 try { 3243 observer.onProcessDied(pid, uid); 3244 } catch (RemoteException e) { 3245 } 3246 } 3247 } 3248 mProcessObservers.finishBroadcast(); 3249 } 3250 3251 final void doPendingActivityLaunchesLocked(boolean doResume) { 3252 final int N = mPendingActivityLaunches.size(); 3253 if (N <= 0) { 3254 return; 3255 } 3256 for (int i=0; i<N; i++) { 3257 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3258 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3259 doResume && i == (N-1), null); 3260 } 3261 mPendingActivityLaunches.clear(); 3262 } 3263 3264 @Override 3265 public final int startActivity(IApplicationThread caller, String callingPackage, 3266 Intent intent, String resolvedType, IBinder resultTo, 3267 String resultWho, int requestCode, int startFlags, 3268 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3269 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3270 resultWho, requestCode, 3271 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3272 } 3273 3274 @Override 3275 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3276 Intent intent, String resolvedType, IBinder resultTo, 3277 String resultWho, int requestCode, int startFlags, 3278 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3279 enforceNotIsolatedCaller("startActivity"); 3280 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3281 false, true, "startActivity", null); 3282 // TODO: Switch to user app stacks here. 3283 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3284 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3285 null, null, options, userId, null); 3286 } 3287 3288 @Override 3289 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3290 Intent intent, String resolvedType, IBinder resultTo, 3291 String resultWho, int requestCode, int startFlags, String profileFile, 3292 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3293 enforceNotIsolatedCaller("startActivityAndWait"); 3294 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3295 false, true, "startActivityAndWait", null); 3296 WaitResult res = new WaitResult(); 3297 // TODO: Switch to user app stacks here. 3298 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3299 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3300 res, null, options, UserHandle.getCallingUserId(), null); 3301 return res; 3302 } 3303 3304 @Override 3305 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3306 Intent intent, String resolvedType, IBinder resultTo, 3307 String resultWho, int requestCode, int startFlags, Configuration config, 3308 Bundle options, int userId) { 3309 enforceNotIsolatedCaller("startActivityWithConfig"); 3310 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3311 false, true, "startActivityWithConfig", null); 3312 // TODO: Switch to user app stacks here. 3313 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3314 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3315 null, null, null, config, options, userId, null); 3316 return ret; 3317 } 3318 3319 @Override 3320 public int startActivityIntentSender(IApplicationThread caller, 3321 IntentSender intent, Intent fillInIntent, String resolvedType, 3322 IBinder resultTo, String resultWho, int requestCode, 3323 int flagsMask, int flagsValues, Bundle options) { 3324 enforceNotIsolatedCaller("startActivityIntentSender"); 3325 // Refuse possible leaked file descriptors 3326 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3327 throw new IllegalArgumentException("File descriptors passed in Intent"); 3328 } 3329 3330 IIntentSender sender = intent.getTarget(); 3331 if (!(sender instanceof PendingIntentRecord)) { 3332 throw new IllegalArgumentException("Bad PendingIntent object"); 3333 } 3334 3335 PendingIntentRecord pir = (PendingIntentRecord)sender; 3336 3337 synchronized (this) { 3338 // If this is coming from the currently resumed activity, it is 3339 // effectively saying that app switches are allowed at this point. 3340 final ActivityStack stack = getFocusedStack(); 3341 if (stack.mResumedActivity != null && 3342 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3343 mAppSwitchesAllowedTime = 0; 3344 } 3345 } 3346 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3347 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3348 return ret; 3349 } 3350 3351 @Override 3352 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3353 Intent intent, String resolvedType, IVoiceInteractionSession session, 3354 IVoiceInteractor interactor, int startFlags, String profileFile, 3355 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3356 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3357 != PackageManager.PERMISSION_GRANTED) { 3358 String msg = "Permission Denial: startVoiceActivity() from pid=" 3359 + Binder.getCallingPid() 3360 + ", uid=" + Binder.getCallingUid() 3361 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3362 Slog.w(TAG, msg); 3363 throw new SecurityException(msg); 3364 } 3365 if (session == null || interactor == null) { 3366 throw new NullPointerException("null session or interactor"); 3367 } 3368 userId = handleIncomingUser(callingPid, callingUid, userId, 3369 false, true, "startVoiceActivity", null); 3370 // TODO: Switch to user app stacks here. 3371 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3372 resolvedType, session, interactor, null, null, 0, startFlags, 3373 profileFile, profileFd, null, null, options, userId, null); 3374 } 3375 3376 @Override 3377 public boolean startNextMatchingActivity(IBinder callingActivity, 3378 Intent intent, Bundle options) { 3379 // Refuse possible leaked file descriptors 3380 if (intent != null && intent.hasFileDescriptors() == true) { 3381 throw new IllegalArgumentException("File descriptors passed in Intent"); 3382 } 3383 3384 synchronized (this) { 3385 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3386 if (r == null) { 3387 ActivityOptions.abort(options); 3388 return false; 3389 } 3390 if (r.app == null || r.app.thread == null) { 3391 // The caller is not running... d'oh! 3392 ActivityOptions.abort(options); 3393 return false; 3394 } 3395 intent = new Intent(intent); 3396 // The caller is not allowed to change the data. 3397 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3398 // And we are resetting to find the next component... 3399 intent.setComponent(null); 3400 3401 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3402 3403 ActivityInfo aInfo = null; 3404 try { 3405 List<ResolveInfo> resolves = 3406 AppGlobals.getPackageManager().queryIntentActivities( 3407 intent, r.resolvedType, 3408 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3409 UserHandle.getCallingUserId()); 3410 3411 // Look for the original activity in the list... 3412 final int N = resolves != null ? resolves.size() : 0; 3413 for (int i=0; i<N; i++) { 3414 ResolveInfo rInfo = resolves.get(i); 3415 if (rInfo.activityInfo.packageName.equals(r.packageName) 3416 && rInfo.activityInfo.name.equals(r.info.name)) { 3417 // We found the current one... the next matching is 3418 // after it. 3419 i++; 3420 if (i<N) { 3421 aInfo = resolves.get(i).activityInfo; 3422 } 3423 if (debug) { 3424 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3425 + "/" + r.info.name); 3426 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3427 + "/" + aInfo.name); 3428 } 3429 break; 3430 } 3431 } 3432 } catch (RemoteException e) { 3433 } 3434 3435 if (aInfo == null) { 3436 // Nobody who is next! 3437 ActivityOptions.abort(options); 3438 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3439 return false; 3440 } 3441 3442 intent.setComponent(new ComponentName( 3443 aInfo.applicationInfo.packageName, aInfo.name)); 3444 intent.setFlags(intent.getFlags()&~( 3445 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3446 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3447 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3448 Intent.FLAG_ACTIVITY_NEW_TASK)); 3449 3450 // Okay now we need to start the new activity, replacing the 3451 // currently running activity. This is a little tricky because 3452 // we want to start the new one as if the current one is finished, 3453 // but not finish the current one first so that there is no flicker. 3454 // And thus... 3455 final boolean wasFinishing = r.finishing; 3456 r.finishing = true; 3457 3458 // Propagate reply information over to the new activity. 3459 final ActivityRecord resultTo = r.resultTo; 3460 final String resultWho = r.resultWho; 3461 final int requestCode = r.requestCode; 3462 r.resultTo = null; 3463 if (resultTo != null) { 3464 resultTo.removeResultsLocked(r, resultWho, requestCode); 3465 } 3466 3467 final long origId = Binder.clearCallingIdentity(); 3468 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3469 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3470 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3471 options, false, null, null); 3472 Binder.restoreCallingIdentity(origId); 3473 3474 r.finishing = wasFinishing; 3475 if (res != ActivityManager.START_SUCCESS) { 3476 return false; 3477 } 3478 return true; 3479 } 3480 } 3481 3482 final int startActivityInPackage(int uid, String callingPackage, 3483 Intent intent, String resolvedType, IBinder resultTo, 3484 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3485 IActivityContainer container) { 3486 3487 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3488 false, true, "startActivityInPackage", null); 3489 3490 // TODO: Switch to user app stacks here. 3491 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3492 null, null, resultTo, resultWho, requestCode, startFlags, 3493 null, null, null, null, options, userId, container); 3494 return ret; 3495 } 3496 3497 @Override 3498 public final int startActivities(IApplicationThread caller, String callingPackage, 3499 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3500 int userId) { 3501 enforceNotIsolatedCaller("startActivities"); 3502 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3503 false, true, "startActivity", null); 3504 // TODO: Switch to user app stacks here. 3505 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3506 resolvedTypes, resultTo, options, userId); 3507 return ret; 3508 } 3509 3510 final int startActivitiesInPackage(int uid, String callingPackage, 3511 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3512 Bundle options, int userId) { 3513 3514 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3515 false, true, "startActivityInPackage", null); 3516 // TODO: Switch to user app stacks here. 3517 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3518 resultTo, options, userId); 3519 return ret; 3520 } 3521 3522 final void addRecentTaskLocked(TaskRecord task) { 3523 int N = mRecentTasks.size(); 3524 // Quick case: check if the top-most recent task is the same. 3525 if (N > 0 && mRecentTasks.get(0) == task) { 3526 return; 3527 } 3528 // Another quick case: never add voice sessions. 3529 if (task.voiceSession != null) { 3530 return; 3531 } 3532 // Remove any existing entries that are the same kind of task. 3533 final Intent intent = task.intent; 3534 final boolean document = intent != null && intent.isDocument(); 3535 for (int i=0; i<N; i++) { 3536 TaskRecord tr = mRecentTasks.get(i); 3537 if (task != tr) { 3538 if (task.userId != tr.userId) { 3539 continue; 3540 } 3541 final Intent trIntent = tr.intent; 3542 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3543 (intent == null || !intent.filterEquals(trIntent))) { 3544 continue; 3545 } 3546 if (document || trIntent != null && trIntent.isDocument()) { 3547 // Document tasks do not match other tasks. 3548 continue; 3549 } 3550 } 3551 3552 // Either task and tr are the same or, their affinities match or their intents match 3553 // and neither of them is a document. 3554 tr.disposeThumbnail(); 3555 mRecentTasks.remove(i); 3556 i--; 3557 N--; 3558 if (task.intent == null) { 3559 // If the new recent task we are adding is not fully 3560 // specified, then replace it with the existing recent task. 3561 task = tr; 3562 } 3563 } 3564 if (N >= MAX_RECENT_TASKS) { 3565 mRecentTasks.remove(N-1).disposeThumbnail(); 3566 } 3567 mRecentTasks.add(0, task); 3568 } 3569 3570 @Override 3571 public void reportActivityFullyDrawn(IBinder token) { 3572 synchronized (this) { 3573 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3574 if (r == null) { 3575 return; 3576 } 3577 r.reportFullyDrawnLocked(); 3578 } 3579 } 3580 3581 @Override 3582 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3583 synchronized (this) { 3584 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3585 if (r == null) { 3586 return; 3587 } 3588 final long origId = Binder.clearCallingIdentity(); 3589 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3590 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3591 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3592 if (config != null) { 3593 r.frozenBeforeDestroy = true; 3594 if (!updateConfigurationLocked(config, r, false, false)) { 3595 mStackSupervisor.resumeTopActivitiesLocked(); 3596 } 3597 } 3598 Binder.restoreCallingIdentity(origId); 3599 } 3600 } 3601 3602 @Override 3603 public int getRequestedOrientation(IBinder token) { 3604 synchronized (this) { 3605 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3606 if (r == null) { 3607 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3608 } 3609 return mWindowManager.getAppOrientation(r.appToken); 3610 } 3611 } 3612 3613 /** 3614 * This is the internal entry point for handling Activity.finish(). 3615 * 3616 * @param token The Binder token referencing the Activity we want to finish. 3617 * @param resultCode Result code, if any, from this Activity. 3618 * @param resultData Result data (Intent), if any, from this Activity. 3619 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3620 * the root Activity in the task. 3621 * 3622 * @return Returns true if the activity successfully finished, or false if it is still running. 3623 */ 3624 @Override 3625 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3626 boolean finishTask) { 3627 // Refuse possible leaked file descriptors 3628 if (resultData != null && resultData.hasFileDescriptors() == true) { 3629 throw new IllegalArgumentException("File descriptors passed in Intent"); 3630 } 3631 3632 synchronized(this) { 3633 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3634 if (r == null) { 3635 return true; 3636 } 3637 // Keep track of the root activity of the task before we finish it 3638 TaskRecord tr = r.task; 3639 ActivityRecord rootR = tr.getRootActivity(); 3640 if (mController != null) { 3641 // Find the first activity that is not finishing. 3642 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3643 if (next != null) { 3644 // ask watcher if this is allowed 3645 boolean resumeOK = true; 3646 try { 3647 resumeOK = mController.activityResuming(next.packageName); 3648 } catch (RemoteException e) { 3649 mController = null; 3650 Watchdog.getInstance().setActivityController(null); 3651 } 3652 3653 if (!resumeOK) { 3654 return false; 3655 } 3656 } 3657 } 3658 final long origId = Binder.clearCallingIdentity(); 3659 try { 3660 boolean res; 3661 if (finishTask && r == rootR) { 3662 // If requested, remove the task that is associated to this activity only if it 3663 // was the root activity in the task. The result code and data is ignored because 3664 // we don't support returning them across task boundaries. 3665 res = removeTaskByIdLocked(tr.taskId, 0); 3666 } else { 3667 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3668 resultData, "app-request", true); 3669 } 3670 return res; 3671 } finally { 3672 Binder.restoreCallingIdentity(origId); 3673 } 3674 } 3675 } 3676 3677 @Override 3678 public final void finishHeavyWeightApp() { 3679 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3680 != PackageManager.PERMISSION_GRANTED) { 3681 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3682 + Binder.getCallingPid() 3683 + ", uid=" + Binder.getCallingUid() 3684 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3685 Slog.w(TAG, msg); 3686 throw new SecurityException(msg); 3687 } 3688 3689 synchronized(this) { 3690 if (mHeavyWeightProcess == null) { 3691 return; 3692 } 3693 3694 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3695 mHeavyWeightProcess.activities); 3696 for (int i=0; i<activities.size(); i++) { 3697 ActivityRecord r = activities.get(i); 3698 if (!r.finishing) { 3699 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3700 null, "finish-heavy", true); 3701 } 3702 } 3703 3704 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3705 mHeavyWeightProcess.userId, 0)); 3706 mHeavyWeightProcess = null; 3707 } 3708 } 3709 3710 @Override 3711 public void crashApplication(int uid, int initialPid, String packageName, 3712 String message) { 3713 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3714 != PackageManager.PERMISSION_GRANTED) { 3715 String msg = "Permission Denial: crashApplication() from pid=" 3716 + Binder.getCallingPid() 3717 + ", uid=" + Binder.getCallingUid() 3718 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3719 Slog.w(TAG, msg); 3720 throw new SecurityException(msg); 3721 } 3722 3723 synchronized(this) { 3724 ProcessRecord proc = null; 3725 3726 // Figure out which process to kill. We don't trust that initialPid 3727 // still has any relation to current pids, so must scan through the 3728 // list. 3729 synchronized (mPidsSelfLocked) { 3730 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3731 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3732 if (p.uid != uid) { 3733 continue; 3734 } 3735 if (p.pid == initialPid) { 3736 proc = p; 3737 break; 3738 } 3739 if (p.pkgList.containsKey(packageName)) { 3740 proc = p; 3741 } 3742 } 3743 } 3744 3745 if (proc == null) { 3746 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3747 + " initialPid=" + initialPid 3748 + " packageName=" + packageName); 3749 return; 3750 } 3751 3752 if (proc.thread != null) { 3753 if (proc.pid == Process.myPid()) { 3754 Log.w(TAG, "crashApplication: trying to crash self!"); 3755 return; 3756 } 3757 long ident = Binder.clearCallingIdentity(); 3758 try { 3759 proc.thread.scheduleCrash(message); 3760 } catch (RemoteException e) { 3761 } 3762 Binder.restoreCallingIdentity(ident); 3763 } 3764 } 3765 } 3766 3767 @Override 3768 public final void finishSubActivity(IBinder token, String resultWho, 3769 int requestCode) { 3770 synchronized(this) { 3771 final long origId = Binder.clearCallingIdentity(); 3772 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3773 if (r != null) { 3774 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3775 } 3776 Binder.restoreCallingIdentity(origId); 3777 } 3778 } 3779 3780 @Override 3781 public boolean finishActivityAffinity(IBinder token) { 3782 synchronized(this) { 3783 final long origId = Binder.clearCallingIdentity(); 3784 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3785 boolean res = false; 3786 if (r != null) { 3787 res = r.task.stack.finishActivityAffinityLocked(r); 3788 } 3789 Binder.restoreCallingIdentity(origId); 3790 return res; 3791 } 3792 } 3793 3794 @Override 3795 public boolean willActivityBeVisible(IBinder token) { 3796 synchronized(this) { 3797 ActivityStack stack = ActivityRecord.getStackLocked(token); 3798 if (stack != null) { 3799 return stack.willActivityBeVisibleLocked(token); 3800 } 3801 return false; 3802 } 3803 } 3804 3805 @Override 3806 public void overridePendingTransition(IBinder token, String packageName, 3807 int enterAnim, int exitAnim) { 3808 synchronized(this) { 3809 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3810 if (self == null) { 3811 return; 3812 } 3813 3814 final long origId = Binder.clearCallingIdentity(); 3815 3816 if (self.state == ActivityState.RESUMED 3817 || self.state == ActivityState.PAUSING) { 3818 mWindowManager.overridePendingAppTransition(packageName, 3819 enterAnim, exitAnim, null); 3820 } 3821 3822 Binder.restoreCallingIdentity(origId); 3823 } 3824 } 3825 3826 /** 3827 * Main function for removing an existing process from the activity manager 3828 * as a result of that process going away. Clears out all connections 3829 * to the process. 3830 */ 3831 private final void handleAppDiedLocked(ProcessRecord app, 3832 boolean restarting, boolean allowRestart) { 3833 int pid = app.pid; 3834 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3835 if (!restarting) { 3836 removeLruProcessLocked(app); 3837 if (pid > 0) { 3838 ProcessList.remove(pid); 3839 } 3840 } 3841 3842 if (mProfileProc == app) { 3843 clearProfilerLocked(); 3844 } 3845 3846 // Remove this application's activities from active lists. 3847 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3848 3849 app.activities.clear(); 3850 3851 if (app.instrumentationClass != null) { 3852 Slog.w(TAG, "Crash of app " + app.processName 3853 + " running instrumentation " + app.instrumentationClass); 3854 Bundle info = new Bundle(); 3855 info.putString("shortMsg", "Process crashed."); 3856 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3857 } 3858 3859 if (!restarting) { 3860 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3861 // If there was nothing to resume, and we are not already 3862 // restarting this process, but there is a visible activity that 3863 // is hosted by the process... then make sure all visible 3864 // activities are running, taking care of restarting this 3865 // process. 3866 if (hasVisibleActivities) { 3867 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3868 } 3869 } 3870 } 3871 } 3872 3873 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3874 IBinder threadBinder = thread.asBinder(); 3875 // Find the application record. 3876 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3877 ProcessRecord rec = mLruProcesses.get(i); 3878 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3879 return i; 3880 } 3881 } 3882 return -1; 3883 } 3884 3885 final ProcessRecord getRecordForAppLocked( 3886 IApplicationThread thread) { 3887 if (thread == null) { 3888 return null; 3889 } 3890 3891 int appIndex = getLRURecordIndexForAppLocked(thread); 3892 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3893 } 3894 3895 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3896 // If there are no longer any background processes running, 3897 // and the app that died was not running instrumentation, 3898 // then tell everyone we are now low on memory. 3899 boolean haveBg = false; 3900 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3901 ProcessRecord rec = mLruProcesses.get(i); 3902 if (rec.thread != null 3903 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3904 haveBg = true; 3905 break; 3906 } 3907 } 3908 3909 if (!haveBg) { 3910 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3911 if (doReport) { 3912 long now = SystemClock.uptimeMillis(); 3913 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3914 doReport = false; 3915 } else { 3916 mLastMemUsageReportTime = now; 3917 } 3918 } 3919 final ArrayList<ProcessMemInfo> memInfos 3920 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3921 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3922 long now = SystemClock.uptimeMillis(); 3923 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3924 ProcessRecord rec = mLruProcesses.get(i); 3925 if (rec == dyingProc || rec.thread == null) { 3926 continue; 3927 } 3928 if (doReport) { 3929 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3930 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3931 } 3932 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3933 // The low memory report is overriding any current 3934 // state for a GC request. Make sure to do 3935 // heavy/important/visible/foreground processes first. 3936 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3937 rec.lastRequestedGc = 0; 3938 } else { 3939 rec.lastRequestedGc = rec.lastLowMemory; 3940 } 3941 rec.reportLowMemory = true; 3942 rec.lastLowMemory = now; 3943 mProcessesToGc.remove(rec); 3944 addProcessToGcListLocked(rec); 3945 } 3946 } 3947 if (doReport) { 3948 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3949 mHandler.sendMessage(msg); 3950 } 3951 scheduleAppGcsLocked(); 3952 } 3953 } 3954 3955 final void appDiedLocked(ProcessRecord app, int pid, 3956 IApplicationThread thread) { 3957 3958 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3959 synchronized (stats) { 3960 stats.noteProcessDiedLocked(app.info.uid, pid); 3961 } 3962 3963 // Clean up already done if the process has been re-started. 3964 if (app.pid == pid && app.thread != null && 3965 app.thread.asBinder() == thread.asBinder()) { 3966 boolean doLowMem = app.instrumentationClass == null; 3967 boolean doOomAdj = doLowMem; 3968 if (!app.killedByAm) { 3969 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3970 + ") has died."); 3971 mAllowLowerMemLevel = true; 3972 } else { 3973 // Note that we always want to do oom adj to update our state with the 3974 // new number of procs. 3975 mAllowLowerMemLevel = false; 3976 doLowMem = false; 3977 } 3978 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3979 if (DEBUG_CLEANUP) Slog.v( 3980 TAG, "Dying app: " + app + ", pid: " + pid 3981 + ", thread: " + thread.asBinder()); 3982 handleAppDiedLocked(app, false, true); 3983 3984 if (doOomAdj) { 3985 updateOomAdjLocked(); 3986 } 3987 if (doLowMem) { 3988 doLowMemReportIfNeededLocked(app); 3989 } 3990 } else if (app.pid != pid) { 3991 // A new process has already been started. 3992 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3993 + ") has died and restarted (pid " + app.pid + ")."); 3994 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3995 } else if (DEBUG_PROCESSES) { 3996 Slog.d(TAG, "Received spurious death notification for thread " 3997 + thread.asBinder()); 3998 } 3999 } 4000 4001 /** 4002 * If a stack trace dump file is configured, dump process stack traces. 4003 * @param clearTraces causes the dump file to be erased prior to the new 4004 * traces being written, if true; when false, the new traces will be 4005 * appended to any existing file content. 4006 * @param firstPids of dalvik VM processes to dump stack traces for first 4007 * @param lastPids of dalvik VM processes to dump stack traces for last 4008 * @param nativeProcs optional list of native process names to dump stack crawls 4009 * @return file containing stack traces, or null if no dump file is configured 4010 */ 4011 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4012 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4013 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4014 if (tracesPath == null || tracesPath.length() == 0) { 4015 return null; 4016 } 4017 4018 File tracesFile = new File(tracesPath); 4019 try { 4020 File tracesDir = tracesFile.getParentFile(); 4021 if (!tracesDir.exists()) { 4022 tracesFile.mkdirs(); 4023 if (!SELinux.restorecon(tracesDir)) { 4024 return null; 4025 } 4026 } 4027 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4028 4029 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4030 tracesFile.createNewFile(); 4031 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4032 } catch (IOException e) { 4033 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4034 return null; 4035 } 4036 4037 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4038 return tracesFile; 4039 } 4040 4041 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4042 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4043 // Use a FileObserver to detect when traces finish writing. 4044 // The order of traces is considered important to maintain for legibility. 4045 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4046 @Override 4047 public synchronized void onEvent(int event, String path) { notify(); } 4048 }; 4049 4050 try { 4051 observer.startWatching(); 4052 4053 // First collect all of the stacks of the most important pids. 4054 if (firstPids != null) { 4055 try { 4056 int num = firstPids.size(); 4057 for (int i = 0; i < num; i++) { 4058 synchronized (observer) { 4059 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4060 observer.wait(200); // Wait for write-close, give up after 200msec 4061 } 4062 } 4063 } catch (InterruptedException e) { 4064 Log.wtf(TAG, e); 4065 } 4066 } 4067 4068 // Next collect the stacks of the native pids 4069 if (nativeProcs != null) { 4070 int[] pids = Process.getPidsForCommands(nativeProcs); 4071 if (pids != null) { 4072 for (int pid : pids) { 4073 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4074 } 4075 } 4076 } 4077 4078 // Lastly, measure CPU usage. 4079 if (processCpuTracker != null) { 4080 processCpuTracker.init(); 4081 System.gc(); 4082 processCpuTracker.update(); 4083 try { 4084 synchronized (processCpuTracker) { 4085 processCpuTracker.wait(500); // measure over 1/2 second. 4086 } 4087 } catch (InterruptedException e) { 4088 } 4089 processCpuTracker.update(); 4090 4091 // We'll take the stack crawls of just the top apps using CPU. 4092 final int N = processCpuTracker.countWorkingStats(); 4093 int numProcs = 0; 4094 for (int i=0; i<N && numProcs<5; i++) { 4095 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4096 if (lastPids.indexOfKey(stats.pid) >= 0) { 4097 numProcs++; 4098 try { 4099 synchronized (observer) { 4100 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4101 observer.wait(200); // Wait for write-close, give up after 200msec 4102 } 4103 } catch (InterruptedException e) { 4104 Log.wtf(TAG, e); 4105 } 4106 4107 } 4108 } 4109 } 4110 } finally { 4111 observer.stopWatching(); 4112 } 4113 } 4114 4115 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4116 if (true || IS_USER_BUILD) { 4117 return; 4118 } 4119 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4120 if (tracesPath == null || tracesPath.length() == 0) { 4121 return; 4122 } 4123 4124 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4125 StrictMode.allowThreadDiskWrites(); 4126 try { 4127 final File tracesFile = new File(tracesPath); 4128 final File tracesDir = tracesFile.getParentFile(); 4129 final File tracesTmp = new File(tracesDir, "__tmp__"); 4130 try { 4131 if (!tracesDir.exists()) { 4132 tracesFile.mkdirs(); 4133 if (!SELinux.restorecon(tracesDir.getPath())) { 4134 return; 4135 } 4136 } 4137 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4138 4139 if (tracesFile.exists()) { 4140 tracesTmp.delete(); 4141 tracesFile.renameTo(tracesTmp); 4142 } 4143 StringBuilder sb = new StringBuilder(); 4144 Time tobj = new Time(); 4145 tobj.set(System.currentTimeMillis()); 4146 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4147 sb.append(": "); 4148 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4149 sb.append(" since "); 4150 sb.append(msg); 4151 FileOutputStream fos = new FileOutputStream(tracesFile); 4152 fos.write(sb.toString().getBytes()); 4153 if (app == null) { 4154 fos.write("\n*** No application process!".getBytes()); 4155 } 4156 fos.close(); 4157 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4158 } catch (IOException e) { 4159 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4160 return; 4161 } 4162 4163 if (app != null) { 4164 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4165 firstPids.add(app.pid); 4166 dumpStackTraces(tracesPath, firstPids, null, null, null); 4167 } 4168 4169 File lastTracesFile = null; 4170 File curTracesFile = null; 4171 for (int i=9; i>=0; i--) { 4172 String name = String.format(Locale.US, "slow%02d.txt", i); 4173 curTracesFile = new File(tracesDir, name); 4174 if (curTracesFile.exists()) { 4175 if (lastTracesFile != null) { 4176 curTracesFile.renameTo(lastTracesFile); 4177 } else { 4178 curTracesFile.delete(); 4179 } 4180 } 4181 lastTracesFile = curTracesFile; 4182 } 4183 tracesFile.renameTo(curTracesFile); 4184 if (tracesTmp.exists()) { 4185 tracesTmp.renameTo(tracesFile); 4186 } 4187 } finally { 4188 StrictMode.setThreadPolicy(oldPolicy); 4189 } 4190 } 4191 4192 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4193 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4194 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4195 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4196 4197 if (mController != null) { 4198 try { 4199 // 0 == continue, -1 = kill process immediately 4200 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4201 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4202 } catch (RemoteException e) { 4203 mController = null; 4204 Watchdog.getInstance().setActivityController(null); 4205 } 4206 } 4207 4208 long anrTime = SystemClock.uptimeMillis(); 4209 if (MONITOR_CPU_USAGE) { 4210 updateCpuStatsNow(); 4211 } 4212 4213 synchronized (this) { 4214 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4215 if (mShuttingDown) { 4216 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4217 return; 4218 } else if (app.notResponding) { 4219 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4220 return; 4221 } else if (app.crashing) { 4222 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4223 return; 4224 } 4225 4226 // In case we come through here for the same app before completing 4227 // this one, mark as anring now so we will bail out. 4228 app.notResponding = true; 4229 4230 // Log the ANR to the event log. 4231 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4232 app.processName, app.info.flags, annotation); 4233 4234 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4235 firstPids.add(app.pid); 4236 4237 int parentPid = app.pid; 4238 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4239 if (parentPid != app.pid) firstPids.add(parentPid); 4240 4241 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4242 4243 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4244 ProcessRecord r = mLruProcesses.get(i); 4245 if (r != null && r.thread != null) { 4246 int pid = r.pid; 4247 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4248 if (r.persistent) { 4249 firstPids.add(pid); 4250 } else { 4251 lastPids.put(pid, Boolean.TRUE); 4252 } 4253 } 4254 } 4255 } 4256 } 4257 4258 // Log the ANR to the main log. 4259 StringBuilder info = new StringBuilder(); 4260 info.setLength(0); 4261 info.append("ANR in ").append(app.processName); 4262 if (activity != null && activity.shortComponentName != null) { 4263 info.append(" (").append(activity.shortComponentName).append(")"); 4264 } 4265 info.append("\n"); 4266 info.append("PID: ").append(app.pid).append("\n"); 4267 if (annotation != null) { 4268 info.append("Reason: ").append(annotation).append("\n"); 4269 } 4270 if (parent != null && parent != activity) { 4271 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4272 } 4273 4274 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4275 4276 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4277 NATIVE_STACKS_OF_INTEREST); 4278 4279 String cpuInfo = null; 4280 if (MONITOR_CPU_USAGE) { 4281 updateCpuStatsNow(); 4282 synchronized (mProcessCpuThread) { 4283 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4284 } 4285 info.append(processCpuTracker.printCurrentLoad()); 4286 info.append(cpuInfo); 4287 } 4288 4289 info.append(processCpuTracker.printCurrentState(anrTime)); 4290 4291 Slog.e(TAG, info.toString()); 4292 if (tracesFile == null) { 4293 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4294 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4295 } 4296 4297 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4298 cpuInfo, tracesFile, null); 4299 4300 if (mController != null) { 4301 try { 4302 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4303 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4304 if (res != 0) { 4305 if (res < 0 && app.pid != MY_PID) { 4306 Process.killProcess(app.pid); 4307 } else { 4308 synchronized (this) { 4309 mServices.scheduleServiceTimeoutLocked(app); 4310 } 4311 } 4312 return; 4313 } 4314 } catch (RemoteException e) { 4315 mController = null; 4316 Watchdog.getInstance().setActivityController(null); 4317 } 4318 } 4319 4320 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4321 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4322 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4323 4324 synchronized (this) { 4325 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4326 killUnneededProcessLocked(app, "background ANR"); 4327 return; 4328 } 4329 4330 // Set the app's notResponding state, and look up the errorReportReceiver 4331 makeAppNotRespondingLocked(app, 4332 activity != null ? activity.shortComponentName : null, 4333 annotation != null ? "ANR " + annotation : "ANR", 4334 info.toString()); 4335 4336 // Bring up the infamous App Not Responding dialog 4337 Message msg = Message.obtain(); 4338 HashMap<String, Object> map = new HashMap<String, Object>(); 4339 msg.what = SHOW_NOT_RESPONDING_MSG; 4340 msg.obj = map; 4341 msg.arg1 = aboveSystem ? 1 : 0; 4342 map.put("app", app); 4343 if (activity != null) { 4344 map.put("activity", activity); 4345 } 4346 4347 mHandler.sendMessage(msg); 4348 } 4349 } 4350 4351 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4352 if (!mLaunchWarningShown) { 4353 mLaunchWarningShown = true; 4354 mHandler.post(new Runnable() { 4355 @Override 4356 public void run() { 4357 synchronized (ActivityManagerService.this) { 4358 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4359 d.show(); 4360 mHandler.postDelayed(new Runnable() { 4361 @Override 4362 public void run() { 4363 synchronized (ActivityManagerService.this) { 4364 d.dismiss(); 4365 mLaunchWarningShown = false; 4366 } 4367 } 4368 }, 4000); 4369 } 4370 } 4371 }); 4372 } 4373 } 4374 4375 @Override 4376 public boolean clearApplicationUserData(final String packageName, 4377 final IPackageDataObserver observer, int userId) { 4378 enforceNotIsolatedCaller("clearApplicationUserData"); 4379 int uid = Binder.getCallingUid(); 4380 int pid = Binder.getCallingPid(); 4381 userId = handleIncomingUser(pid, uid, 4382 userId, false, true, "clearApplicationUserData", null); 4383 long callingId = Binder.clearCallingIdentity(); 4384 try { 4385 IPackageManager pm = AppGlobals.getPackageManager(); 4386 int pkgUid = -1; 4387 synchronized(this) { 4388 try { 4389 pkgUid = pm.getPackageUid(packageName, userId); 4390 } catch (RemoteException e) { 4391 } 4392 if (pkgUid == -1) { 4393 Slog.w(TAG, "Invalid packageName: " + packageName); 4394 if (observer != null) { 4395 try { 4396 observer.onRemoveCompleted(packageName, false); 4397 } catch (RemoteException e) { 4398 Slog.i(TAG, "Observer no longer exists."); 4399 } 4400 } 4401 return false; 4402 } 4403 if (uid == pkgUid || checkComponentPermission( 4404 android.Manifest.permission.CLEAR_APP_USER_DATA, 4405 pid, uid, -1, true) 4406 == PackageManager.PERMISSION_GRANTED) { 4407 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4408 } else { 4409 throw new SecurityException("PID " + pid + " does not have permission " 4410 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4411 + " of package " + packageName); 4412 } 4413 } 4414 4415 try { 4416 // Clear application user data 4417 pm.clearApplicationUserData(packageName, observer, userId); 4418 4419 // Remove all permissions granted from/to this package 4420 removeUriPermissionsForPackageLocked(packageName, userId, true); 4421 4422 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4423 Uri.fromParts("package", packageName, null)); 4424 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4425 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4426 null, null, 0, null, null, null, false, false, userId); 4427 } catch (RemoteException e) { 4428 } 4429 } finally { 4430 Binder.restoreCallingIdentity(callingId); 4431 } 4432 return true; 4433 } 4434 4435 @Override 4436 public void killBackgroundProcesses(final String packageName, int userId) { 4437 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4438 != PackageManager.PERMISSION_GRANTED && 4439 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4440 != PackageManager.PERMISSION_GRANTED) { 4441 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4442 + Binder.getCallingPid() 4443 + ", uid=" + Binder.getCallingUid() 4444 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4445 Slog.w(TAG, msg); 4446 throw new SecurityException(msg); 4447 } 4448 4449 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4450 userId, true, true, "killBackgroundProcesses", null); 4451 long callingId = Binder.clearCallingIdentity(); 4452 try { 4453 IPackageManager pm = AppGlobals.getPackageManager(); 4454 synchronized(this) { 4455 int appId = -1; 4456 try { 4457 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4458 } catch (RemoteException e) { 4459 } 4460 if (appId == -1) { 4461 Slog.w(TAG, "Invalid packageName: " + packageName); 4462 return; 4463 } 4464 killPackageProcessesLocked(packageName, appId, userId, 4465 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4466 } 4467 } finally { 4468 Binder.restoreCallingIdentity(callingId); 4469 } 4470 } 4471 4472 @Override 4473 public void killAllBackgroundProcesses() { 4474 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4475 != PackageManager.PERMISSION_GRANTED) { 4476 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4477 + Binder.getCallingPid() 4478 + ", uid=" + Binder.getCallingUid() 4479 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4480 Slog.w(TAG, msg); 4481 throw new SecurityException(msg); 4482 } 4483 4484 long callingId = Binder.clearCallingIdentity(); 4485 try { 4486 synchronized(this) { 4487 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4488 final int NP = mProcessNames.getMap().size(); 4489 for (int ip=0; ip<NP; ip++) { 4490 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4491 final int NA = apps.size(); 4492 for (int ia=0; ia<NA; ia++) { 4493 ProcessRecord app = apps.valueAt(ia); 4494 if (app.persistent) { 4495 // we don't kill persistent processes 4496 continue; 4497 } 4498 if (app.removed) { 4499 procs.add(app); 4500 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4501 app.removed = true; 4502 procs.add(app); 4503 } 4504 } 4505 } 4506 4507 int N = procs.size(); 4508 for (int i=0; i<N; i++) { 4509 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4510 } 4511 mAllowLowerMemLevel = true; 4512 updateOomAdjLocked(); 4513 doLowMemReportIfNeededLocked(null); 4514 } 4515 } finally { 4516 Binder.restoreCallingIdentity(callingId); 4517 } 4518 } 4519 4520 @Override 4521 public void forceStopPackage(final String packageName, int userId) { 4522 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4523 != PackageManager.PERMISSION_GRANTED) { 4524 String msg = "Permission Denial: forceStopPackage() from pid=" 4525 + Binder.getCallingPid() 4526 + ", uid=" + Binder.getCallingUid() 4527 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4528 Slog.w(TAG, msg); 4529 throw new SecurityException(msg); 4530 } 4531 final int callingPid = Binder.getCallingPid(); 4532 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4533 userId, true, true, "forceStopPackage", null); 4534 long callingId = Binder.clearCallingIdentity(); 4535 try { 4536 IPackageManager pm = AppGlobals.getPackageManager(); 4537 synchronized(this) { 4538 int[] users = userId == UserHandle.USER_ALL 4539 ? getUsersLocked() : new int[] { userId }; 4540 for (int user : users) { 4541 int pkgUid = -1; 4542 try { 4543 pkgUid = pm.getPackageUid(packageName, user); 4544 } catch (RemoteException e) { 4545 } 4546 if (pkgUid == -1) { 4547 Slog.w(TAG, "Invalid packageName: " + packageName); 4548 continue; 4549 } 4550 try { 4551 pm.setPackageStoppedState(packageName, true, user); 4552 } catch (RemoteException e) { 4553 } catch (IllegalArgumentException e) { 4554 Slog.w(TAG, "Failed trying to unstop package " 4555 + packageName + ": " + e); 4556 } 4557 if (isUserRunningLocked(user, false)) { 4558 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4559 } 4560 } 4561 } 4562 } finally { 4563 Binder.restoreCallingIdentity(callingId); 4564 } 4565 } 4566 4567 /* 4568 * The pkg name and app id have to be specified. 4569 */ 4570 @Override 4571 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4572 if (pkg == null) { 4573 return; 4574 } 4575 // Make sure the uid is valid. 4576 if (appid < 0) { 4577 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4578 return; 4579 } 4580 int callerUid = Binder.getCallingUid(); 4581 // Only the system server can kill an application 4582 if (callerUid == Process.SYSTEM_UID) { 4583 // Post an aysnc message to kill the application 4584 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4585 msg.arg1 = appid; 4586 msg.arg2 = 0; 4587 Bundle bundle = new Bundle(); 4588 bundle.putString("pkg", pkg); 4589 bundle.putString("reason", reason); 4590 msg.obj = bundle; 4591 mHandler.sendMessage(msg); 4592 } else { 4593 throw new SecurityException(callerUid + " cannot kill pkg: " + 4594 pkg); 4595 } 4596 } 4597 4598 @Override 4599 public void closeSystemDialogs(String reason) { 4600 enforceNotIsolatedCaller("closeSystemDialogs"); 4601 4602 final int pid = Binder.getCallingPid(); 4603 final int uid = Binder.getCallingUid(); 4604 final long origId = Binder.clearCallingIdentity(); 4605 try { 4606 synchronized (this) { 4607 // Only allow this from foreground processes, so that background 4608 // applications can't abuse it to prevent system UI from being shown. 4609 if (uid >= Process.FIRST_APPLICATION_UID) { 4610 ProcessRecord proc; 4611 synchronized (mPidsSelfLocked) { 4612 proc = mPidsSelfLocked.get(pid); 4613 } 4614 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4615 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4616 + " from background process " + proc); 4617 return; 4618 } 4619 } 4620 closeSystemDialogsLocked(reason); 4621 } 4622 } finally { 4623 Binder.restoreCallingIdentity(origId); 4624 } 4625 } 4626 4627 void closeSystemDialogsLocked(String reason) { 4628 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4629 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4630 | Intent.FLAG_RECEIVER_FOREGROUND); 4631 if (reason != null) { 4632 intent.putExtra("reason", reason); 4633 } 4634 mWindowManager.closeSystemDialogs(reason); 4635 4636 mStackSupervisor.closeSystemDialogsLocked(); 4637 4638 broadcastIntentLocked(null, null, intent, null, 4639 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4640 Process.SYSTEM_UID, UserHandle.USER_ALL); 4641 } 4642 4643 @Override 4644 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4645 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4646 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4647 for (int i=pids.length-1; i>=0; i--) { 4648 ProcessRecord proc; 4649 int oomAdj; 4650 synchronized (this) { 4651 synchronized (mPidsSelfLocked) { 4652 proc = mPidsSelfLocked.get(pids[i]); 4653 oomAdj = proc != null ? proc.setAdj : 0; 4654 } 4655 } 4656 infos[i] = new Debug.MemoryInfo(); 4657 Debug.getMemoryInfo(pids[i], infos[i]); 4658 if (proc != null) { 4659 synchronized (this) { 4660 if (proc.thread != null && proc.setAdj == oomAdj) { 4661 // Record this for posterity if the process has been stable. 4662 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4663 infos[i].getTotalUss(), false, proc.pkgList); 4664 } 4665 } 4666 } 4667 } 4668 return infos; 4669 } 4670 4671 @Override 4672 public long[] getProcessPss(int[] pids) { 4673 enforceNotIsolatedCaller("getProcessPss"); 4674 long[] pss = new long[pids.length]; 4675 for (int i=pids.length-1; i>=0; i--) { 4676 ProcessRecord proc; 4677 int oomAdj; 4678 synchronized (this) { 4679 synchronized (mPidsSelfLocked) { 4680 proc = mPidsSelfLocked.get(pids[i]); 4681 oomAdj = proc != null ? proc.setAdj : 0; 4682 } 4683 } 4684 long[] tmpUss = new long[1]; 4685 pss[i] = Debug.getPss(pids[i], tmpUss); 4686 if (proc != null) { 4687 synchronized (this) { 4688 if (proc.thread != null && proc.setAdj == oomAdj) { 4689 // Record this for posterity if the process has been stable. 4690 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4691 } 4692 } 4693 } 4694 } 4695 return pss; 4696 } 4697 4698 @Override 4699 public void killApplicationProcess(String processName, int uid) { 4700 if (processName == null) { 4701 return; 4702 } 4703 4704 int callerUid = Binder.getCallingUid(); 4705 // Only the system server can kill an application 4706 if (callerUid == Process.SYSTEM_UID) { 4707 synchronized (this) { 4708 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4709 if (app != null && app.thread != null) { 4710 try { 4711 app.thread.scheduleSuicide(); 4712 } catch (RemoteException e) { 4713 // If the other end already died, then our work here is done. 4714 } 4715 } else { 4716 Slog.w(TAG, "Process/uid not found attempting kill of " 4717 + processName + " / " + uid); 4718 } 4719 } 4720 } else { 4721 throw new SecurityException(callerUid + " cannot kill app process: " + 4722 processName); 4723 } 4724 } 4725 4726 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4727 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4728 false, true, false, false, UserHandle.getUserId(uid), reason); 4729 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4730 Uri.fromParts("package", packageName, null)); 4731 if (!mProcessesReady) { 4732 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4733 | Intent.FLAG_RECEIVER_FOREGROUND); 4734 } 4735 intent.putExtra(Intent.EXTRA_UID, uid); 4736 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4737 broadcastIntentLocked(null, null, intent, 4738 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4739 false, false, 4740 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4741 } 4742 4743 private void forceStopUserLocked(int userId, String reason) { 4744 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4745 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4746 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4747 | Intent.FLAG_RECEIVER_FOREGROUND); 4748 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4749 broadcastIntentLocked(null, null, intent, 4750 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4751 false, false, 4752 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4753 } 4754 4755 private final boolean killPackageProcessesLocked(String packageName, int appId, 4756 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4757 boolean doit, boolean evenPersistent, String reason) { 4758 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4759 4760 // Remove all processes this package may have touched: all with the 4761 // same UID (except for the system or root user), and all whose name 4762 // matches the package name. 4763 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4764 final int NP = mProcessNames.getMap().size(); 4765 for (int ip=0; ip<NP; ip++) { 4766 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4767 final int NA = apps.size(); 4768 for (int ia=0; ia<NA; ia++) { 4769 ProcessRecord app = apps.valueAt(ia); 4770 if (app.persistent && !evenPersistent) { 4771 // we don't kill persistent processes 4772 continue; 4773 } 4774 if (app.removed) { 4775 if (doit) { 4776 procs.add(app); 4777 } 4778 continue; 4779 } 4780 4781 // Skip process if it doesn't meet our oom adj requirement. 4782 if (app.setAdj < minOomAdj) { 4783 continue; 4784 } 4785 4786 // If no package is specified, we call all processes under the 4787 // give user id. 4788 if (packageName == null) { 4789 if (app.userId != userId) { 4790 continue; 4791 } 4792 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4793 continue; 4794 } 4795 // Package has been specified, we want to hit all processes 4796 // that match it. We need to qualify this by the processes 4797 // that are running under the specified app and user ID. 4798 } else { 4799 if (UserHandle.getAppId(app.uid) != appId) { 4800 continue; 4801 } 4802 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4803 continue; 4804 } 4805 if (!app.pkgList.containsKey(packageName)) { 4806 continue; 4807 } 4808 } 4809 4810 // Process has passed all conditions, kill it! 4811 if (!doit) { 4812 return true; 4813 } 4814 app.removed = true; 4815 procs.add(app); 4816 } 4817 } 4818 4819 int N = procs.size(); 4820 for (int i=0; i<N; i++) { 4821 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4822 } 4823 updateOomAdjLocked(); 4824 return N > 0; 4825 } 4826 4827 private final boolean forceStopPackageLocked(String name, int appId, 4828 boolean callerWillRestart, boolean purgeCache, boolean doit, 4829 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4830 int i; 4831 int N; 4832 4833 if (userId == UserHandle.USER_ALL && name == null) { 4834 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4835 } 4836 4837 if (appId < 0 && name != null) { 4838 try { 4839 appId = UserHandle.getAppId( 4840 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4841 } catch (RemoteException e) { 4842 } 4843 } 4844 4845 if (doit) { 4846 if (name != null) { 4847 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4848 + " user=" + userId + ": " + reason); 4849 } else { 4850 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4851 } 4852 4853 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4854 for (int ip=pmap.size()-1; ip>=0; ip--) { 4855 SparseArray<Long> ba = pmap.valueAt(ip); 4856 for (i=ba.size()-1; i>=0; i--) { 4857 boolean remove = false; 4858 final int entUid = ba.keyAt(i); 4859 if (name != null) { 4860 if (userId == UserHandle.USER_ALL) { 4861 if (UserHandle.getAppId(entUid) == appId) { 4862 remove = true; 4863 } 4864 } else { 4865 if (entUid == UserHandle.getUid(userId, appId)) { 4866 remove = true; 4867 } 4868 } 4869 } else if (UserHandle.getUserId(entUid) == userId) { 4870 remove = true; 4871 } 4872 if (remove) { 4873 ba.removeAt(i); 4874 } 4875 } 4876 if (ba.size() == 0) { 4877 pmap.removeAt(ip); 4878 } 4879 } 4880 } 4881 4882 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4883 -100, callerWillRestart, true, doit, evenPersistent, 4884 name == null ? ("stop user " + userId) : ("stop " + name)); 4885 4886 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4887 if (!doit) { 4888 return true; 4889 } 4890 didSomething = true; 4891 } 4892 4893 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4894 if (!doit) { 4895 return true; 4896 } 4897 didSomething = true; 4898 } 4899 4900 if (name == null) { 4901 // Remove all sticky broadcasts from this user. 4902 mStickyBroadcasts.remove(userId); 4903 } 4904 4905 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4906 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4907 userId, providers)) { 4908 if (!doit) { 4909 return true; 4910 } 4911 didSomething = true; 4912 } 4913 N = providers.size(); 4914 for (i=0; i<N; i++) { 4915 removeDyingProviderLocked(null, providers.get(i), true); 4916 } 4917 4918 // Remove transient permissions granted from/to this package/user 4919 removeUriPermissionsForPackageLocked(name, userId, false); 4920 4921 if (name == null || uninstalling) { 4922 // Remove pending intents. For now we only do this when force 4923 // stopping users, because we have some problems when doing this 4924 // for packages -- app widgets are not currently cleaned up for 4925 // such packages, so they can be left with bad pending intents. 4926 if (mIntentSenderRecords.size() > 0) { 4927 Iterator<WeakReference<PendingIntentRecord>> it 4928 = mIntentSenderRecords.values().iterator(); 4929 while (it.hasNext()) { 4930 WeakReference<PendingIntentRecord> wpir = it.next(); 4931 if (wpir == null) { 4932 it.remove(); 4933 continue; 4934 } 4935 PendingIntentRecord pir = wpir.get(); 4936 if (pir == null) { 4937 it.remove(); 4938 continue; 4939 } 4940 if (name == null) { 4941 // Stopping user, remove all objects for the user. 4942 if (pir.key.userId != userId) { 4943 // Not the same user, skip it. 4944 continue; 4945 } 4946 } else { 4947 if (UserHandle.getAppId(pir.uid) != appId) { 4948 // Different app id, skip it. 4949 continue; 4950 } 4951 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4952 // Different user, skip it. 4953 continue; 4954 } 4955 if (!pir.key.packageName.equals(name)) { 4956 // Different package, skip it. 4957 continue; 4958 } 4959 } 4960 if (!doit) { 4961 return true; 4962 } 4963 didSomething = true; 4964 it.remove(); 4965 pir.canceled = true; 4966 if (pir.key.activity != null) { 4967 pir.key.activity.pendingResults.remove(pir.ref); 4968 } 4969 } 4970 } 4971 } 4972 4973 if (doit) { 4974 if (purgeCache && name != null) { 4975 AttributeCache ac = AttributeCache.instance(); 4976 if (ac != null) { 4977 ac.removePackage(name); 4978 } 4979 } 4980 if (mBooted) { 4981 mStackSupervisor.resumeTopActivitiesLocked(); 4982 mStackSupervisor.scheduleIdleLocked(); 4983 } 4984 } 4985 4986 return didSomething; 4987 } 4988 4989 private final boolean removeProcessLocked(ProcessRecord app, 4990 boolean callerWillRestart, boolean allowRestart, String reason) { 4991 final String name = app.processName; 4992 final int uid = app.uid; 4993 if (DEBUG_PROCESSES) Slog.d( 4994 TAG, "Force removing proc " + app.toShortString() + " (" + name 4995 + "/" + uid + ")"); 4996 4997 mProcessNames.remove(name, uid); 4998 mIsolatedProcesses.remove(app.uid); 4999 if (mHeavyWeightProcess == app) { 5000 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5001 mHeavyWeightProcess.userId, 0)); 5002 mHeavyWeightProcess = null; 5003 } 5004 boolean needRestart = false; 5005 if (app.pid > 0 && app.pid != MY_PID) { 5006 int pid = app.pid; 5007 synchronized (mPidsSelfLocked) { 5008 mPidsSelfLocked.remove(pid); 5009 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5010 } 5011 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5012 app.processName, app.info.uid); 5013 if (app.isolated) { 5014 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5015 } 5016 killUnneededProcessLocked(app, reason); 5017 handleAppDiedLocked(app, true, allowRestart); 5018 removeLruProcessLocked(app); 5019 5020 if (app.persistent && !app.isolated) { 5021 if (!callerWillRestart) { 5022 addAppLocked(app.info, false); 5023 } else { 5024 needRestart = true; 5025 } 5026 } 5027 } else { 5028 mRemovedProcesses.add(app); 5029 } 5030 5031 return needRestart; 5032 } 5033 5034 private final void processStartTimedOutLocked(ProcessRecord app) { 5035 final int pid = app.pid; 5036 boolean gone = false; 5037 synchronized (mPidsSelfLocked) { 5038 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5039 if (knownApp != null && knownApp.thread == null) { 5040 mPidsSelfLocked.remove(pid); 5041 gone = true; 5042 } 5043 } 5044 5045 if (gone) { 5046 Slog.w(TAG, "Process " + app + " failed to attach"); 5047 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5048 pid, app.uid, app.processName); 5049 mProcessNames.remove(app.processName, app.uid); 5050 mIsolatedProcesses.remove(app.uid); 5051 if (mHeavyWeightProcess == app) { 5052 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5053 mHeavyWeightProcess.userId, 0)); 5054 mHeavyWeightProcess = null; 5055 } 5056 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5057 app.processName, app.info.uid); 5058 if (app.isolated) { 5059 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5060 } 5061 // Take care of any launching providers waiting for this process. 5062 checkAppInLaunchingProvidersLocked(app, true); 5063 // Take care of any services that are waiting for the process. 5064 mServices.processStartTimedOutLocked(app); 5065 killUnneededProcessLocked(app, "start timeout"); 5066 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5067 Slog.w(TAG, "Unattached app died before backup, skipping"); 5068 try { 5069 IBackupManager bm = IBackupManager.Stub.asInterface( 5070 ServiceManager.getService(Context.BACKUP_SERVICE)); 5071 bm.agentDisconnected(app.info.packageName); 5072 } catch (RemoteException e) { 5073 // Can't happen; the backup manager is local 5074 } 5075 } 5076 if (isPendingBroadcastProcessLocked(pid)) { 5077 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5078 skipPendingBroadcastLocked(pid); 5079 } 5080 } else { 5081 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5082 } 5083 } 5084 5085 private final boolean attachApplicationLocked(IApplicationThread thread, 5086 int pid) { 5087 5088 // Find the application record that is being attached... either via 5089 // the pid if we are running in multiple processes, or just pull the 5090 // next app record if we are emulating process with anonymous threads. 5091 ProcessRecord app; 5092 if (pid != MY_PID && pid >= 0) { 5093 synchronized (mPidsSelfLocked) { 5094 app = mPidsSelfLocked.get(pid); 5095 } 5096 } else { 5097 app = null; 5098 } 5099 5100 if (app == null) { 5101 Slog.w(TAG, "No pending application record for pid " + pid 5102 + " (IApplicationThread " + thread + "); dropping process"); 5103 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5104 if (pid > 0 && pid != MY_PID) { 5105 Process.killProcessQuiet(pid); 5106 } else { 5107 try { 5108 thread.scheduleExit(); 5109 } catch (Exception e) { 5110 // Ignore exceptions. 5111 } 5112 } 5113 return false; 5114 } 5115 5116 // If this application record is still attached to a previous 5117 // process, clean it up now. 5118 if (app.thread != null) { 5119 handleAppDiedLocked(app, true, true); 5120 } 5121 5122 // Tell the process all about itself. 5123 5124 if (localLOGV) Slog.v( 5125 TAG, "Binding process pid " + pid + " to record " + app); 5126 5127 final String processName = app.processName; 5128 try { 5129 AppDeathRecipient adr = new AppDeathRecipient( 5130 app, pid, thread); 5131 thread.asBinder().linkToDeath(adr, 0); 5132 app.deathRecipient = adr; 5133 } catch (RemoteException e) { 5134 app.resetPackageList(mProcessStats); 5135 startProcessLocked(app, "link fail", processName); 5136 return false; 5137 } 5138 5139 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5140 5141 app.makeActive(thread, mProcessStats); 5142 app.curAdj = app.setAdj = -100; 5143 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5144 app.forcingToForeground = null; 5145 updateProcessForegroundLocked(app, false, false); 5146 app.hasShownUi = false; 5147 app.debugging = false; 5148 app.cached = false; 5149 5150 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5151 5152 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5153 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5154 5155 if (!normalMode) { 5156 Slog.i(TAG, "Launching preboot mode app: " + app); 5157 } 5158 5159 if (localLOGV) Slog.v( 5160 TAG, "New app record " + app 5161 + " thread=" + thread.asBinder() + " pid=" + pid); 5162 try { 5163 int testMode = IApplicationThread.DEBUG_OFF; 5164 if (mDebugApp != null && mDebugApp.equals(processName)) { 5165 testMode = mWaitForDebugger 5166 ? IApplicationThread.DEBUG_WAIT 5167 : IApplicationThread.DEBUG_ON; 5168 app.debugging = true; 5169 if (mDebugTransient) { 5170 mDebugApp = mOrigDebugApp; 5171 mWaitForDebugger = mOrigWaitForDebugger; 5172 } 5173 } 5174 String profileFile = app.instrumentationProfileFile; 5175 ParcelFileDescriptor profileFd = null; 5176 boolean profileAutoStop = false; 5177 if (mProfileApp != null && mProfileApp.equals(processName)) { 5178 mProfileProc = app; 5179 profileFile = mProfileFile; 5180 profileFd = mProfileFd; 5181 profileAutoStop = mAutoStopProfiler; 5182 } 5183 boolean enableOpenGlTrace = false; 5184 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5185 enableOpenGlTrace = true; 5186 mOpenGlTraceApp = null; 5187 } 5188 5189 // If the app is being launched for restore or full backup, set it up specially 5190 boolean isRestrictedBackupMode = false; 5191 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5192 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5193 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5194 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5195 } 5196 5197 ensurePackageDexOpt(app.instrumentationInfo != null 5198 ? app.instrumentationInfo.packageName 5199 : app.info.packageName); 5200 if (app.instrumentationClass != null) { 5201 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5202 } 5203 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5204 + processName + " with config " + mConfiguration); 5205 ApplicationInfo appInfo = app.instrumentationInfo != null 5206 ? app.instrumentationInfo : app.info; 5207 app.compat = compatibilityInfoForPackageLocked(appInfo); 5208 if (profileFd != null) { 5209 profileFd = profileFd.dup(); 5210 } 5211 thread.bindApplication(processName, appInfo, providers, 5212 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5213 app.instrumentationArguments, app.instrumentationWatcher, 5214 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5215 isRestrictedBackupMode || !normalMode, app.persistent, 5216 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5217 mCoreSettingsObserver.getCoreSettingsLocked()); 5218 updateLruProcessLocked(app, false, null); 5219 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5220 } catch (Exception e) { 5221 // todo: Yikes! What should we do? For now we will try to 5222 // start another process, but that could easily get us in 5223 // an infinite loop of restarting processes... 5224 Slog.w(TAG, "Exception thrown during bind!", e); 5225 5226 app.resetPackageList(mProcessStats); 5227 app.unlinkDeathRecipient(); 5228 startProcessLocked(app, "bind fail", processName); 5229 return false; 5230 } 5231 5232 // Remove this record from the list of starting applications. 5233 mPersistentStartingProcesses.remove(app); 5234 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5235 "Attach application locked removing on hold: " + app); 5236 mProcessesOnHold.remove(app); 5237 5238 boolean badApp = false; 5239 boolean didSomething = false; 5240 5241 // See if the top visible activity is waiting to run in this process... 5242 if (normalMode) { 5243 try { 5244 if (mStackSupervisor.attachApplicationLocked(app)) { 5245 didSomething = true; 5246 } 5247 } catch (Exception e) { 5248 badApp = true; 5249 } 5250 } 5251 5252 // Find any services that should be running in this process... 5253 if (!badApp) { 5254 try { 5255 didSomething |= mServices.attachApplicationLocked(app, processName); 5256 } catch (Exception e) { 5257 badApp = true; 5258 } 5259 } 5260 5261 // Check if a next-broadcast receiver is in this process... 5262 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5263 try { 5264 didSomething |= sendPendingBroadcastsLocked(app); 5265 } catch (Exception e) { 5266 // If the app died trying to launch the receiver we declare it 'bad' 5267 badApp = true; 5268 } 5269 } 5270 5271 // Check whether the next backup agent is in this process... 5272 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5273 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5274 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5275 try { 5276 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5277 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5278 mBackupTarget.backupMode); 5279 } catch (Exception e) { 5280 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5281 e.printStackTrace(); 5282 } 5283 } 5284 5285 if (badApp) { 5286 // todo: Also need to kill application to deal with all 5287 // kinds of exceptions. 5288 handleAppDiedLocked(app, false, true); 5289 return false; 5290 } 5291 5292 if (!didSomething) { 5293 updateOomAdjLocked(); 5294 } 5295 5296 return true; 5297 } 5298 5299 @Override 5300 public final void attachApplication(IApplicationThread thread) { 5301 synchronized (this) { 5302 int callingPid = Binder.getCallingPid(); 5303 final long origId = Binder.clearCallingIdentity(); 5304 attachApplicationLocked(thread, callingPid); 5305 Binder.restoreCallingIdentity(origId); 5306 } 5307 } 5308 5309 @Override 5310 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5311 final long origId = Binder.clearCallingIdentity(); 5312 synchronized (this) { 5313 ActivityStack stack = ActivityRecord.getStackLocked(token); 5314 if (stack != null) { 5315 ActivityRecord r = 5316 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5317 if (stopProfiling) { 5318 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5319 try { 5320 mProfileFd.close(); 5321 } catch (IOException e) { 5322 } 5323 clearProfilerLocked(); 5324 } 5325 } 5326 } 5327 } 5328 Binder.restoreCallingIdentity(origId); 5329 } 5330 5331 void enableScreenAfterBoot() { 5332 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5333 SystemClock.uptimeMillis()); 5334 mWindowManager.enableScreenAfterBoot(); 5335 5336 synchronized (this) { 5337 updateEventDispatchingLocked(); 5338 } 5339 } 5340 5341 @Override 5342 public void showBootMessage(final CharSequence msg, final boolean always) { 5343 enforceNotIsolatedCaller("showBootMessage"); 5344 mWindowManager.showBootMessage(msg, always); 5345 } 5346 5347 @Override 5348 public void dismissKeyguardOnNextActivity() { 5349 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5350 final long token = Binder.clearCallingIdentity(); 5351 try { 5352 synchronized (this) { 5353 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5354 if (mLockScreenShown) { 5355 mLockScreenShown = false; 5356 comeOutOfSleepIfNeededLocked(); 5357 } 5358 mStackSupervisor.setDismissKeyguard(true); 5359 } 5360 } finally { 5361 Binder.restoreCallingIdentity(token); 5362 } 5363 } 5364 5365 final void finishBooting() { 5366 // Register receivers to handle package update events 5367 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5368 5369 synchronized (this) { 5370 // Ensure that any processes we had put on hold are now started 5371 // up. 5372 final int NP = mProcessesOnHold.size(); 5373 if (NP > 0) { 5374 ArrayList<ProcessRecord> procs = 5375 new ArrayList<ProcessRecord>(mProcessesOnHold); 5376 for (int ip=0; ip<NP; ip++) { 5377 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5378 + procs.get(ip)); 5379 startProcessLocked(procs.get(ip), "on-hold", null); 5380 } 5381 } 5382 5383 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5384 // Start looking for apps that are abusing wake locks. 5385 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5386 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5387 // Tell anyone interested that we are done booting! 5388 SystemProperties.set("sys.boot_completed", "1"); 5389 SystemProperties.set("dev.bootcomplete", "1"); 5390 for (int i=0; i<mStartedUsers.size(); i++) { 5391 UserStartedState uss = mStartedUsers.valueAt(i); 5392 if (uss.mState == UserStartedState.STATE_BOOTING) { 5393 uss.mState = UserStartedState.STATE_RUNNING; 5394 final int userId = mStartedUsers.keyAt(i); 5395 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5396 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5397 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5398 broadcastIntentLocked(null, null, intent, null, 5399 new IIntentReceiver.Stub() { 5400 @Override 5401 public void performReceive(Intent intent, int resultCode, 5402 String data, Bundle extras, boolean ordered, 5403 boolean sticky, int sendingUser) { 5404 synchronized (ActivityManagerService.this) { 5405 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5406 true, false); 5407 } 5408 } 5409 }, 5410 0, null, null, 5411 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5412 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5413 userId); 5414 } 5415 } 5416 scheduleStartProfilesLocked(); 5417 } 5418 } 5419 } 5420 5421 final void ensureBootCompleted() { 5422 boolean booting; 5423 boolean enableScreen; 5424 synchronized (this) { 5425 booting = mBooting; 5426 mBooting = false; 5427 enableScreen = !mBooted; 5428 mBooted = true; 5429 } 5430 5431 if (booting) { 5432 finishBooting(); 5433 } 5434 5435 if (enableScreen) { 5436 enableScreenAfterBoot(); 5437 } 5438 } 5439 5440 @Override 5441 public final void activityResumed(IBinder token) { 5442 final long origId = Binder.clearCallingIdentity(); 5443 synchronized(this) { 5444 ActivityStack stack = ActivityRecord.getStackLocked(token); 5445 if (stack != null) { 5446 ActivityRecord.activityResumedLocked(token); 5447 } 5448 } 5449 Binder.restoreCallingIdentity(origId); 5450 } 5451 5452 @Override 5453 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5454 final long origId = Binder.clearCallingIdentity(); 5455 synchronized(this) { 5456 ActivityStack stack = ActivityRecord.getStackLocked(token); 5457 if (stack != null) { 5458 stack.activityPausedLocked(token, false, persistentState); 5459 } 5460 } 5461 Binder.restoreCallingIdentity(origId); 5462 } 5463 5464 @Override 5465 public final void activityStopped(IBinder token, Bundle icicle, 5466 PersistableBundle persistentState, CharSequence description) { 5467 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5468 5469 // Refuse possible leaked file descriptors 5470 if (icicle != null && icicle.hasFileDescriptors()) { 5471 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5472 } 5473 5474 final long origId = Binder.clearCallingIdentity(); 5475 5476 synchronized (this) { 5477 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5478 if (r != null) { 5479 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5480 } 5481 } 5482 5483 trimApplications(); 5484 5485 Binder.restoreCallingIdentity(origId); 5486 } 5487 5488 @Override 5489 public final void activityDestroyed(IBinder token) { 5490 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5491 synchronized (this) { 5492 ActivityStack stack = ActivityRecord.getStackLocked(token); 5493 if (stack != null) { 5494 stack.activityDestroyedLocked(token); 5495 } 5496 } 5497 } 5498 5499 @Override 5500 public String getCallingPackage(IBinder token) { 5501 synchronized (this) { 5502 ActivityRecord r = getCallingRecordLocked(token); 5503 return r != null ? r.info.packageName : null; 5504 } 5505 } 5506 5507 @Override 5508 public ComponentName getCallingActivity(IBinder token) { 5509 synchronized (this) { 5510 ActivityRecord r = getCallingRecordLocked(token); 5511 return r != null ? r.intent.getComponent() : null; 5512 } 5513 } 5514 5515 private ActivityRecord getCallingRecordLocked(IBinder token) { 5516 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5517 if (r == null) { 5518 return null; 5519 } 5520 return r.resultTo; 5521 } 5522 5523 @Override 5524 public ComponentName getActivityClassForToken(IBinder token) { 5525 synchronized(this) { 5526 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5527 if (r == null) { 5528 return null; 5529 } 5530 return r.intent.getComponent(); 5531 } 5532 } 5533 5534 @Override 5535 public String getPackageForToken(IBinder token) { 5536 synchronized(this) { 5537 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5538 if (r == null) { 5539 return null; 5540 } 5541 return r.packageName; 5542 } 5543 } 5544 5545 @Override 5546 public IIntentSender getIntentSender(int type, 5547 String packageName, IBinder token, String resultWho, 5548 int requestCode, Intent[] intents, String[] resolvedTypes, 5549 int flags, Bundle options, int userId) { 5550 enforceNotIsolatedCaller("getIntentSender"); 5551 // Refuse possible leaked file descriptors 5552 if (intents != null) { 5553 if (intents.length < 1) { 5554 throw new IllegalArgumentException("Intents array length must be >= 1"); 5555 } 5556 for (int i=0; i<intents.length; i++) { 5557 Intent intent = intents[i]; 5558 if (intent != null) { 5559 if (intent.hasFileDescriptors()) { 5560 throw new IllegalArgumentException("File descriptors passed in Intent"); 5561 } 5562 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5563 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5564 throw new IllegalArgumentException( 5565 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5566 } 5567 intents[i] = new Intent(intent); 5568 } 5569 } 5570 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5571 throw new IllegalArgumentException( 5572 "Intent array length does not match resolvedTypes length"); 5573 } 5574 } 5575 if (options != null) { 5576 if (options.hasFileDescriptors()) { 5577 throw new IllegalArgumentException("File descriptors passed in options"); 5578 } 5579 } 5580 5581 synchronized(this) { 5582 int callingUid = Binder.getCallingUid(); 5583 int origUserId = userId; 5584 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5585 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5586 "getIntentSender", null); 5587 if (origUserId == UserHandle.USER_CURRENT) { 5588 // We don't want to evaluate this until the pending intent is 5589 // actually executed. However, we do want to always do the 5590 // security checking for it above. 5591 userId = UserHandle.USER_CURRENT; 5592 } 5593 try { 5594 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5595 int uid = AppGlobals.getPackageManager() 5596 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5597 if (!UserHandle.isSameApp(callingUid, uid)) { 5598 String msg = "Permission Denial: getIntentSender() from pid=" 5599 + Binder.getCallingPid() 5600 + ", uid=" + Binder.getCallingUid() 5601 + ", (need uid=" + uid + ")" 5602 + " is not allowed to send as package " + packageName; 5603 Slog.w(TAG, msg); 5604 throw new SecurityException(msg); 5605 } 5606 } 5607 5608 return getIntentSenderLocked(type, packageName, callingUid, userId, 5609 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5610 5611 } catch (RemoteException e) { 5612 throw new SecurityException(e); 5613 } 5614 } 5615 } 5616 5617 IIntentSender getIntentSenderLocked(int type, String packageName, 5618 int callingUid, int userId, IBinder token, String resultWho, 5619 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5620 Bundle options) { 5621 if (DEBUG_MU) 5622 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5623 ActivityRecord activity = null; 5624 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5625 activity = ActivityRecord.isInStackLocked(token); 5626 if (activity == null) { 5627 return null; 5628 } 5629 if (activity.finishing) { 5630 return null; 5631 } 5632 } 5633 5634 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5635 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5636 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5637 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5638 |PendingIntent.FLAG_UPDATE_CURRENT); 5639 5640 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5641 type, packageName, activity, resultWho, 5642 requestCode, intents, resolvedTypes, flags, options, userId); 5643 WeakReference<PendingIntentRecord> ref; 5644 ref = mIntentSenderRecords.get(key); 5645 PendingIntentRecord rec = ref != null ? ref.get() : null; 5646 if (rec != null) { 5647 if (!cancelCurrent) { 5648 if (updateCurrent) { 5649 if (rec.key.requestIntent != null) { 5650 rec.key.requestIntent.replaceExtras(intents != null ? 5651 intents[intents.length - 1] : null); 5652 } 5653 if (intents != null) { 5654 intents[intents.length-1] = rec.key.requestIntent; 5655 rec.key.allIntents = intents; 5656 rec.key.allResolvedTypes = resolvedTypes; 5657 } else { 5658 rec.key.allIntents = null; 5659 rec.key.allResolvedTypes = null; 5660 } 5661 } 5662 return rec; 5663 } 5664 rec.canceled = true; 5665 mIntentSenderRecords.remove(key); 5666 } 5667 if (noCreate) { 5668 return rec; 5669 } 5670 rec = new PendingIntentRecord(this, key, callingUid); 5671 mIntentSenderRecords.put(key, rec.ref); 5672 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5673 if (activity.pendingResults == null) { 5674 activity.pendingResults 5675 = new HashSet<WeakReference<PendingIntentRecord>>(); 5676 } 5677 activity.pendingResults.add(rec.ref); 5678 } 5679 return rec; 5680 } 5681 5682 @Override 5683 public void cancelIntentSender(IIntentSender sender) { 5684 if (!(sender instanceof PendingIntentRecord)) { 5685 return; 5686 } 5687 synchronized(this) { 5688 PendingIntentRecord rec = (PendingIntentRecord)sender; 5689 try { 5690 int uid = AppGlobals.getPackageManager() 5691 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5692 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5693 String msg = "Permission Denial: cancelIntentSender() from pid=" 5694 + Binder.getCallingPid() 5695 + ", uid=" + Binder.getCallingUid() 5696 + " is not allowed to cancel packges " 5697 + rec.key.packageName; 5698 Slog.w(TAG, msg); 5699 throw new SecurityException(msg); 5700 } 5701 } catch (RemoteException e) { 5702 throw new SecurityException(e); 5703 } 5704 cancelIntentSenderLocked(rec, true); 5705 } 5706 } 5707 5708 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5709 rec.canceled = true; 5710 mIntentSenderRecords.remove(rec.key); 5711 if (cleanActivity && rec.key.activity != null) { 5712 rec.key.activity.pendingResults.remove(rec.ref); 5713 } 5714 } 5715 5716 @Override 5717 public String getPackageForIntentSender(IIntentSender pendingResult) { 5718 if (!(pendingResult instanceof PendingIntentRecord)) { 5719 return null; 5720 } 5721 try { 5722 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5723 return res.key.packageName; 5724 } catch (ClassCastException e) { 5725 } 5726 return null; 5727 } 5728 5729 @Override 5730 public int getUidForIntentSender(IIntentSender sender) { 5731 if (sender instanceof PendingIntentRecord) { 5732 try { 5733 PendingIntentRecord res = (PendingIntentRecord)sender; 5734 return res.uid; 5735 } catch (ClassCastException e) { 5736 } 5737 } 5738 return -1; 5739 } 5740 5741 @Override 5742 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5743 if (!(pendingResult instanceof PendingIntentRecord)) { 5744 return false; 5745 } 5746 try { 5747 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5748 if (res.key.allIntents == null) { 5749 return false; 5750 } 5751 for (int i=0; i<res.key.allIntents.length; i++) { 5752 Intent intent = res.key.allIntents[i]; 5753 if (intent.getPackage() != null && intent.getComponent() != null) { 5754 return false; 5755 } 5756 } 5757 return true; 5758 } catch (ClassCastException e) { 5759 } 5760 return false; 5761 } 5762 5763 @Override 5764 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5765 if (!(pendingResult instanceof PendingIntentRecord)) { 5766 return false; 5767 } 5768 try { 5769 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5770 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5771 return true; 5772 } 5773 return false; 5774 } catch (ClassCastException e) { 5775 } 5776 return false; 5777 } 5778 5779 @Override 5780 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5781 if (!(pendingResult instanceof PendingIntentRecord)) { 5782 return null; 5783 } 5784 try { 5785 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5786 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5787 } catch (ClassCastException e) { 5788 } 5789 return null; 5790 } 5791 5792 @Override 5793 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5794 if (!(pendingResult instanceof PendingIntentRecord)) { 5795 return null; 5796 } 5797 try { 5798 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5799 Intent intent = res.key.requestIntent; 5800 if (intent != null) { 5801 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5802 || res.lastTagPrefix.equals(prefix))) { 5803 return res.lastTag; 5804 } 5805 res.lastTagPrefix = prefix; 5806 StringBuilder sb = new StringBuilder(128); 5807 if (prefix != null) { 5808 sb.append(prefix); 5809 } 5810 if (intent.getAction() != null) { 5811 sb.append(intent.getAction()); 5812 } else if (intent.getComponent() != null) { 5813 intent.getComponent().appendShortString(sb); 5814 } else { 5815 sb.append("?"); 5816 } 5817 return res.lastTag = sb.toString(); 5818 } 5819 } catch (ClassCastException e) { 5820 } 5821 return null; 5822 } 5823 5824 @Override 5825 public void setProcessLimit(int max) { 5826 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5827 "setProcessLimit()"); 5828 synchronized (this) { 5829 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5830 mProcessLimitOverride = max; 5831 } 5832 trimApplications(); 5833 } 5834 5835 @Override 5836 public int getProcessLimit() { 5837 synchronized (this) { 5838 return mProcessLimitOverride; 5839 } 5840 } 5841 5842 void foregroundTokenDied(ForegroundToken token) { 5843 synchronized (ActivityManagerService.this) { 5844 synchronized (mPidsSelfLocked) { 5845 ForegroundToken cur 5846 = mForegroundProcesses.get(token.pid); 5847 if (cur != token) { 5848 return; 5849 } 5850 mForegroundProcesses.remove(token.pid); 5851 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5852 if (pr == null) { 5853 return; 5854 } 5855 pr.forcingToForeground = null; 5856 updateProcessForegroundLocked(pr, false, false); 5857 } 5858 updateOomAdjLocked(); 5859 } 5860 } 5861 5862 @Override 5863 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5864 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5865 "setProcessForeground()"); 5866 synchronized(this) { 5867 boolean changed = false; 5868 5869 synchronized (mPidsSelfLocked) { 5870 ProcessRecord pr = mPidsSelfLocked.get(pid); 5871 if (pr == null && isForeground) { 5872 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5873 return; 5874 } 5875 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5876 if (oldToken != null) { 5877 oldToken.token.unlinkToDeath(oldToken, 0); 5878 mForegroundProcesses.remove(pid); 5879 if (pr != null) { 5880 pr.forcingToForeground = null; 5881 } 5882 changed = true; 5883 } 5884 if (isForeground && token != null) { 5885 ForegroundToken newToken = new ForegroundToken() { 5886 @Override 5887 public void binderDied() { 5888 foregroundTokenDied(this); 5889 } 5890 }; 5891 newToken.pid = pid; 5892 newToken.token = token; 5893 try { 5894 token.linkToDeath(newToken, 0); 5895 mForegroundProcesses.put(pid, newToken); 5896 pr.forcingToForeground = token; 5897 changed = true; 5898 } catch (RemoteException e) { 5899 // If the process died while doing this, we will later 5900 // do the cleanup with the process death link. 5901 } 5902 } 5903 } 5904 5905 if (changed) { 5906 updateOomAdjLocked(); 5907 } 5908 } 5909 } 5910 5911 // ========================================================= 5912 // PERMISSIONS 5913 // ========================================================= 5914 5915 static class PermissionController extends IPermissionController.Stub { 5916 ActivityManagerService mActivityManagerService; 5917 PermissionController(ActivityManagerService activityManagerService) { 5918 mActivityManagerService = activityManagerService; 5919 } 5920 5921 @Override 5922 public boolean checkPermission(String permission, int pid, int uid) { 5923 return mActivityManagerService.checkPermission(permission, pid, 5924 uid) == PackageManager.PERMISSION_GRANTED; 5925 } 5926 } 5927 5928 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5929 @Override 5930 public int checkComponentPermission(String permission, int pid, int uid, 5931 int owningUid, boolean exported) { 5932 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5933 owningUid, exported); 5934 } 5935 5936 @Override 5937 public Object getAMSLock() { 5938 return ActivityManagerService.this; 5939 } 5940 } 5941 5942 /** 5943 * This can be called with or without the global lock held. 5944 */ 5945 int checkComponentPermission(String permission, int pid, int uid, 5946 int owningUid, boolean exported) { 5947 // We might be performing an operation on behalf of an indirect binder 5948 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5949 // client identity accordingly before proceeding. 5950 Identity tlsIdentity = sCallerIdentity.get(); 5951 if (tlsIdentity != null) { 5952 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5953 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5954 uid = tlsIdentity.uid; 5955 pid = tlsIdentity.pid; 5956 } 5957 5958 if (pid == MY_PID) { 5959 return PackageManager.PERMISSION_GRANTED; 5960 } 5961 5962 return ActivityManager.checkComponentPermission(permission, uid, 5963 owningUid, exported); 5964 } 5965 5966 /** 5967 * As the only public entry point for permissions checking, this method 5968 * can enforce the semantic that requesting a check on a null global 5969 * permission is automatically denied. (Internally a null permission 5970 * string is used when calling {@link #checkComponentPermission} in cases 5971 * when only uid-based security is needed.) 5972 * 5973 * This can be called with or without the global lock held. 5974 */ 5975 @Override 5976 public int checkPermission(String permission, int pid, int uid) { 5977 if (permission == null) { 5978 return PackageManager.PERMISSION_DENIED; 5979 } 5980 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5981 } 5982 5983 /** 5984 * Binder IPC calls go through the public entry point. 5985 * This can be called with or without the global lock held. 5986 */ 5987 int checkCallingPermission(String permission) { 5988 return checkPermission(permission, 5989 Binder.getCallingPid(), 5990 UserHandle.getAppId(Binder.getCallingUid())); 5991 } 5992 5993 /** 5994 * This can be called with or without the global lock held. 5995 */ 5996 void enforceCallingPermission(String permission, String func) { 5997 if (checkCallingPermission(permission) 5998 == PackageManager.PERMISSION_GRANTED) { 5999 return; 6000 } 6001 6002 String msg = "Permission Denial: " + func + " from pid=" 6003 + Binder.getCallingPid() 6004 + ", uid=" + Binder.getCallingUid() 6005 + " requires " + permission; 6006 Slog.w(TAG, msg); 6007 throw new SecurityException(msg); 6008 } 6009 6010 /** 6011 * Determine if UID is holding permissions required to access {@link Uri} in 6012 * the given {@link ProviderInfo}. Final permission checking is always done 6013 * in {@link ContentProvider}. 6014 */ 6015 private final boolean checkHoldingPermissionsLocked( 6016 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6017 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6018 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6019 6020 if (pi.applicationInfo.uid == uid) { 6021 return true; 6022 } else if (!pi.exported) { 6023 return false; 6024 } 6025 6026 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6027 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6028 try { 6029 // check if target holds top-level <provider> permissions 6030 if (!readMet && pi.readPermission != null 6031 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6032 readMet = true; 6033 } 6034 if (!writeMet && pi.writePermission != null 6035 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6036 writeMet = true; 6037 } 6038 6039 // track if unprotected read/write is allowed; any denied 6040 // <path-permission> below removes this ability 6041 boolean allowDefaultRead = pi.readPermission == null; 6042 boolean allowDefaultWrite = pi.writePermission == null; 6043 6044 // check if target holds any <path-permission> that match uri 6045 final PathPermission[] pps = pi.pathPermissions; 6046 if (pps != null) { 6047 final String path = grantUri.uri.getPath(); 6048 int i = pps.length; 6049 while (i > 0 && (!readMet || !writeMet)) { 6050 i--; 6051 PathPermission pp = pps[i]; 6052 if (pp.match(path)) { 6053 if (!readMet) { 6054 final String pprperm = pp.getReadPermission(); 6055 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6056 + pprperm + " for " + pp.getPath() 6057 + ": match=" + pp.match(path) 6058 + " check=" + pm.checkUidPermission(pprperm, uid)); 6059 if (pprperm != null) { 6060 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 6061 readMet = true; 6062 } else { 6063 allowDefaultRead = false; 6064 } 6065 } 6066 } 6067 if (!writeMet) { 6068 final String ppwperm = pp.getWritePermission(); 6069 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6070 + ppwperm + " for " + pp.getPath() 6071 + ": match=" + pp.match(path) 6072 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6073 if (ppwperm != null) { 6074 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 6075 writeMet = true; 6076 } else { 6077 allowDefaultWrite = false; 6078 } 6079 } 6080 } 6081 } 6082 } 6083 } 6084 6085 // grant unprotected <provider> read/write, if not blocked by 6086 // <path-permission> above 6087 if (allowDefaultRead) readMet = true; 6088 if (allowDefaultWrite) writeMet = true; 6089 6090 } catch (RemoteException e) { 6091 return false; 6092 } 6093 6094 return readMet && writeMet; 6095 } 6096 6097 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6098 ProviderInfo pi = null; 6099 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6100 if (cpr != null) { 6101 pi = cpr.info; 6102 } else { 6103 try { 6104 pi = AppGlobals.getPackageManager().resolveContentProvider( 6105 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6106 } catch (RemoteException ex) { 6107 } 6108 } 6109 return pi; 6110 } 6111 6112 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6113 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6114 if (targetUris != null) { 6115 return targetUris.get(grantUri); 6116 } 6117 return null; 6118 } 6119 6120 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6121 String targetPkg, int targetUid, GrantUri grantUri) { 6122 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6123 if (targetUris == null) { 6124 targetUris = Maps.newArrayMap(); 6125 mGrantedUriPermissions.put(targetUid, targetUris); 6126 } 6127 6128 UriPermission perm = targetUris.get(grantUri); 6129 if (perm == null) { 6130 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6131 targetUris.put(grantUri, perm); 6132 } 6133 6134 return perm; 6135 } 6136 6137 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6138 final int modeFlags) { 6139 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6140 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6141 : UriPermission.STRENGTH_OWNED; 6142 6143 // Root gets to do everything. 6144 if (uid == 0) { 6145 return true; 6146 } 6147 6148 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6149 if (perms == null) return false; 6150 6151 // First look for exact match 6152 final UriPermission exactPerm = perms.get(grantUri); 6153 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6154 return true; 6155 } 6156 6157 // No exact match, look for prefixes 6158 final int N = perms.size(); 6159 for (int i = 0; i < N; i++) { 6160 final UriPermission perm = perms.valueAt(i); 6161 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6162 && perm.getStrength(modeFlags) >= minStrength) { 6163 return true; 6164 } 6165 } 6166 6167 return false; 6168 } 6169 6170 @Override 6171 public int checkUriPermission(Uri uri, int pid, int uid, 6172 final int modeFlags, int userId) { 6173 enforceNotIsolatedCaller("checkUriPermission"); 6174 6175 // Another redirected-binder-call permissions check as in 6176 // {@link checkComponentPermission}. 6177 Identity tlsIdentity = sCallerIdentity.get(); 6178 if (tlsIdentity != null) { 6179 uid = tlsIdentity.uid; 6180 pid = tlsIdentity.pid; 6181 } 6182 6183 // Our own process gets to do everything. 6184 if (pid == MY_PID) { 6185 return PackageManager.PERMISSION_GRANTED; 6186 } 6187 synchronized (this) { 6188 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6189 ? PackageManager.PERMISSION_GRANTED 6190 : PackageManager.PERMISSION_DENIED; 6191 } 6192 } 6193 6194 /** 6195 * Check if the targetPkg can be granted permission to access uri by 6196 * the callingUid using the given modeFlags. Throws a security exception 6197 * if callingUid is not allowed to do this. Returns the uid of the target 6198 * if the URI permission grant should be performed; returns -1 if it is not 6199 * needed (for example targetPkg already has permission to access the URI). 6200 * If you already know the uid of the target, you can supply it in 6201 * lastTargetUid else set that to -1. 6202 */ 6203 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6204 final int modeFlags, int lastTargetUid) { 6205 if (!Intent.isAccessUriMode(modeFlags)) { 6206 return -1; 6207 } 6208 6209 if (targetPkg != null) { 6210 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6211 "Checking grant " + targetPkg + " permission to " + grantUri); 6212 } 6213 6214 final IPackageManager pm = AppGlobals.getPackageManager(); 6215 6216 // If this is not a content: uri, we can't do anything with it. 6217 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6218 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6219 "Can't grant URI permission for non-content URI: " + grantUri); 6220 return -1; 6221 } 6222 6223 final String authority = grantUri.uri.getAuthority(); 6224 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6225 if (pi == null) { 6226 Slog.w(TAG, "No content provider found for permission check: " + 6227 grantUri.uri.toSafeString()); 6228 return -1; 6229 } 6230 6231 int targetUid = lastTargetUid; 6232 if (targetUid < 0 && targetPkg != null) { 6233 try { 6234 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6235 if (targetUid < 0) { 6236 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6237 "Can't grant URI permission no uid for: " + targetPkg); 6238 return -1; 6239 } 6240 } catch (RemoteException ex) { 6241 return -1; 6242 } 6243 } 6244 6245 if (targetUid >= 0) { 6246 // First... does the target actually need this permission? 6247 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6248 // No need to grant the target this permission. 6249 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6250 "Target " + targetPkg + " already has full permission to " + grantUri); 6251 return -1; 6252 } 6253 } else { 6254 // First... there is no target package, so can anyone access it? 6255 boolean allowed = pi.exported; 6256 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6257 if (pi.readPermission != null) { 6258 allowed = false; 6259 } 6260 } 6261 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6262 if (pi.writePermission != null) { 6263 allowed = false; 6264 } 6265 } 6266 if (allowed) { 6267 return -1; 6268 } 6269 } 6270 6271 // Second... is the provider allowing granting of URI permissions? 6272 if (!pi.grantUriPermissions) { 6273 throw new SecurityException("Provider " + pi.packageName 6274 + "/" + pi.name 6275 + " does not allow granting of Uri permissions (uri " 6276 + grantUri + ")"); 6277 } 6278 if (pi.uriPermissionPatterns != null) { 6279 final int N = pi.uriPermissionPatterns.length; 6280 boolean allowed = false; 6281 for (int i=0; i<N; i++) { 6282 if (pi.uriPermissionPatterns[i] != null 6283 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6284 allowed = true; 6285 break; 6286 } 6287 } 6288 if (!allowed) { 6289 throw new SecurityException("Provider " + pi.packageName 6290 + "/" + pi.name 6291 + " does not allow granting of permission to path of Uri " 6292 + grantUri); 6293 } 6294 } 6295 6296 // Third... does the caller itself have permission to access 6297 // this uri? 6298 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6299 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6300 // Require they hold a strong enough Uri permission 6301 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6302 throw new SecurityException("Uid " + callingUid 6303 + " does not have permission to uri " + grantUri); 6304 } 6305 } 6306 } 6307 return targetUid; 6308 } 6309 6310 @Override 6311 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6312 final int modeFlags, int userId) { 6313 enforceNotIsolatedCaller("checkGrantUriPermission"); 6314 synchronized(this) { 6315 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6316 new GrantUri(userId, uri, false), modeFlags, -1); 6317 } 6318 } 6319 6320 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6321 final int modeFlags, UriPermissionOwner owner) { 6322 if (!Intent.isAccessUriMode(modeFlags)) { 6323 return; 6324 } 6325 6326 // So here we are: the caller has the assumed permission 6327 // to the uri, and the target doesn't. Let's now give this to 6328 // the target. 6329 6330 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6331 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6332 6333 final String authority = grantUri.uri.getAuthority(); 6334 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6335 if (pi == null) { 6336 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6337 return; 6338 } 6339 6340 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6341 grantUri.prefix = true; 6342 } 6343 final UriPermission perm = findOrCreateUriPermissionLocked( 6344 pi.packageName, targetPkg, targetUid, grantUri); 6345 perm.grantModes(modeFlags, owner); 6346 } 6347 6348 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6349 final int modeFlags, UriPermissionOwner owner) { 6350 if (targetPkg == null) { 6351 throw new NullPointerException("targetPkg"); 6352 } 6353 6354 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6355 -1); 6356 if (targetUid < 0) { 6357 return; 6358 } 6359 6360 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6361 owner); 6362 } 6363 6364 static class NeededUriGrants extends ArrayList<GrantUri> { 6365 final String targetPkg; 6366 final int targetUid; 6367 final int flags; 6368 6369 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6370 this.targetPkg = targetPkg; 6371 this.targetUid = targetUid; 6372 this.flags = flags; 6373 } 6374 } 6375 6376 /** 6377 * Like checkGrantUriPermissionLocked, but takes an Intent. 6378 */ 6379 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6380 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6381 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6382 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6383 + " clip=" + (intent != null ? intent.getClipData() : null) 6384 + " from " + intent + "; flags=0x" 6385 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6386 6387 if (targetPkg == null) { 6388 throw new NullPointerException("targetPkg"); 6389 } 6390 6391 if (intent == null) { 6392 return null; 6393 } 6394 Uri data = intent.getData(); 6395 ClipData clip = intent.getClipData(); 6396 if (data == null && clip == null) { 6397 return null; 6398 } 6399 6400 if (data != null) { 6401 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data); 6402 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6403 needed != null ? needed.targetUid : -1); 6404 if (targetUid > 0) { 6405 if (needed == null) { 6406 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6407 } 6408 needed.add(grantUri); 6409 } 6410 } 6411 if (clip != null) { 6412 for (int i=0; i<clip.getItemCount(); i++) { 6413 Uri uri = clip.getItemAt(i).getUri(); 6414 if (uri != null) { 6415 int targetUid = -1; 6416 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri); 6417 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6418 needed != null ? needed.targetUid : -1); 6419 if (targetUid > 0) { 6420 if (needed == null) { 6421 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6422 } 6423 needed.add(grantUri); 6424 } 6425 } else { 6426 Intent clipIntent = clip.getItemAt(i).getIntent(); 6427 if (clipIntent != null) { 6428 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6429 callingUid, targetPkg, clipIntent, mode, needed); 6430 if (newNeeded != null) { 6431 needed = newNeeded; 6432 } 6433 } 6434 } 6435 } 6436 } 6437 6438 return needed; 6439 } 6440 6441 /** 6442 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6443 */ 6444 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6445 UriPermissionOwner owner) { 6446 if (needed != null) { 6447 for (int i=0; i<needed.size(); i++) { 6448 GrantUri grantUri = needed.get(i); 6449 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6450 grantUri, needed.flags, owner); 6451 } 6452 } 6453 } 6454 6455 void grantUriPermissionFromIntentLocked(int callingUid, 6456 String targetPkg, Intent intent, UriPermissionOwner owner) { 6457 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6458 intent, intent != null ? intent.getFlags() : 0, null); 6459 if (needed == null) { 6460 return; 6461 } 6462 6463 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6464 } 6465 6466 @Override 6467 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6468 final int modeFlags, int userId) { 6469 enforceNotIsolatedCaller("grantUriPermission"); 6470 GrantUri grantUri = new GrantUri(userId, uri, false); 6471 synchronized(this) { 6472 final ProcessRecord r = getRecordForAppLocked(caller); 6473 if (r == null) { 6474 throw new SecurityException("Unable to find app for caller " 6475 + caller 6476 + " when granting permission to uri " + grantUri); 6477 } 6478 if (targetPkg == null) { 6479 throw new IllegalArgumentException("null target"); 6480 } 6481 if (grantUri == null) { 6482 throw new IllegalArgumentException("null uri"); 6483 } 6484 6485 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6486 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6487 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6488 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6489 6490 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null); 6491 } 6492 } 6493 6494 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6495 if (perm.modeFlags == 0) { 6496 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6497 perm.targetUid); 6498 if (perms != null) { 6499 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6500 "Removing " + perm.targetUid + " permission to " + perm.uri); 6501 6502 perms.remove(perm.uri); 6503 if (perms.isEmpty()) { 6504 mGrantedUriPermissions.remove(perm.targetUid); 6505 } 6506 } 6507 } 6508 } 6509 6510 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 6511 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 6512 6513 final IPackageManager pm = AppGlobals.getPackageManager(); 6514 final String authority = grantUri.uri.getAuthority(); 6515 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6516 if (pi == null) { 6517 Slog.w(TAG, "No content provider found for permission revoke: " 6518 + grantUri.toSafeString()); 6519 return; 6520 } 6521 6522 // Does the caller have this permission on the URI? 6523 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6524 // Right now, if you are not the original owner of the permission, 6525 // you are not allowed to revoke it. 6526 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6527 throw new SecurityException("Uid " + callingUid 6528 + " does not have permission to uri " + grantUri); 6529 //} 6530 } 6531 6532 boolean persistChanged = false; 6533 6534 // Go through all of the permissions and remove any that match. 6535 int N = mGrantedUriPermissions.size(); 6536 for (int i = 0; i < N; i++) { 6537 final int targetUid = mGrantedUriPermissions.keyAt(i); 6538 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6539 6540 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6541 final UriPermission perm = it.next(); 6542 if (perm.uri.sourceUserId == grantUri.sourceUserId 6543 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 6544 if (DEBUG_URI_PERMISSION) 6545 Slog.v(TAG, 6546 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6547 persistChanged |= perm.revokeModes( 6548 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6549 if (perm.modeFlags == 0) { 6550 it.remove(); 6551 } 6552 } 6553 } 6554 6555 if (perms.isEmpty()) { 6556 mGrantedUriPermissions.remove(targetUid); 6557 N--; 6558 i--; 6559 } 6560 } 6561 6562 if (persistChanged) { 6563 schedulePersistUriGrants(); 6564 } 6565 } 6566 6567 @Override 6568 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 6569 int userId) { 6570 enforceNotIsolatedCaller("revokeUriPermission"); 6571 synchronized(this) { 6572 final ProcessRecord r = getRecordForAppLocked(caller); 6573 if (r == null) { 6574 throw new SecurityException("Unable to find app for caller " 6575 + caller 6576 + " when revoking permission to uri " + uri); 6577 } 6578 if (uri == null) { 6579 Slog.w(TAG, "revokeUriPermission: null uri"); 6580 return; 6581 } 6582 6583 if (!Intent.isAccessUriMode(modeFlags)) { 6584 return; 6585 } 6586 6587 final IPackageManager pm = AppGlobals.getPackageManager(); 6588 final String authority = uri.getAuthority(); 6589 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 6590 if (pi == null) { 6591 Slog.w(TAG, "No content provider found for permission revoke: " 6592 + uri.toSafeString()); 6593 return; 6594 } 6595 6596 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 6597 } 6598 } 6599 6600 /** 6601 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6602 * given package. 6603 * 6604 * @param packageName Package name to match, or {@code null} to apply to all 6605 * packages. 6606 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6607 * to all users. 6608 * @param persistable If persistable grants should be removed. 6609 */ 6610 private void removeUriPermissionsForPackageLocked( 6611 String packageName, int userHandle, boolean persistable) { 6612 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6613 throw new IllegalArgumentException("Must narrow by either package or user"); 6614 } 6615 6616 boolean persistChanged = false; 6617 6618 int N = mGrantedUriPermissions.size(); 6619 for (int i = 0; i < N; i++) { 6620 final int targetUid = mGrantedUriPermissions.keyAt(i); 6621 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6622 6623 // Only inspect grants matching user 6624 if (userHandle == UserHandle.USER_ALL 6625 || userHandle == UserHandle.getUserId(targetUid)) { 6626 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6627 final UriPermission perm = it.next(); 6628 6629 // Only inspect grants matching package 6630 if (packageName == null || perm.sourcePkg.equals(packageName) 6631 || perm.targetPkg.equals(packageName)) { 6632 persistChanged |= perm.revokeModes( 6633 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6634 6635 // Only remove when no modes remain; any persisted grants 6636 // will keep this alive. 6637 if (perm.modeFlags == 0) { 6638 it.remove(); 6639 } 6640 } 6641 } 6642 6643 if (perms.isEmpty()) { 6644 mGrantedUriPermissions.remove(targetUid); 6645 N--; 6646 i--; 6647 } 6648 } 6649 } 6650 6651 if (persistChanged) { 6652 schedulePersistUriGrants(); 6653 } 6654 } 6655 6656 @Override 6657 public IBinder newUriPermissionOwner(String name) { 6658 enforceNotIsolatedCaller("newUriPermissionOwner"); 6659 synchronized(this) { 6660 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6661 return owner.getExternalTokenLocked(); 6662 } 6663 } 6664 6665 @Override 6666 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 6667 final int modeFlags, int userId) { 6668 synchronized(this) { 6669 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6670 if (owner == null) { 6671 throw new IllegalArgumentException("Unknown owner: " + token); 6672 } 6673 if (fromUid != Binder.getCallingUid()) { 6674 if (Binder.getCallingUid() != Process.myUid()) { 6675 // Only system code can grant URI permissions on behalf 6676 // of other users. 6677 throw new SecurityException("nice try"); 6678 } 6679 } 6680 if (targetPkg == null) { 6681 throw new IllegalArgumentException("null target"); 6682 } 6683 if (uri == null) { 6684 throw new IllegalArgumentException("null uri"); 6685 } 6686 6687 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false), 6688 modeFlags, owner); 6689 } 6690 } 6691 6692 @Override 6693 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 6694 synchronized(this) { 6695 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6696 if (owner == null) { 6697 throw new IllegalArgumentException("Unknown owner: " + token); 6698 } 6699 6700 if (uri == null) { 6701 owner.removeUriPermissionsLocked(mode); 6702 } else { 6703 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 6704 } 6705 } 6706 } 6707 6708 private void schedulePersistUriGrants() { 6709 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6710 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6711 10 * DateUtils.SECOND_IN_MILLIS); 6712 } 6713 } 6714 6715 private void writeGrantedUriPermissions() { 6716 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6717 6718 // Snapshot permissions so we can persist without lock 6719 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6720 synchronized (this) { 6721 final int size = mGrantedUriPermissions.size(); 6722 for (int i = 0; i < size; i++) { 6723 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6724 for (UriPermission perm : perms.values()) { 6725 if (perm.persistedModeFlags != 0) { 6726 persist.add(perm.snapshot()); 6727 } 6728 } 6729 } 6730 } 6731 6732 FileOutputStream fos = null; 6733 try { 6734 fos = mGrantFile.startWrite(); 6735 6736 XmlSerializer out = new FastXmlSerializer(); 6737 out.setOutput(fos, "utf-8"); 6738 out.startDocument(null, true); 6739 out.startTag(null, TAG_URI_GRANTS); 6740 for (UriPermission.Snapshot perm : persist) { 6741 out.startTag(null, TAG_URI_GRANT); 6742 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 6743 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 6744 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6745 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6746 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6747 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6748 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6749 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6750 out.endTag(null, TAG_URI_GRANT); 6751 } 6752 out.endTag(null, TAG_URI_GRANTS); 6753 out.endDocument(); 6754 6755 mGrantFile.finishWrite(fos); 6756 } catch (IOException e) { 6757 if (fos != null) { 6758 mGrantFile.failWrite(fos); 6759 } 6760 } 6761 } 6762 6763 private void readGrantedUriPermissionsLocked() { 6764 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6765 6766 final long now = System.currentTimeMillis(); 6767 6768 FileInputStream fis = null; 6769 try { 6770 fis = mGrantFile.openRead(); 6771 final XmlPullParser in = Xml.newPullParser(); 6772 in.setInput(fis, null); 6773 6774 int type; 6775 while ((type = in.next()) != END_DOCUMENT) { 6776 final String tag = in.getName(); 6777 if (type == START_TAG) { 6778 if (TAG_URI_GRANT.equals(tag)) { 6779 final int sourceUserId; 6780 final int targetUserId; 6781 final int userHandle = readIntAttribute(in, 6782 ATTR_USER_HANDLE, UserHandle.USER_NULL); 6783 if (userHandle != UserHandle.USER_NULL) { 6784 // For backwards compatibility. 6785 sourceUserId = userHandle; 6786 targetUserId = userHandle; 6787 } else { 6788 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 6789 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 6790 } 6791 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6792 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6793 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6794 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6795 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6796 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6797 6798 // Sanity check that provider still belongs to source package 6799 final ProviderInfo pi = getProviderInfoLocked( 6800 uri.getAuthority(), sourceUserId); 6801 if (pi != null && sourcePkg.equals(pi.packageName)) { 6802 int targetUid = -1; 6803 try { 6804 targetUid = AppGlobals.getPackageManager() 6805 .getPackageUid(targetPkg, targetUserId); 6806 } catch (RemoteException e) { 6807 } 6808 if (targetUid != -1) { 6809 final UriPermission perm = findOrCreateUriPermissionLocked( 6810 sourcePkg, targetPkg, targetUid, 6811 new GrantUri(sourceUserId, uri, prefix)); 6812 perm.initPersistedModes(modeFlags, createdTime); 6813 } 6814 } else { 6815 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6816 + " but instead found " + pi); 6817 } 6818 } 6819 } 6820 } 6821 } catch (FileNotFoundException e) { 6822 // Missing grants is okay 6823 } catch (IOException e) { 6824 Log.wtf(TAG, "Failed reading Uri grants", e); 6825 } catch (XmlPullParserException e) { 6826 Log.wtf(TAG, "Failed reading Uri grants", e); 6827 } finally { 6828 IoUtils.closeQuietly(fis); 6829 } 6830 } 6831 6832 @Override 6833 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6834 enforceNotIsolatedCaller("takePersistableUriPermission"); 6835 6836 Preconditions.checkFlagsArgument(modeFlags, 6837 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6838 6839 synchronized (this) { 6840 final int callingUid = Binder.getCallingUid(); 6841 boolean persistChanged = false; 6842 GrantUri grantUri = new GrantUri(userId, uri, false); 6843 6844 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6845 new GrantUri(userId, uri, false)); 6846 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6847 new GrantUri(userId, uri, true)); 6848 6849 final boolean exactValid = (exactPerm != null) 6850 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6851 final boolean prefixValid = (prefixPerm != null) 6852 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6853 6854 if (!(exactValid || prefixValid)) { 6855 throw new SecurityException("No persistable permission grants found for UID " 6856 + callingUid + " and Uri " + grantUri.toSafeString()); 6857 } 6858 6859 if (exactValid) { 6860 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6861 } 6862 if (prefixValid) { 6863 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6864 } 6865 6866 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6867 6868 if (persistChanged) { 6869 schedulePersistUriGrants(); 6870 } 6871 } 6872 } 6873 6874 @Override 6875 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6876 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6877 6878 Preconditions.checkFlagsArgument(modeFlags, 6879 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6880 6881 synchronized (this) { 6882 final int callingUid = Binder.getCallingUid(); 6883 boolean persistChanged = false; 6884 6885 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6886 new GrantUri(userId, uri, false)); 6887 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6888 new GrantUri(userId, uri, true)); 6889 if (exactPerm == null && prefixPerm == null) { 6890 throw new SecurityException("No permission grants found for UID " + callingUid 6891 + " and Uri " + uri.toSafeString()); 6892 } 6893 6894 if (exactPerm != null) { 6895 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6896 removeUriPermissionIfNeededLocked(exactPerm); 6897 } 6898 if (prefixPerm != null) { 6899 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6900 removeUriPermissionIfNeededLocked(prefixPerm); 6901 } 6902 6903 if (persistChanged) { 6904 schedulePersistUriGrants(); 6905 } 6906 } 6907 } 6908 6909 /** 6910 * Prune any older {@link UriPermission} for the given UID until outstanding 6911 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6912 * 6913 * @return if any mutations occured that require persisting. 6914 */ 6915 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6916 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6917 if (perms == null) return false; 6918 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6919 6920 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6921 for (UriPermission perm : perms.values()) { 6922 if (perm.persistedModeFlags != 0) { 6923 persisted.add(perm); 6924 } 6925 } 6926 6927 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6928 if (trimCount <= 0) return false; 6929 6930 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6931 for (int i = 0; i < trimCount; i++) { 6932 final UriPermission perm = persisted.get(i); 6933 6934 if (DEBUG_URI_PERMISSION) { 6935 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6936 } 6937 6938 perm.releasePersistableModes(~0); 6939 removeUriPermissionIfNeededLocked(perm); 6940 } 6941 6942 return true; 6943 } 6944 6945 @Override 6946 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6947 String packageName, boolean incoming) { 6948 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6949 Preconditions.checkNotNull(packageName, "packageName"); 6950 6951 final int callingUid = Binder.getCallingUid(); 6952 final IPackageManager pm = AppGlobals.getPackageManager(); 6953 try { 6954 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6955 if (packageUid != callingUid) { 6956 throw new SecurityException( 6957 "Package " + packageName + " does not belong to calling UID " + callingUid); 6958 } 6959 } catch (RemoteException e) { 6960 throw new SecurityException("Failed to verify package name ownership"); 6961 } 6962 6963 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6964 synchronized (this) { 6965 if (incoming) { 6966 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6967 callingUid); 6968 if (perms == null) { 6969 Slog.w(TAG, "No permission grants found for " + packageName); 6970 } else { 6971 for (UriPermission perm : perms.values()) { 6972 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6973 result.add(perm.buildPersistedPublicApiObject()); 6974 } 6975 } 6976 } 6977 } else { 6978 final int size = mGrantedUriPermissions.size(); 6979 for (int i = 0; i < size; i++) { 6980 final ArrayMap<GrantUri, UriPermission> perms = 6981 mGrantedUriPermissions.valueAt(i); 6982 for (UriPermission perm : perms.values()) { 6983 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6984 result.add(perm.buildPersistedPublicApiObject()); 6985 } 6986 } 6987 } 6988 } 6989 } 6990 return new ParceledListSlice<android.content.UriPermission>(result); 6991 } 6992 6993 @Override 6994 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6995 synchronized (this) { 6996 ProcessRecord app = 6997 who != null ? getRecordForAppLocked(who) : null; 6998 if (app == null) return; 6999 7000 Message msg = Message.obtain(); 7001 msg.what = WAIT_FOR_DEBUGGER_MSG; 7002 msg.obj = app; 7003 msg.arg1 = waiting ? 1 : 0; 7004 mHandler.sendMessage(msg); 7005 } 7006 } 7007 7008 @Override 7009 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7010 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7011 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7012 outInfo.availMem = Process.getFreeMemory(); 7013 outInfo.totalMem = Process.getTotalMemory(); 7014 outInfo.threshold = homeAppMem; 7015 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7016 outInfo.hiddenAppThreshold = cachedAppMem; 7017 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7018 ProcessList.SERVICE_ADJ); 7019 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7020 ProcessList.VISIBLE_APP_ADJ); 7021 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7022 ProcessList.FOREGROUND_APP_ADJ); 7023 } 7024 7025 // ========================================================= 7026 // TASK MANAGEMENT 7027 // ========================================================= 7028 7029 @Override 7030 public List<IAppTask> getAppTasks() { 7031 int callingUid = Binder.getCallingUid(); 7032 long ident = Binder.clearCallingIdentity(); 7033 synchronized(this) { 7034 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7035 try { 7036 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7037 7038 final int N = mRecentTasks.size(); 7039 for (int i = 0; i < N; i++) { 7040 TaskRecord tr = mRecentTasks.get(i); 7041 // Skip tasks that are not created by the caller 7042 if (tr.creatorUid == callingUid) { 7043 ActivityManager.RecentTaskInfo taskInfo = 7044 createRecentTaskInfoFromTaskRecord(tr); 7045 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7046 list.add(taskImpl); 7047 } 7048 } 7049 } finally { 7050 Binder.restoreCallingIdentity(ident); 7051 } 7052 return list; 7053 } 7054 } 7055 7056 @Override 7057 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7058 final int callingUid = Binder.getCallingUid(); 7059 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7060 7061 synchronized(this) { 7062 if (localLOGV) Slog.v( 7063 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7064 7065 final boolean allowed = checkCallingPermission( 7066 android.Manifest.permission.GET_TASKS) 7067 == PackageManager.PERMISSION_GRANTED; 7068 if (!allowed) { 7069 Slog.w(TAG, "getTasks: caller " + callingUid 7070 + " does not hold GET_TASKS; limiting output"); 7071 } 7072 7073 // TODO: Improve with MRU list from all ActivityStacks. 7074 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7075 } 7076 7077 return list; 7078 } 7079 7080 TaskRecord getMostRecentTask() { 7081 return mRecentTasks.get(0); 7082 } 7083 7084 /** 7085 * Creates a new RecentTaskInfo from a TaskRecord. 7086 */ 7087 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7088 ActivityManager.RecentTaskInfo rti 7089 = new ActivityManager.RecentTaskInfo(); 7090 rti.id = tr.mActivities.isEmpty() ? -1 : tr.taskId; 7091 rti.persistentId = tr.taskId; 7092 rti.baseIntent = new Intent(tr.getBaseIntent()); 7093 rti.origActivity = tr.origActivity; 7094 rti.description = tr.lastDescription; 7095 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 7096 rti.userId = tr.userId; 7097 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7098 return rti; 7099 } 7100 7101 @Override 7102 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7103 int flags, int userId) { 7104 final int callingUid = Binder.getCallingUid(); 7105 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7106 false, true, "getRecentTasks", null); 7107 7108 synchronized (this) { 7109 final boolean allowed = checkCallingPermission( 7110 android.Manifest.permission.GET_TASKS) 7111 == PackageManager.PERMISSION_GRANTED; 7112 if (!allowed) { 7113 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7114 + " does not hold GET_TASKS; limiting output"); 7115 } 7116 final boolean detailed = checkCallingPermission( 7117 android.Manifest.permission.GET_DETAILED_TASKS) 7118 == PackageManager.PERMISSION_GRANTED; 7119 7120 IPackageManager pm = AppGlobals.getPackageManager(); 7121 7122 final int N = mRecentTasks.size(); 7123 ArrayList<ActivityManager.RecentTaskInfo> res 7124 = new ArrayList<ActivityManager.RecentTaskInfo>( 7125 maxNum < N ? maxNum : N); 7126 7127 final Set<Integer> includedUsers; 7128 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7129 includedUsers = getProfileIdsLocked(userId); 7130 } else { 7131 includedUsers = new HashSet<Integer>(); 7132 } 7133 includedUsers.add(Integer.valueOf(userId)); 7134 for (int i=0; i<N && maxNum > 0; i++) { 7135 TaskRecord tr = mRecentTasks.get(i); 7136 // Only add calling user or related users recent tasks 7137 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7138 7139 // Return the entry if desired by the caller. We always return 7140 // the first entry, because callers always expect this to be the 7141 // foreground app. We may filter others if the caller has 7142 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7143 // we should exclude the entry. 7144 7145 if (i == 0 7146 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7147 || (tr.intent == null) 7148 || ((tr.intent.getFlags() 7149 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7150 if (!allowed) { 7151 // If the caller doesn't have the GET_TASKS permission, then only 7152 // allow them to see a small subset of tasks -- their own and home. 7153 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7154 continue; 7155 } 7156 } 7157 7158 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7159 if (!detailed) { 7160 rti.baseIntent.replaceExtras((Bundle)null); 7161 } 7162 7163 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7164 // Check whether this activity is currently available. 7165 try { 7166 if (rti.origActivity != null) { 7167 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7168 == null) { 7169 continue; 7170 } 7171 } else if (rti.baseIntent != null) { 7172 if (pm.queryIntentActivities(rti.baseIntent, 7173 null, 0, userId) == null) { 7174 continue; 7175 } 7176 } 7177 } catch (RemoteException e) { 7178 // Will never happen. 7179 } 7180 } 7181 7182 res.add(rti); 7183 maxNum--; 7184 } 7185 } 7186 return res; 7187 } 7188 } 7189 7190 private TaskRecord recentTaskForIdLocked(int id) { 7191 final int N = mRecentTasks.size(); 7192 for (int i=0; i<N; i++) { 7193 TaskRecord tr = mRecentTasks.get(i); 7194 if (tr.taskId == id) { 7195 return tr; 7196 } 7197 } 7198 return null; 7199 } 7200 7201 @Override 7202 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7203 synchronized (this) { 7204 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7205 "getTaskThumbnails()"); 7206 TaskRecord tr = recentTaskForIdLocked(id); 7207 if (tr != null) { 7208 return tr.getTaskThumbnailsLocked(); 7209 } 7210 } 7211 return null; 7212 } 7213 7214 @Override 7215 public Bitmap getTaskTopThumbnail(int id) { 7216 synchronized (this) { 7217 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7218 "getTaskTopThumbnail()"); 7219 TaskRecord tr = recentTaskForIdLocked(id); 7220 if (tr != null) { 7221 return tr.getTaskTopThumbnailLocked(); 7222 } 7223 } 7224 return null; 7225 } 7226 7227 @Override 7228 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 7229 synchronized (this) { 7230 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7231 if (r != null) { 7232 r.taskDescription = td; 7233 r.task.updateTaskDescription(); 7234 } 7235 } 7236 } 7237 7238 @Override 7239 public boolean removeSubTask(int taskId, int subTaskIndex) { 7240 synchronized (this) { 7241 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7242 "removeSubTask()"); 7243 long ident = Binder.clearCallingIdentity(); 7244 try { 7245 TaskRecord tr = recentTaskForIdLocked(taskId); 7246 if (tr != null) { 7247 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7248 } 7249 return false; 7250 } finally { 7251 Binder.restoreCallingIdentity(ident); 7252 } 7253 } 7254 } 7255 7256 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7257 if (!pr.killedByAm) { 7258 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7259 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7260 pr.processName, pr.setAdj, reason); 7261 pr.killedByAm = true; 7262 Process.killProcessQuiet(pr.pid); 7263 } 7264 } 7265 7266 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7267 tr.disposeThumbnail(); 7268 mRecentTasks.remove(tr); 7269 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7270 Intent baseIntent = new Intent( 7271 tr.intent != null ? tr.intent : tr.affinityIntent); 7272 ComponentName component = baseIntent.getComponent(); 7273 if (component == null) { 7274 Slog.w(TAG, "Now component for base intent of task: " + tr); 7275 return; 7276 } 7277 7278 // Find any running services associated with this app. 7279 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7280 7281 if (killProcesses) { 7282 // Find any running processes associated with this app. 7283 final String pkg = component.getPackageName(); 7284 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7285 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7286 for (int i=0; i<pmap.size(); i++) { 7287 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7288 for (int j=0; j<uids.size(); j++) { 7289 ProcessRecord proc = uids.valueAt(j); 7290 if (proc.userId != tr.userId) { 7291 continue; 7292 } 7293 if (!proc.pkgList.containsKey(pkg)) { 7294 continue; 7295 } 7296 procs.add(proc); 7297 } 7298 } 7299 7300 // Kill the running processes. 7301 for (int i=0; i<procs.size(); i++) { 7302 ProcessRecord pr = procs.get(i); 7303 if (pr == mHomeProcess) { 7304 // Don't kill the home process along with tasks from the same package. 7305 continue; 7306 } 7307 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7308 killUnneededProcessLocked(pr, "remove task"); 7309 } else { 7310 pr.waitingToKill = "remove task"; 7311 } 7312 } 7313 } 7314 } 7315 7316 /** 7317 * Removes the task with the specified task id. 7318 * 7319 * @param taskId Identifier of the task to be removed. 7320 * @param flags Additional operational flags. May be 0 or 7321 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7322 * @return Returns true if the given task was found and removed. 7323 */ 7324 private boolean removeTaskByIdLocked(int taskId, int flags) { 7325 TaskRecord tr = recentTaskForIdLocked(taskId); 7326 if (tr != null) { 7327 tr.removeTaskActivitiesLocked(-1, false); 7328 cleanUpRemovedTaskLocked(tr, flags); 7329 if (tr.isPersistable) { 7330 notifyTaskPersisterLocked(tr, true); 7331 } 7332 return true; 7333 } 7334 return false; 7335 } 7336 7337 @Override 7338 public boolean removeTask(int taskId, int flags) { 7339 synchronized (this) { 7340 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7341 "removeTask()"); 7342 long ident = Binder.clearCallingIdentity(); 7343 try { 7344 return removeTaskByIdLocked(taskId, flags); 7345 } finally { 7346 Binder.restoreCallingIdentity(ident); 7347 } 7348 } 7349 } 7350 7351 /** 7352 * TODO: Add mController hook 7353 */ 7354 @Override 7355 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7356 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7357 "moveTaskToFront()"); 7358 7359 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7360 synchronized(this) { 7361 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7362 Binder.getCallingUid(), "Task to front")) { 7363 ActivityOptions.abort(options); 7364 return; 7365 } 7366 final long origId = Binder.clearCallingIdentity(); 7367 try { 7368 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7369 if (task == null) { 7370 return; 7371 } 7372 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7373 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7374 return; 7375 } 7376 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7377 } finally { 7378 Binder.restoreCallingIdentity(origId); 7379 } 7380 ActivityOptions.abort(options); 7381 } 7382 } 7383 7384 @Override 7385 public void moveTaskToBack(int taskId) { 7386 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7387 "moveTaskToBack()"); 7388 7389 synchronized(this) { 7390 TaskRecord tr = recentTaskForIdLocked(taskId); 7391 if (tr != null) { 7392 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7393 ActivityStack stack = tr.stack; 7394 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7395 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7396 Binder.getCallingUid(), "Task to back")) { 7397 return; 7398 } 7399 } 7400 final long origId = Binder.clearCallingIdentity(); 7401 try { 7402 stack.moveTaskToBackLocked(taskId, null); 7403 } finally { 7404 Binder.restoreCallingIdentity(origId); 7405 } 7406 } 7407 } 7408 } 7409 7410 /** 7411 * Moves an activity, and all of the other activities within the same task, to the bottom 7412 * of the history stack. The activity's order within the task is unchanged. 7413 * 7414 * @param token A reference to the activity we wish to move 7415 * @param nonRoot If false then this only works if the activity is the root 7416 * of a task; if true it will work for any activity in a task. 7417 * @return Returns true if the move completed, false if not. 7418 */ 7419 @Override 7420 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7421 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7422 synchronized(this) { 7423 final long origId = Binder.clearCallingIdentity(); 7424 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7425 if (taskId >= 0) { 7426 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7427 } 7428 Binder.restoreCallingIdentity(origId); 7429 } 7430 return false; 7431 } 7432 7433 @Override 7434 public void moveTaskBackwards(int task) { 7435 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7436 "moveTaskBackwards()"); 7437 7438 synchronized(this) { 7439 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7440 Binder.getCallingUid(), "Task backwards")) { 7441 return; 7442 } 7443 final long origId = Binder.clearCallingIdentity(); 7444 moveTaskBackwardsLocked(task); 7445 Binder.restoreCallingIdentity(origId); 7446 } 7447 } 7448 7449 private final void moveTaskBackwardsLocked(int task) { 7450 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7451 } 7452 7453 @Override 7454 public IBinder getHomeActivityToken() throws RemoteException { 7455 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7456 "getHomeActivityToken()"); 7457 synchronized (this) { 7458 return mStackSupervisor.getHomeActivityToken(); 7459 } 7460 } 7461 7462 @Override 7463 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7464 IActivityContainerCallback callback) throws RemoteException { 7465 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7466 "createActivityContainer()"); 7467 synchronized (this) { 7468 if (parentActivityToken == null) { 7469 throw new IllegalArgumentException("parent token must not be null"); 7470 } 7471 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7472 if (r == null) { 7473 return null; 7474 } 7475 if (callback == null) { 7476 throw new IllegalArgumentException("callback must not be null"); 7477 } 7478 return mStackSupervisor.createActivityContainer(r, callback); 7479 } 7480 } 7481 7482 @Override 7483 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7484 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7485 "deleteActivityContainer()"); 7486 synchronized (this) { 7487 mStackSupervisor.deleteActivityContainer(container); 7488 } 7489 } 7490 7491 @Override 7492 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7493 throws RemoteException { 7494 synchronized (this) { 7495 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7496 if (stack != null) { 7497 return stack.mActivityContainer; 7498 } 7499 return null; 7500 } 7501 } 7502 7503 @Override 7504 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7505 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7506 "moveTaskToStack()"); 7507 if (stackId == HOME_STACK_ID) { 7508 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7509 new RuntimeException("here").fillInStackTrace()); 7510 } 7511 synchronized (this) { 7512 long ident = Binder.clearCallingIdentity(); 7513 try { 7514 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7515 + stackId + " toTop=" + toTop); 7516 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7517 } finally { 7518 Binder.restoreCallingIdentity(ident); 7519 } 7520 } 7521 } 7522 7523 @Override 7524 public void resizeStack(int stackBoxId, Rect bounds) { 7525 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7526 "resizeStackBox()"); 7527 long ident = Binder.clearCallingIdentity(); 7528 try { 7529 mWindowManager.resizeStack(stackBoxId, bounds); 7530 } finally { 7531 Binder.restoreCallingIdentity(ident); 7532 } 7533 } 7534 7535 @Override 7536 public List<StackInfo> getAllStackInfos() { 7537 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7538 "getAllStackInfos()"); 7539 long ident = Binder.clearCallingIdentity(); 7540 try { 7541 synchronized (this) { 7542 return mStackSupervisor.getAllStackInfosLocked(); 7543 } 7544 } finally { 7545 Binder.restoreCallingIdentity(ident); 7546 } 7547 } 7548 7549 @Override 7550 public StackInfo getStackInfo(int stackId) { 7551 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7552 "getStackInfo()"); 7553 long ident = Binder.clearCallingIdentity(); 7554 try { 7555 synchronized (this) { 7556 return mStackSupervisor.getStackInfoLocked(stackId); 7557 } 7558 } finally { 7559 Binder.restoreCallingIdentity(ident); 7560 } 7561 } 7562 7563 @Override 7564 public boolean isInHomeStack(int taskId) { 7565 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7566 "getStackInfo()"); 7567 long ident = Binder.clearCallingIdentity(); 7568 try { 7569 synchronized (this) { 7570 TaskRecord tr = recentTaskForIdLocked(taskId); 7571 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 7572 } 7573 } finally { 7574 Binder.restoreCallingIdentity(ident); 7575 } 7576 } 7577 7578 @Override 7579 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7580 synchronized(this) { 7581 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7582 } 7583 } 7584 7585 private boolean isLockTaskAuthorized(ComponentName name) { 7586 final DevicePolicyManager dpm = (DevicePolicyManager) 7587 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7588 return dpm != null && dpm.isLockTaskPermitted(name); 7589 } 7590 7591 private void startLockTaskMode(TaskRecord task) { 7592 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7593 return; 7594 } 7595 long ident = Binder.clearCallingIdentity(); 7596 try { 7597 synchronized (this) { 7598 // Since we lost lock on task, make sure it is still there. 7599 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7600 if (task != null) { 7601 mStackSupervisor.setLockTaskModeLocked(task); 7602 } 7603 } 7604 } finally { 7605 Binder.restoreCallingIdentity(ident); 7606 } 7607 } 7608 7609 @Override 7610 public void startLockTaskMode(int taskId) { 7611 long ident = Binder.clearCallingIdentity(); 7612 try { 7613 final TaskRecord task; 7614 synchronized (this) { 7615 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7616 } 7617 if (task != null) { 7618 startLockTaskMode(task); 7619 } 7620 } finally { 7621 Binder.restoreCallingIdentity(ident); 7622 } 7623 } 7624 7625 @Override 7626 public void startLockTaskMode(IBinder token) { 7627 long ident = Binder.clearCallingIdentity(); 7628 try { 7629 final TaskRecord task; 7630 synchronized (this) { 7631 final ActivityRecord r = ActivityRecord.forToken(token); 7632 if (r == null) { 7633 return; 7634 } 7635 task = r.task; 7636 } 7637 if (task != null) { 7638 startLockTaskMode(task); 7639 } 7640 } finally { 7641 Binder.restoreCallingIdentity(ident); 7642 } 7643 } 7644 7645 @Override 7646 public void stopLockTaskMode() { 7647 // Check if the calling task is eligible to use lock task 7648 final int uid = Binder.getCallingUid(); 7649 try { 7650 final String name = AppGlobals.getPackageManager().getNameForUid(uid); 7651 if (!isLockTaskAuthorized(new ComponentName(name, name))) { 7652 return; 7653 } 7654 } catch (RemoteException e) { 7655 Log.d(TAG, "stopLockTaskMode " + e); 7656 return; 7657 } 7658 // Stop lock task 7659 synchronized (this) { 7660 mStackSupervisor.setLockTaskModeLocked(null); 7661 } 7662 } 7663 7664 @Override 7665 public boolean isInLockTaskMode() { 7666 synchronized (this) { 7667 return mStackSupervisor.isInLockTaskMode(); 7668 } 7669 } 7670 7671 // ========================================================= 7672 // CONTENT PROVIDERS 7673 // ========================================================= 7674 7675 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7676 List<ProviderInfo> providers = null; 7677 try { 7678 providers = AppGlobals.getPackageManager(). 7679 queryContentProviders(app.processName, app.uid, 7680 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7681 } catch (RemoteException ex) { 7682 } 7683 if (DEBUG_MU) 7684 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7685 int userId = app.userId; 7686 if (providers != null) { 7687 int N = providers.size(); 7688 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7689 for (int i=0; i<N; i++) { 7690 ProviderInfo cpi = 7691 (ProviderInfo)providers.get(i); 7692 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7693 cpi.name, cpi.flags); 7694 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7695 // This is a singleton provider, but a user besides the 7696 // default user is asking to initialize a process it runs 7697 // in... well, no, it doesn't actually run in this process, 7698 // it runs in the process of the default user. Get rid of it. 7699 providers.remove(i); 7700 N--; 7701 i--; 7702 continue; 7703 } 7704 7705 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7706 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7707 if (cpr == null) { 7708 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7709 mProviderMap.putProviderByClass(comp, cpr); 7710 } 7711 if (DEBUG_MU) 7712 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7713 app.pubProviders.put(cpi.name, cpr); 7714 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7715 // Don't add this if it is a platform component that is marked 7716 // to run in multiple processes, because this is actually 7717 // part of the framework so doesn't make sense to track as a 7718 // separate apk in the process. 7719 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7720 } 7721 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7722 } 7723 } 7724 return providers; 7725 } 7726 7727 /** 7728 * Check if {@link ProcessRecord} has a possible chance at accessing the 7729 * given {@link ProviderInfo}. Final permission checking is always done 7730 * in {@link ContentProvider}. 7731 */ 7732 private final String checkContentProviderPermissionLocked( 7733 ProviderInfo cpi, ProcessRecord r, int userId) { 7734 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7735 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7736 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7737 // Looking for cross-user grants before to enforce the typical cross-users permissions 7738 if (userId != UserHandle.getUserId(callingUid)) { 7739 if (perms != null) { 7740 for (GrantUri grantUri : perms.keySet()) { 7741 if (grantUri.sourceUserId == userId) { 7742 String authority = grantUri.uri.getAuthority(); 7743 if (authority.equals(cpi.authority)) { 7744 return null; 7745 } 7746 } 7747 } 7748 } 7749 } 7750 userId = handleIncomingUser(callingPid, callingUid, userId, 7751 false, true, "checkContentProviderPermissionLocked", null); 7752 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7753 cpi.applicationInfo.uid, cpi.exported) 7754 == PackageManager.PERMISSION_GRANTED) { 7755 return null; 7756 } 7757 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7758 cpi.applicationInfo.uid, cpi.exported) 7759 == PackageManager.PERMISSION_GRANTED) { 7760 return null; 7761 } 7762 7763 PathPermission[] pps = cpi.pathPermissions; 7764 if (pps != null) { 7765 int i = pps.length; 7766 while (i > 0) { 7767 i--; 7768 PathPermission pp = pps[i]; 7769 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7770 cpi.applicationInfo.uid, cpi.exported) 7771 == PackageManager.PERMISSION_GRANTED) { 7772 return null; 7773 } 7774 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7775 cpi.applicationInfo.uid, cpi.exported) 7776 == PackageManager.PERMISSION_GRANTED) { 7777 return null; 7778 } 7779 } 7780 } 7781 7782 if (perms != null) { 7783 for (GrantUri grantUri : perms.keySet()) { 7784 if (grantUri.uri.getAuthority().equals(cpi.authority)) { 7785 return null; 7786 } 7787 } 7788 } 7789 7790 String msg; 7791 if (!cpi.exported) { 7792 msg = "Permission Denial: opening provider " + cpi.name 7793 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7794 + ", uid=" + callingUid + ") that is not exported from uid " 7795 + cpi.applicationInfo.uid; 7796 } else { 7797 msg = "Permission Denial: opening provider " + cpi.name 7798 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7799 + ", uid=" + callingUid + ") requires " 7800 + cpi.readPermission + " or " + cpi.writePermission; 7801 } 7802 Slog.w(TAG, msg); 7803 return msg; 7804 } 7805 7806 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7807 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7808 if (r != null) { 7809 for (int i=0; i<r.conProviders.size(); i++) { 7810 ContentProviderConnection conn = r.conProviders.get(i); 7811 if (conn.provider == cpr) { 7812 if (DEBUG_PROVIDER) Slog.v(TAG, 7813 "Adding provider requested by " 7814 + r.processName + " from process " 7815 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7816 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7817 if (stable) { 7818 conn.stableCount++; 7819 conn.numStableIncs++; 7820 } else { 7821 conn.unstableCount++; 7822 conn.numUnstableIncs++; 7823 } 7824 return conn; 7825 } 7826 } 7827 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7828 if (stable) { 7829 conn.stableCount = 1; 7830 conn.numStableIncs = 1; 7831 } else { 7832 conn.unstableCount = 1; 7833 conn.numUnstableIncs = 1; 7834 } 7835 cpr.connections.add(conn); 7836 r.conProviders.add(conn); 7837 return conn; 7838 } 7839 cpr.addExternalProcessHandleLocked(externalProcessToken); 7840 return null; 7841 } 7842 7843 boolean decProviderCountLocked(ContentProviderConnection conn, 7844 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7845 if (conn != null) { 7846 cpr = conn.provider; 7847 if (DEBUG_PROVIDER) Slog.v(TAG, 7848 "Removing provider requested by " 7849 + conn.client.processName + " from process " 7850 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7851 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7852 if (stable) { 7853 conn.stableCount--; 7854 } else { 7855 conn.unstableCount--; 7856 } 7857 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7858 cpr.connections.remove(conn); 7859 conn.client.conProviders.remove(conn); 7860 return true; 7861 } 7862 return false; 7863 } 7864 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7865 return false; 7866 } 7867 7868 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7869 String name, IBinder token, boolean stable, int userId) { 7870 ContentProviderRecord cpr; 7871 ContentProviderConnection conn = null; 7872 ProviderInfo cpi = null; 7873 7874 synchronized(this) { 7875 ProcessRecord r = null; 7876 if (caller != null) { 7877 r = getRecordForAppLocked(caller); 7878 if (r == null) { 7879 throw new SecurityException( 7880 "Unable to find app for caller " + caller 7881 + " (pid=" + Binder.getCallingPid() 7882 + ") when getting content provider " + name); 7883 } 7884 } 7885 7886 // First check if this content provider has been published... 7887 cpr = mProviderMap.getProviderByName(name, userId); 7888 boolean providerRunning = cpr != null; 7889 if (providerRunning) { 7890 cpi = cpr.info; 7891 String msg; 7892 if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) { 7893 throw new SecurityException(msg); 7894 } 7895 7896 if (r != null && cpr.canRunHere(r)) { 7897 // This provider has been published or is in the process 7898 // of being published... but it is also allowed to run 7899 // in the caller's process, so don't make a connection 7900 // and just let the caller instantiate its own instance. 7901 ContentProviderHolder holder = cpr.newHolder(null); 7902 // don't give caller the provider object, it needs 7903 // to make its own. 7904 holder.provider = null; 7905 return holder; 7906 } 7907 7908 final long origId = Binder.clearCallingIdentity(); 7909 7910 // In this case the provider instance already exists, so we can 7911 // return it right away. 7912 conn = incProviderCountLocked(r, cpr, token, stable); 7913 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7914 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7915 // If this is a perceptible app accessing the provider, 7916 // make sure to count it as being accessed and thus 7917 // back up on the LRU list. This is good because 7918 // content providers are often expensive to start. 7919 updateLruProcessLocked(cpr.proc, false, null); 7920 } 7921 } 7922 7923 if (cpr.proc != null) { 7924 if (false) { 7925 if (cpr.name.flattenToShortString().equals( 7926 "com.android.providers.calendar/.CalendarProvider2")) { 7927 Slog.v(TAG, "****************** KILLING " 7928 + cpr.name.flattenToShortString()); 7929 Process.killProcess(cpr.proc.pid); 7930 } 7931 } 7932 boolean success = updateOomAdjLocked(cpr.proc); 7933 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7934 // NOTE: there is still a race here where a signal could be 7935 // pending on the process even though we managed to update its 7936 // adj level. Not sure what to do about this, but at least 7937 // the race is now smaller. 7938 if (!success) { 7939 // Uh oh... it looks like the provider's process 7940 // has been killed on us. We need to wait for a new 7941 // process to be started, and make sure its death 7942 // doesn't kill our process. 7943 Slog.i(TAG, 7944 "Existing provider " + cpr.name.flattenToShortString() 7945 + " is crashing; detaching " + r); 7946 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7947 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7948 if (!lastRef) { 7949 // This wasn't the last ref our process had on 7950 // the provider... we have now been killed, bail. 7951 return null; 7952 } 7953 providerRunning = false; 7954 conn = null; 7955 } 7956 } 7957 7958 Binder.restoreCallingIdentity(origId); 7959 } 7960 7961 boolean singleton; 7962 if (!providerRunning) { 7963 try { 7964 cpi = AppGlobals.getPackageManager(). 7965 resolveContentProvider(name, 7966 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7967 } catch (RemoteException ex) { 7968 } 7969 if (cpi == null) { 7970 return null; 7971 } 7972 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7973 cpi.name, cpi.flags); 7974 if (singleton) { 7975 userId = 0; 7976 } 7977 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7978 7979 String msg; 7980 if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) { 7981 throw new SecurityException(msg); 7982 } 7983 7984 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7985 && !cpi.processName.equals("system")) { 7986 // If this content provider does not run in the system 7987 // process, and the system is not yet ready to run other 7988 // processes, then fail fast instead of hanging. 7989 throw new IllegalArgumentException( 7990 "Attempt to launch content provider before system ready"); 7991 } 7992 7993 // Make sure that the user who owns this provider is started. If not, 7994 // we don't want to allow it to run. 7995 if (mStartedUsers.get(userId) == null) { 7996 Slog.w(TAG, "Unable to launch app " 7997 + cpi.applicationInfo.packageName + "/" 7998 + cpi.applicationInfo.uid + " for provider " 7999 + name + ": user " + userId + " is stopped"); 8000 return null; 8001 } 8002 8003 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8004 cpr = mProviderMap.getProviderByClass(comp, userId); 8005 final boolean firstClass = cpr == null; 8006 if (firstClass) { 8007 try { 8008 ApplicationInfo ai = 8009 AppGlobals.getPackageManager(). 8010 getApplicationInfo( 8011 cpi.applicationInfo.packageName, 8012 STOCK_PM_FLAGS, userId); 8013 if (ai == null) { 8014 Slog.w(TAG, "No package info for content provider " 8015 + cpi.name); 8016 return null; 8017 } 8018 ai = getAppInfoForUser(ai, userId); 8019 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8020 } catch (RemoteException ex) { 8021 // pm is in same process, this will never happen. 8022 } 8023 } 8024 8025 if (r != null && cpr.canRunHere(r)) { 8026 // If this is a multiprocess provider, then just return its 8027 // info and allow the caller to instantiate it. Only do 8028 // this if the provider is the same user as the caller's 8029 // process, or can run as root (so can be in any process). 8030 return cpr.newHolder(null); 8031 } 8032 8033 if (DEBUG_PROVIDER) { 8034 RuntimeException e = new RuntimeException("here"); 8035 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8036 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8037 } 8038 8039 // This is single process, and our app is now connecting to it. 8040 // See if we are already in the process of launching this 8041 // provider. 8042 final int N = mLaunchingProviders.size(); 8043 int i; 8044 for (i=0; i<N; i++) { 8045 if (mLaunchingProviders.get(i) == cpr) { 8046 break; 8047 } 8048 } 8049 8050 // If the provider is not already being launched, then get it 8051 // started. 8052 if (i >= N) { 8053 final long origId = Binder.clearCallingIdentity(); 8054 8055 try { 8056 // Content provider is now in use, its package can't be stopped. 8057 try { 8058 AppGlobals.getPackageManager().setPackageStoppedState( 8059 cpr.appInfo.packageName, false, userId); 8060 } catch (RemoteException e) { 8061 } catch (IllegalArgumentException e) { 8062 Slog.w(TAG, "Failed trying to unstop package " 8063 + cpr.appInfo.packageName + ": " + e); 8064 } 8065 8066 // Use existing process if already started 8067 ProcessRecord proc = getProcessRecordLocked( 8068 cpi.processName, cpr.appInfo.uid, false); 8069 if (proc != null && proc.thread != null) { 8070 if (DEBUG_PROVIDER) { 8071 Slog.d(TAG, "Installing in existing process " + proc); 8072 } 8073 proc.pubProviders.put(cpi.name, cpr); 8074 try { 8075 proc.thread.scheduleInstallProvider(cpi); 8076 } catch (RemoteException e) { 8077 } 8078 } else { 8079 proc = startProcessLocked(cpi.processName, 8080 cpr.appInfo, false, 0, "content provider", 8081 new ComponentName(cpi.applicationInfo.packageName, 8082 cpi.name), false, false, false); 8083 if (proc == null) { 8084 Slog.w(TAG, "Unable to launch app " 8085 + cpi.applicationInfo.packageName + "/" 8086 + cpi.applicationInfo.uid + " for provider " 8087 + name + ": process is bad"); 8088 return null; 8089 } 8090 } 8091 cpr.launchingApp = proc; 8092 mLaunchingProviders.add(cpr); 8093 } finally { 8094 Binder.restoreCallingIdentity(origId); 8095 } 8096 } 8097 8098 // Make sure the provider is published (the same provider class 8099 // may be published under multiple names). 8100 if (firstClass) { 8101 mProviderMap.putProviderByClass(comp, cpr); 8102 } 8103 8104 mProviderMap.putProviderByName(name, cpr); 8105 conn = incProviderCountLocked(r, cpr, token, stable); 8106 if (conn != null) { 8107 conn.waiting = true; 8108 } 8109 } 8110 } 8111 8112 // Wait for the provider to be published... 8113 synchronized (cpr) { 8114 while (cpr.provider == null) { 8115 if (cpr.launchingApp == null) { 8116 Slog.w(TAG, "Unable to launch app " 8117 + cpi.applicationInfo.packageName + "/" 8118 + cpi.applicationInfo.uid + " for provider " 8119 + name + ": launching app became null"); 8120 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8121 UserHandle.getUserId(cpi.applicationInfo.uid), 8122 cpi.applicationInfo.packageName, 8123 cpi.applicationInfo.uid, name); 8124 return null; 8125 } 8126 try { 8127 if (DEBUG_MU) { 8128 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8129 + cpr.launchingApp); 8130 } 8131 if (conn != null) { 8132 conn.waiting = true; 8133 } 8134 cpr.wait(); 8135 } catch (InterruptedException ex) { 8136 } finally { 8137 if (conn != null) { 8138 conn.waiting = false; 8139 } 8140 } 8141 } 8142 } 8143 return cpr != null ? cpr.newHolder(conn) : null; 8144 } 8145 8146 @Override 8147 public final ContentProviderHolder getContentProvider( 8148 IApplicationThread caller, String name, int userId, boolean stable) { 8149 enforceNotIsolatedCaller("getContentProvider"); 8150 if (caller == null) { 8151 String msg = "null IApplicationThread when getting content provider " 8152 + name; 8153 Slog.w(TAG, msg); 8154 throw new SecurityException(msg); 8155 } 8156 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8157 // with cross-user grant. 8158 return getContentProviderImpl(caller, name, null, stable, userId); 8159 } 8160 8161 public ContentProviderHolder getContentProviderExternal( 8162 String name, int userId, IBinder token) { 8163 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8164 "Do not have permission in call getContentProviderExternal()"); 8165 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8166 false, true, "getContentProvider", null); 8167 return getContentProviderExternalUnchecked(name, token, userId); 8168 } 8169 8170 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8171 IBinder token, int userId) { 8172 return getContentProviderImpl(null, name, token, true, userId); 8173 } 8174 8175 /** 8176 * Drop a content provider from a ProcessRecord's bookkeeping 8177 */ 8178 public void removeContentProvider(IBinder connection, boolean stable) { 8179 enforceNotIsolatedCaller("removeContentProvider"); 8180 long ident = Binder.clearCallingIdentity(); 8181 try { 8182 synchronized (this) { 8183 ContentProviderConnection conn; 8184 try { 8185 conn = (ContentProviderConnection)connection; 8186 } catch (ClassCastException e) { 8187 String msg ="removeContentProvider: " + connection 8188 + " not a ContentProviderConnection"; 8189 Slog.w(TAG, msg); 8190 throw new IllegalArgumentException(msg); 8191 } 8192 if (conn == null) { 8193 throw new NullPointerException("connection is null"); 8194 } 8195 if (decProviderCountLocked(conn, null, null, stable)) { 8196 updateOomAdjLocked(); 8197 } 8198 } 8199 } finally { 8200 Binder.restoreCallingIdentity(ident); 8201 } 8202 } 8203 8204 public void removeContentProviderExternal(String name, IBinder token) { 8205 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8206 "Do not have permission in call removeContentProviderExternal()"); 8207 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8208 } 8209 8210 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8211 synchronized (this) { 8212 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8213 if(cpr == null) { 8214 //remove from mProvidersByClass 8215 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8216 return; 8217 } 8218 8219 //update content provider record entry info 8220 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8221 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8222 if (localCpr.hasExternalProcessHandles()) { 8223 if (localCpr.removeExternalProcessHandleLocked(token)) { 8224 updateOomAdjLocked(); 8225 } else { 8226 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8227 + " with no external reference for token: " 8228 + token + "."); 8229 } 8230 } else { 8231 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8232 + " with no external references."); 8233 } 8234 } 8235 } 8236 8237 public final void publishContentProviders(IApplicationThread caller, 8238 List<ContentProviderHolder> providers) { 8239 if (providers == null) { 8240 return; 8241 } 8242 8243 enforceNotIsolatedCaller("publishContentProviders"); 8244 synchronized (this) { 8245 final ProcessRecord r = getRecordForAppLocked(caller); 8246 if (DEBUG_MU) 8247 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8248 if (r == null) { 8249 throw new SecurityException( 8250 "Unable to find app for caller " + caller 8251 + " (pid=" + Binder.getCallingPid() 8252 + ") when publishing content providers"); 8253 } 8254 8255 final long origId = Binder.clearCallingIdentity(); 8256 8257 final int N = providers.size(); 8258 for (int i=0; i<N; i++) { 8259 ContentProviderHolder src = providers.get(i); 8260 if (src == null || src.info == null || src.provider == null) { 8261 continue; 8262 } 8263 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8264 if (DEBUG_MU) 8265 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8266 if (dst != null) { 8267 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8268 mProviderMap.putProviderByClass(comp, dst); 8269 String names[] = dst.info.authority.split(";"); 8270 for (int j = 0; j < names.length; j++) { 8271 mProviderMap.putProviderByName(names[j], dst); 8272 } 8273 8274 int NL = mLaunchingProviders.size(); 8275 int j; 8276 for (j=0; j<NL; j++) { 8277 if (mLaunchingProviders.get(j) == dst) { 8278 mLaunchingProviders.remove(j); 8279 j--; 8280 NL--; 8281 } 8282 } 8283 synchronized (dst) { 8284 dst.provider = src.provider; 8285 dst.proc = r; 8286 dst.notifyAll(); 8287 } 8288 updateOomAdjLocked(r); 8289 } 8290 } 8291 8292 Binder.restoreCallingIdentity(origId); 8293 } 8294 } 8295 8296 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8297 ContentProviderConnection conn; 8298 try { 8299 conn = (ContentProviderConnection)connection; 8300 } catch (ClassCastException e) { 8301 String msg ="refContentProvider: " + connection 8302 + " not a ContentProviderConnection"; 8303 Slog.w(TAG, msg); 8304 throw new IllegalArgumentException(msg); 8305 } 8306 if (conn == null) { 8307 throw new NullPointerException("connection is null"); 8308 } 8309 8310 synchronized (this) { 8311 if (stable > 0) { 8312 conn.numStableIncs += stable; 8313 } 8314 stable = conn.stableCount + stable; 8315 if (stable < 0) { 8316 throw new IllegalStateException("stableCount < 0: " + stable); 8317 } 8318 8319 if (unstable > 0) { 8320 conn.numUnstableIncs += unstable; 8321 } 8322 unstable = conn.unstableCount + unstable; 8323 if (unstable < 0) { 8324 throw new IllegalStateException("unstableCount < 0: " + unstable); 8325 } 8326 8327 if ((stable+unstable) <= 0) { 8328 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8329 + stable + " unstable=" + unstable); 8330 } 8331 conn.stableCount = stable; 8332 conn.unstableCount = unstable; 8333 return !conn.dead; 8334 } 8335 } 8336 8337 public void unstableProviderDied(IBinder connection) { 8338 ContentProviderConnection conn; 8339 try { 8340 conn = (ContentProviderConnection)connection; 8341 } catch (ClassCastException e) { 8342 String msg ="refContentProvider: " + connection 8343 + " not a ContentProviderConnection"; 8344 Slog.w(TAG, msg); 8345 throw new IllegalArgumentException(msg); 8346 } 8347 if (conn == null) { 8348 throw new NullPointerException("connection is null"); 8349 } 8350 8351 // Safely retrieve the content provider associated with the connection. 8352 IContentProvider provider; 8353 synchronized (this) { 8354 provider = conn.provider.provider; 8355 } 8356 8357 if (provider == null) { 8358 // Um, yeah, we're way ahead of you. 8359 return; 8360 } 8361 8362 // Make sure the caller is being honest with us. 8363 if (provider.asBinder().pingBinder()) { 8364 // Er, no, still looks good to us. 8365 synchronized (this) { 8366 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8367 + " says " + conn + " died, but we don't agree"); 8368 return; 8369 } 8370 } 8371 8372 // Well look at that! It's dead! 8373 synchronized (this) { 8374 if (conn.provider.provider != provider) { 8375 // But something changed... good enough. 8376 return; 8377 } 8378 8379 ProcessRecord proc = conn.provider.proc; 8380 if (proc == null || proc.thread == null) { 8381 // Seems like the process is already cleaned up. 8382 return; 8383 } 8384 8385 // As far as we're concerned, this is just like receiving a 8386 // death notification... just a bit prematurely. 8387 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8388 + ") early provider death"); 8389 final long ident = Binder.clearCallingIdentity(); 8390 try { 8391 appDiedLocked(proc, proc.pid, proc.thread); 8392 } finally { 8393 Binder.restoreCallingIdentity(ident); 8394 } 8395 } 8396 } 8397 8398 @Override 8399 public void appNotRespondingViaProvider(IBinder connection) { 8400 enforceCallingPermission( 8401 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8402 8403 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8404 if (conn == null) { 8405 Slog.w(TAG, "ContentProviderConnection is null"); 8406 return; 8407 } 8408 8409 final ProcessRecord host = conn.provider.proc; 8410 if (host == null) { 8411 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8412 return; 8413 } 8414 8415 final long token = Binder.clearCallingIdentity(); 8416 try { 8417 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8418 } finally { 8419 Binder.restoreCallingIdentity(token); 8420 } 8421 } 8422 8423 public final void installSystemProviders() { 8424 List<ProviderInfo> providers; 8425 synchronized (this) { 8426 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8427 providers = generateApplicationProvidersLocked(app); 8428 if (providers != null) { 8429 for (int i=providers.size()-1; i>=0; i--) { 8430 ProviderInfo pi = (ProviderInfo)providers.get(i); 8431 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8432 Slog.w(TAG, "Not installing system proc provider " + pi.name 8433 + ": not system .apk"); 8434 providers.remove(i); 8435 } 8436 } 8437 } 8438 } 8439 if (providers != null) { 8440 mSystemThread.installSystemProviders(providers); 8441 } 8442 8443 mCoreSettingsObserver = new CoreSettingsObserver(this); 8444 8445 mUsageStatsService.monitorPackages(); 8446 } 8447 8448 /** 8449 * Allows app to retrieve the MIME type of a URI without having permission 8450 * to access its content provider. 8451 * 8452 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8453 * 8454 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8455 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8456 */ 8457 public String getProviderMimeType(Uri uri, int userId) { 8458 enforceNotIsolatedCaller("getProviderMimeType"); 8459 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8460 userId, false, true, "getProviderMimeType", null); 8461 final String name = uri.getAuthority(); 8462 final long ident = Binder.clearCallingIdentity(); 8463 ContentProviderHolder holder = null; 8464 8465 try { 8466 holder = getContentProviderExternalUnchecked(name, null, userId); 8467 if (holder != null) { 8468 return holder.provider.getType(uri); 8469 } 8470 } catch (RemoteException e) { 8471 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8472 return null; 8473 } finally { 8474 if (holder != null) { 8475 removeContentProviderExternalUnchecked(name, null, userId); 8476 } 8477 Binder.restoreCallingIdentity(ident); 8478 } 8479 8480 return null; 8481 } 8482 8483 // ========================================================= 8484 // GLOBAL MANAGEMENT 8485 // ========================================================= 8486 8487 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8488 boolean isolated) { 8489 String proc = customProcess != null ? customProcess : info.processName; 8490 BatteryStatsImpl.Uid.Proc ps = null; 8491 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8492 int uid = info.uid; 8493 if (isolated) { 8494 int userId = UserHandle.getUserId(uid); 8495 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8496 while (true) { 8497 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8498 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8499 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8500 } 8501 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8502 mNextIsolatedProcessUid++; 8503 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8504 // No process for this uid, use it. 8505 break; 8506 } 8507 stepsLeft--; 8508 if (stepsLeft <= 0) { 8509 return null; 8510 } 8511 } 8512 } 8513 return new ProcessRecord(stats, info, proc, uid); 8514 } 8515 8516 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8517 ProcessRecord app; 8518 if (!isolated) { 8519 app = getProcessRecordLocked(info.processName, info.uid, true); 8520 } else { 8521 app = null; 8522 } 8523 8524 if (app == null) { 8525 app = newProcessRecordLocked(info, null, isolated); 8526 mProcessNames.put(info.processName, app.uid, app); 8527 if (isolated) { 8528 mIsolatedProcesses.put(app.uid, app); 8529 } 8530 updateLruProcessLocked(app, false, null); 8531 updateOomAdjLocked(); 8532 } 8533 8534 // This package really, really can not be stopped. 8535 try { 8536 AppGlobals.getPackageManager().setPackageStoppedState( 8537 info.packageName, false, UserHandle.getUserId(app.uid)); 8538 } catch (RemoteException e) { 8539 } catch (IllegalArgumentException e) { 8540 Slog.w(TAG, "Failed trying to unstop package " 8541 + info.packageName + ": " + e); 8542 } 8543 8544 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8545 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8546 app.persistent = true; 8547 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8548 } 8549 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8550 mPersistentStartingProcesses.add(app); 8551 startProcessLocked(app, "added application", app.processName); 8552 } 8553 8554 return app; 8555 } 8556 8557 public void unhandledBack() { 8558 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8559 "unhandledBack()"); 8560 8561 synchronized(this) { 8562 final long origId = Binder.clearCallingIdentity(); 8563 try { 8564 getFocusedStack().unhandledBackLocked(); 8565 } finally { 8566 Binder.restoreCallingIdentity(origId); 8567 } 8568 } 8569 } 8570 8571 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8572 enforceNotIsolatedCaller("openContentUri"); 8573 final int userId = UserHandle.getCallingUserId(); 8574 String name = uri.getAuthority(); 8575 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8576 ParcelFileDescriptor pfd = null; 8577 if (cph != null) { 8578 // We record the binder invoker's uid in thread-local storage before 8579 // going to the content provider to open the file. Later, in the code 8580 // that handles all permissions checks, we look for this uid and use 8581 // that rather than the Activity Manager's own uid. The effect is that 8582 // we do the check against the caller's permissions even though it looks 8583 // to the content provider like the Activity Manager itself is making 8584 // the request. 8585 sCallerIdentity.set(new Identity( 8586 Binder.getCallingPid(), Binder.getCallingUid())); 8587 try { 8588 pfd = cph.provider.openFile(null, uri, "r", null); 8589 } catch (FileNotFoundException e) { 8590 // do nothing; pfd will be returned null 8591 } finally { 8592 // Ensure that whatever happens, we clean up the identity state 8593 sCallerIdentity.remove(); 8594 } 8595 8596 // We've got the fd now, so we're done with the provider. 8597 removeContentProviderExternalUnchecked(name, null, userId); 8598 } else { 8599 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8600 } 8601 return pfd; 8602 } 8603 8604 // Actually is sleeping or shutting down or whatever else in the future 8605 // is an inactive state. 8606 public boolean isSleepingOrShuttingDown() { 8607 return mSleeping || mShuttingDown; 8608 } 8609 8610 public boolean isSleeping() { 8611 return mSleeping; 8612 } 8613 8614 void goingToSleep() { 8615 synchronized(this) { 8616 mWentToSleep = true; 8617 updateEventDispatchingLocked(); 8618 goToSleepIfNeededLocked(); 8619 } 8620 } 8621 8622 void finishRunningVoiceLocked() { 8623 if (mRunningVoice) { 8624 mRunningVoice = false; 8625 goToSleepIfNeededLocked(); 8626 } 8627 } 8628 8629 void goToSleepIfNeededLocked() { 8630 if (mWentToSleep && !mRunningVoice) { 8631 if (!mSleeping) { 8632 mSleeping = true; 8633 mStackSupervisor.goingToSleepLocked(); 8634 8635 // Initialize the wake times of all processes. 8636 checkExcessivePowerUsageLocked(false); 8637 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8638 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8639 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8640 } 8641 } 8642 } 8643 8644 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 8645 mTaskPersister.notify(task, flush); 8646 } 8647 8648 @Override 8649 public boolean shutdown(int timeout) { 8650 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8651 != PackageManager.PERMISSION_GRANTED) { 8652 throw new SecurityException("Requires permission " 8653 + android.Manifest.permission.SHUTDOWN); 8654 } 8655 8656 boolean timedout = false; 8657 8658 synchronized(this) { 8659 mShuttingDown = true; 8660 updateEventDispatchingLocked(); 8661 timedout = mStackSupervisor.shutdownLocked(timeout); 8662 } 8663 8664 mAppOpsService.shutdown(); 8665 mUsageStatsService.shutdown(); 8666 mBatteryStatsService.shutdown(); 8667 synchronized (this) { 8668 mProcessStats.shutdownLocked(); 8669 } 8670 notifyTaskPersisterLocked(null, true); 8671 8672 return timedout; 8673 } 8674 8675 public final void activitySlept(IBinder token) { 8676 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8677 8678 final long origId = Binder.clearCallingIdentity(); 8679 8680 synchronized (this) { 8681 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8682 if (r != null) { 8683 mStackSupervisor.activitySleptLocked(r); 8684 } 8685 } 8686 8687 Binder.restoreCallingIdentity(origId); 8688 } 8689 8690 void logLockScreen(String msg) { 8691 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8692 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8693 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8694 mStackSupervisor.mDismissKeyguardOnNextActivity); 8695 } 8696 8697 private void comeOutOfSleepIfNeededLocked() { 8698 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8699 if (mSleeping) { 8700 mSleeping = false; 8701 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8702 } 8703 } 8704 } 8705 8706 void wakingUp() { 8707 synchronized(this) { 8708 mWentToSleep = false; 8709 updateEventDispatchingLocked(); 8710 comeOutOfSleepIfNeededLocked(); 8711 } 8712 } 8713 8714 void startRunningVoiceLocked() { 8715 if (!mRunningVoice) { 8716 mRunningVoice = true; 8717 comeOutOfSleepIfNeededLocked(); 8718 } 8719 } 8720 8721 private void updateEventDispatchingLocked() { 8722 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8723 } 8724 8725 public void setLockScreenShown(boolean shown) { 8726 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8727 != PackageManager.PERMISSION_GRANTED) { 8728 throw new SecurityException("Requires permission " 8729 + android.Manifest.permission.DEVICE_POWER); 8730 } 8731 8732 synchronized(this) { 8733 long ident = Binder.clearCallingIdentity(); 8734 try { 8735 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8736 mLockScreenShown = shown; 8737 comeOutOfSleepIfNeededLocked(); 8738 } finally { 8739 Binder.restoreCallingIdentity(ident); 8740 } 8741 } 8742 } 8743 8744 public void stopAppSwitches() { 8745 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8746 != PackageManager.PERMISSION_GRANTED) { 8747 throw new SecurityException("Requires permission " 8748 + android.Manifest.permission.STOP_APP_SWITCHES); 8749 } 8750 8751 synchronized(this) { 8752 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8753 + APP_SWITCH_DELAY_TIME; 8754 mDidAppSwitch = false; 8755 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8756 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8757 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8758 } 8759 } 8760 8761 public void resumeAppSwitches() { 8762 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8763 != PackageManager.PERMISSION_GRANTED) { 8764 throw new SecurityException("Requires permission " 8765 + android.Manifest.permission.STOP_APP_SWITCHES); 8766 } 8767 8768 synchronized(this) { 8769 // Note that we don't execute any pending app switches... we will 8770 // let those wait until either the timeout, or the next start 8771 // activity request. 8772 mAppSwitchesAllowedTime = 0; 8773 } 8774 } 8775 8776 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8777 String name) { 8778 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8779 return true; 8780 } 8781 8782 final int perm = checkComponentPermission( 8783 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8784 callingUid, -1, true); 8785 if (perm == PackageManager.PERMISSION_GRANTED) { 8786 return true; 8787 } 8788 8789 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8790 return false; 8791 } 8792 8793 public void setDebugApp(String packageName, boolean waitForDebugger, 8794 boolean persistent) { 8795 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8796 "setDebugApp()"); 8797 8798 long ident = Binder.clearCallingIdentity(); 8799 try { 8800 // Note that this is not really thread safe if there are multiple 8801 // callers into it at the same time, but that's not a situation we 8802 // care about. 8803 if (persistent) { 8804 final ContentResolver resolver = mContext.getContentResolver(); 8805 Settings.Global.putString( 8806 resolver, Settings.Global.DEBUG_APP, 8807 packageName); 8808 Settings.Global.putInt( 8809 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8810 waitForDebugger ? 1 : 0); 8811 } 8812 8813 synchronized (this) { 8814 if (!persistent) { 8815 mOrigDebugApp = mDebugApp; 8816 mOrigWaitForDebugger = mWaitForDebugger; 8817 } 8818 mDebugApp = packageName; 8819 mWaitForDebugger = waitForDebugger; 8820 mDebugTransient = !persistent; 8821 if (packageName != null) { 8822 forceStopPackageLocked(packageName, -1, false, false, true, true, 8823 false, UserHandle.USER_ALL, "set debug app"); 8824 } 8825 } 8826 } finally { 8827 Binder.restoreCallingIdentity(ident); 8828 } 8829 } 8830 8831 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8832 synchronized (this) { 8833 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8834 if (!isDebuggable) { 8835 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8836 throw new SecurityException("Process not debuggable: " + app.packageName); 8837 } 8838 } 8839 8840 mOpenGlTraceApp = processName; 8841 } 8842 } 8843 8844 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8845 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8846 synchronized (this) { 8847 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8848 if (!isDebuggable) { 8849 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8850 throw new SecurityException("Process not debuggable: " + app.packageName); 8851 } 8852 } 8853 mProfileApp = processName; 8854 mProfileFile = profileFile; 8855 if (mProfileFd != null) { 8856 try { 8857 mProfileFd.close(); 8858 } catch (IOException e) { 8859 } 8860 mProfileFd = null; 8861 } 8862 mProfileFd = profileFd; 8863 mProfileType = 0; 8864 mAutoStopProfiler = autoStopProfiler; 8865 } 8866 } 8867 8868 @Override 8869 public void setAlwaysFinish(boolean enabled) { 8870 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8871 "setAlwaysFinish()"); 8872 8873 Settings.Global.putInt( 8874 mContext.getContentResolver(), 8875 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8876 8877 synchronized (this) { 8878 mAlwaysFinishActivities = enabled; 8879 } 8880 } 8881 8882 @Override 8883 public void setActivityController(IActivityController controller) { 8884 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8885 "setActivityController()"); 8886 synchronized (this) { 8887 mController = controller; 8888 Watchdog.getInstance().setActivityController(controller); 8889 } 8890 } 8891 8892 @Override 8893 public void setUserIsMonkey(boolean userIsMonkey) { 8894 synchronized (this) { 8895 synchronized (mPidsSelfLocked) { 8896 final int callingPid = Binder.getCallingPid(); 8897 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8898 if (precessRecord == null) { 8899 throw new SecurityException("Unknown process: " + callingPid); 8900 } 8901 if (precessRecord.instrumentationUiAutomationConnection == null) { 8902 throw new SecurityException("Only an instrumentation process " 8903 + "with a UiAutomation can call setUserIsMonkey"); 8904 } 8905 } 8906 mUserIsMonkey = userIsMonkey; 8907 } 8908 } 8909 8910 @Override 8911 public boolean isUserAMonkey() { 8912 synchronized (this) { 8913 // If there is a controller also implies the user is a monkey. 8914 return (mUserIsMonkey || mController != null); 8915 } 8916 } 8917 8918 public void requestBugReport() { 8919 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8920 SystemProperties.set("ctl.start", "bugreport"); 8921 } 8922 8923 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8924 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8925 } 8926 8927 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8928 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8929 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8930 } 8931 return KEY_DISPATCHING_TIMEOUT; 8932 } 8933 8934 @Override 8935 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8936 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8937 != PackageManager.PERMISSION_GRANTED) { 8938 throw new SecurityException("Requires permission " 8939 + android.Manifest.permission.FILTER_EVENTS); 8940 } 8941 ProcessRecord proc; 8942 long timeout; 8943 synchronized (this) { 8944 synchronized (mPidsSelfLocked) { 8945 proc = mPidsSelfLocked.get(pid); 8946 } 8947 timeout = getInputDispatchingTimeoutLocked(proc); 8948 } 8949 8950 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8951 return -1; 8952 } 8953 8954 return timeout; 8955 } 8956 8957 /** 8958 * Handle input dispatching timeouts. 8959 * Returns whether input dispatching should be aborted or not. 8960 */ 8961 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8962 final ActivityRecord activity, final ActivityRecord parent, 8963 final boolean aboveSystem, String reason) { 8964 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8965 != PackageManager.PERMISSION_GRANTED) { 8966 throw new SecurityException("Requires permission " 8967 + android.Manifest.permission.FILTER_EVENTS); 8968 } 8969 8970 final String annotation; 8971 if (reason == null) { 8972 annotation = "Input dispatching timed out"; 8973 } else { 8974 annotation = "Input dispatching timed out (" + reason + ")"; 8975 } 8976 8977 if (proc != null) { 8978 synchronized (this) { 8979 if (proc.debugging) { 8980 return false; 8981 } 8982 8983 if (mDidDexOpt) { 8984 // Give more time since we were dexopting. 8985 mDidDexOpt = false; 8986 return false; 8987 } 8988 8989 if (proc.instrumentationClass != null) { 8990 Bundle info = new Bundle(); 8991 info.putString("shortMsg", "keyDispatchingTimedOut"); 8992 info.putString("longMsg", annotation); 8993 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8994 return true; 8995 } 8996 } 8997 mHandler.post(new Runnable() { 8998 @Override 8999 public void run() { 9000 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9001 } 9002 }); 9003 } 9004 9005 return true; 9006 } 9007 9008 public Bundle getAssistContextExtras(int requestType) { 9009 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9010 "getAssistContextExtras()"); 9011 PendingAssistExtras pae; 9012 Bundle extras = new Bundle(); 9013 synchronized (this) { 9014 ActivityRecord activity = getFocusedStack().mResumedActivity; 9015 if (activity == null) { 9016 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9017 return null; 9018 } 9019 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9020 if (activity.app == null || activity.app.thread == null) { 9021 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9022 return extras; 9023 } 9024 if (activity.app.pid == Binder.getCallingPid()) { 9025 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9026 return extras; 9027 } 9028 pae = new PendingAssistExtras(activity); 9029 try { 9030 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9031 requestType); 9032 mPendingAssistExtras.add(pae); 9033 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9034 } catch (RemoteException e) { 9035 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9036 return extras; 9037 } 9038 } 9039 synchronized (pae) { 9040 while (!pae.haveResult) { 9041 try { 9042 pae.wait(); 9043 } catch (InterruptedException e) { 9044 } 9045 } 9046 if (pae.result != null) { 9047 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9048 } 9049 } 9050 synchronized (this) { 9051 mPendingAssistExtras.remove(pae); 9052 mHandler.removeCallbacks(pae); 9053 } 9054 return extras; 9055 } 9056 9057 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9058 PendingAssistExtras pae = (PendingAssistExtras)token; 9059 synchronized (pae) { 9060 pae.result = extras; 9061 pae.haveResult = true; 9062 pae.notifyAll(); 9063 } 9064 } 9065 9066 public void registerProcessObserver(IProcessObserver observer) { 9067 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9068 "registerProcessObserver()"); 9069 synchronized (this) { 9070 mProcessObservers.register(observer); 9071 } 9072 } 9073 9074 @Override 9075 public void unregisterProcessObserver(IProcessObserver observer) { 9076 synchronized (this) { 9077 mProcessObservers.unregister(observer); 9078 } 9079 } 9080 9081 @Override 9082 public boolean convertFromTranslucent(IBinder token) { 9083 final long origId = Binder.clearCallingIdentity(); 9084 try { 9085 synchronized (this) { 9086 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9087 if (r == null) { 9088 return false; 9089 } 9090 if (r.changeWindowTranslucency(true)) { 9091 mWindowManager.setAppFullscreen(token, true); 9092 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9093 return true; 9094 } 9095 return false; 9096 } 9097 } finally { 9098 Binder.restoreCallingIdentity(origId); 9099 } 9100 } 9101 9102 @Override 9103 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9104 final long origId = Binder.clearCallingIdentity(); 9105 try { 9106 synchronized (this) { 9107 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9108 if (r == null) { 9109 return false; 9110 } 9111 if (r.changeWindowTranslucency(false)) { 9112 r.task.stack.convertToTranslucent(r, options); 9113 mWindowManager.setAppFullscreen(token, false); 9114 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9115 return true; 9116 } 9117 return false; 9118 } 9119 } finally { 9120 Binder.restoreCallingIdentity(origId); 9121 } 9122 } 9123 9124 @Override 9125 public ActivityOptions getActivityOptions(IBinder token) { 9126 final long origId = Binder.clearCallingIdentity(); 9127 try { 9128 synchronized (this) { 9129 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9130 if (r != null) { 9131 final ActivityOptions activityOptions = r.pendingOptions; 9132 r.pendingOptions = null; 9133 return activityOptions; 9134 } 9135 return null; 9136 } 9137 } finally { 9138 Binder.restoreCallingIdentity(origId); 9139 } 9140 } 9141 9142 @Override 9143 public void setImmersive(IBinder token, boolean immersive) { 9144 synchronized(this) { 9145 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9146 if (r == null) { 9147 throw new IllegalArgumentException(); 9148 } 9149 r.immersive = immersive; 9150 9151 // update associated state if we're frontmost 9152 if (r == mFocusedActivity) { 9153 if (DEBUG_IMMERSIVE) { 9154 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9155 } 9156 applyUpdateLockStateLocked(r); 9157 } 9158 } 9159 } 9160 9161 @Override 9162 public boolean isImmersive(IBinder token) { 9163 synchronized (this) { 9164 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9165 if (r == null) { 9166 throw new IllegalArgumentException(); 9167 } 9168 return r.immersive; 9169 } 9170 } 9171 9172 public boolean isTopActivityImmersive() { 9173 enforceNotIsolatedCaller("startActivity"); 9174 synchronized (this) { 9175 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9176 return (r != null) ? r.immersive : false; 9177 } 9178 } 9179 9180 public final void enterSafeMode() { 9181 synchronized(this) { 9182 // It only makes sense to do this before the system is ready 9183 // and started launching other packages. 9184 if (!mSystemReady) { 9185 try { 9186 AppGlobals.getPackageManager().enterSafeMode(); 9187 } catch (RemoteException e) { 9188 } 9189 } 9190 9191 mSafeMode = true; 9192 } 9193 } 9194 9195 public final void showSafeModeOverlay() { 9196 View v = LayoutInflater.from(mContext).inflate( 9197 com.android.internal.R.layout.safe_mode, null); 9198 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9199 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9200 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9201 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9202 lp.gravity = Gravity.BOTTOM | Gravity.START; 9203 lp.format = v.getBackground().getOpacity(); 9204 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9205 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9206 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9207 ((WindowManager)mContext.getSystemService( 9208 Context.WINDOW_SERVICE)).addView(v, lp); 9209 } 9210 9211 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9212 if (!(sender instanceof PendingIntentRecord)) { 9213 return; 9214 } 9215 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9216 synchronized (stats) { 9217 if (mBatteryStatsService.isOnBattery()) { 9218 mBatteryStatsService.enforceCallingPermission(); 9219 PendingIntentRecord rec = (PendingIntentRecord)sender; 9220 int MY_UID = Binder.getCallingUid(); 9221 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9222 BatteryStatsImpl.Uid.Pkg pkg = 9223 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9224 sourcePkg != null ? sourcePkg : rec.key.packageName); 9225 pkg.incWakeupsLocked(); 9226 } 9227 } 9228 } 9229 9230 public boolean killPids(int[] pids, String pReason, boolean secure) { 9231 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9232 throw new SecurityException("killPids only available to the system"); 9233 } 9234 String reason = (pReason == null) ? "Unknown" : pReason; 9235 // XXX Note: don't acquire main activity lock here, because the window 9236 // manager calls in with its locks held. 9237 9238 boolean killed = false; 9239 synchronized (mPidsSelfLocked) { 9240 int[] types = new int[pids.length]; 9241 int worstType = 0; 9242 for (int i=0; i<pids.length; i++) { 9243 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9244 if (proc != null) { 9245 int type = proc.setAdj; 9246 types[i] = type; 9247 if (type > worstType) { 9248 worstType = type; 9249 } 9250 } 9251 } 9252 9253 // If the worst oom_adj is somewhere in the cached proc LRU range, 9254 // then constrain it so we will kill all cached procs. 9255 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9256 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9257 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9258 } 9259 9260 // If this is not a secure call, don't let it kill processes that 9261 // are important. 9262 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9263 worstType = ProcessList.SERVICE_ADJ; 9264 } 9265 9266 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9267 for (int i=0; i<pids.length; i++) { 9268 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9269 if (proc == null) { 9270 continue; 9271 } 9272 int adj = proc.setAdj; 9273 if (adj >= worstType && !proc.killedByAm) { 9274 killUnneededProcessLocked(proc, reason); 9275 killed = true; 9276 } 9277 } 9278 } 9279 return killed; 9280 } 9281 9282 @Override 9283 public void killUid(int uid, String reason) { 9284 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9285 throw new SecurityException("killUid only available to the system"); 9286 } 9287 synchronized (this) { 9288 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9289 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9290 reason != null ? reason : "kill uid"); 9291 } 9292 } 9293 9294 @Override 9295 public boolean killProcessesBelowForeground(String reason) { 9296 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9297 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9298 } 9299 9300 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9301 } 9302 9303 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9304 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9305 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9306 } 9307 9308 boolean killed = false; 9309 synchronized (mPidsSelfLocked) { 9310 final int size = mPidsSelfLocked.size(); 9311 for (int i = 0; i < size; i++) { 9312 final int pid = mPidsSelfLocked.keyAt(i); 9313 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9314 if (proc == null) continue; 9315 9316 final int adj = proc.setAdj; 9317 if (adj > belowAdj && !proc.killedByAm) { 9318 killUnneededProcessLocked(proc, reason); 9319 killed = true; 9320 } 9321 } 9322 } 9323 return killed; 9324 } 9325 9326 @Override 9327 public void hang(final IBinder who, boolean allowRestart) { 9328 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9329 != PackageManager.PERMISSION_GRANTED) { 9330 throw new SecurityException("Requires permission " 9331 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9332 } 9333 9334 final IBinder.DeathRecipient death = new DeathRecipient() { 9335 @Override 9336 public void binderDied() { 9337 synchronized (this) { 9338 notifyAll(); 9339 } 9340 } 9341 }; 9342 9343 try { 9344 who.linkToDeath(death, 0); 9345 } catch (RemoteException e) { 9346 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9347 return; 9348 } 9349 9350 synchronized (this) { 9351 Watchdog.getInstance().setAllowRestart(allowRestart); 9352 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9353 synchronized (death) { 9354 while (who.isBinderAlive()) { 9355 try { 9356 death.wait(); 9357 } catch (InterruptedException e) { 9358 } 9359 } 9360 } 9361 Watchdog.getInstance().setAllowRestart(true); 9362 } 9363 } 9364 9365 @Override 9366 public void restart() { 9367 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9368 != PackageManager.PERMISSION_GRANTED) { 9369 throw new SecurityException("Requires permission " 9370 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9371 } 9372 9373 Log.i(TAG, "Sending shutdown broadcast..."); 9374 9375 BroadcastReceiver br = new BroadcastReceiver() { 9376 @Override public void onReceive(Context context, Intent intent) { 9377 // Now the broadcast is done, finish up the low-level shutdown. 9378 Log.i(TAG, "Shutting down activity manager..."); 9379 shutdown(10000); 9380 Log.i(TAG, "Shutdown complete, restarting!"); 9381 Process.killProcess(Process.myPid()); 9382 System.exit(10); 9383 } 9384 }; 9385 9386 // First send the high-level shut down broadcast. 9387 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9388 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9389 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9390 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9391 mContext.sendOrderedBroadcastAsUser(intent, 9392 UserHandle.ALL, null, br, mHandler, 0, null, null); 9393 */ 9394 br.onReceive(mContext, intent); 9395 } 9396 9397 private long getLowRamTimeSinceIdle(long now) { 9398 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9399 } 9400 9401 @Override 9402 public void performIdleMaintenance() { 9403 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9404 != PackageManager.PERMISSION_GRANTED) { 9405 throw new SecurityException("Requires permission " 9406 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9407 } 9408 9409 synchronized (this) { 9410 final long now = SystemClock.uptimeMillis(); 9411 final long timeSinceLastIdle = now - mLastIdleTime; 9412 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9413 mLastIdleTime = now; 9414 mLowRamTimeSinceLastIdle = 0; 9415 if (mLowRamStartTime != 0) { 9416 mLowRamStartTime = now; 9417 } 9418 9419 StringBuilder sb = new StringBuilder(128); 9420 sb.append("Idle maintenance over "); 9421 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9422 sb.append(" low RAM for "); 9423 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9424 Slog.i(TAG, sb.toString()); 9425 9426 // If at least 1/3 of our time since the last idle period has been spent 9427 // with RAM low, then we want to kill processes. 9428 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9429 9430 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9431 ProcessRecord proc = mLruProcesses.get(i); 9432 if (proc.notCachedSinceIdle) { 9433 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9434 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9435 if (doKilling && proc.initialIdlePss != 0 9436 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9437 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9438 + " from " + proc.initialIdlePss + ")"); 9439 } 9440 } 9441 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9442 proc.notCachedSinceIdle = true; 9443 proc.initialIdlePss = 0; 9444 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9445 isSleeping(), now); 9446 } 9447 } 9448 9449 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9450 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9451 } 9452 } 9453 9454 private void retrieveSettings() { 9455 final ContentResolver resolver = mContext.getContentResolver(); 9456 String debugApp = Settings.Global.getString( 9457 resolver, Settings.Global.DEBUG_APP); 9458 boolean waitForDebugger = Settings.Global.getInt( 9459 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9460 boolean alwaysFinishActivities = Settings.Global.getInt( 9461 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9462 boolean forceRtl = Settings.Global.getInt( 9463 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9464 // Transfer any global setting for forcing RTL layout, into a System Property 9465 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9466 9467 Configuration configuration = new Configuration(); 9468 Settings.System.getConfiguration(resolver, configuration); 9469 if (forceRtl) { 9470 // This will take care of setting the correct layout direction flags 9471 configuration.setLayoutDirection(configuration.locale); 9472 } 9473 9474 synchronized (this) { 9475 mDebugApp = mOrigDebugApp = debugApp; 9476 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9477 mAlwaysFinishActivities = alwaysFinishActivities; 9478 // This happens before any activities are started, so we can 9479 // change mConfiguration in-place. 9480 updateConfigurationLocked(configuration, null, false, true); 9481 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9482 } 9483 } 9484 9485 public boolean testIsSystemReady() { 9486 // no need to synchronize(this) just to read & return the value 9487 return mSystemReady; 9488 } 9489 9490 private static File getCalledPreBootReceiversFile() { 9491 File dataDir = Environment.getDataDirectory(); 9492 File systemDir = new File(dataDir, "system"); 9493 File fname = new File(systemDir, "called_pre_boots.dat"); 9494 return fname; 9495 } 9496 9497 static final int LAST_DONE_VERSION = 10000; 9498 9499 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9500 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9501 File file = getCalledPreBootReceiversFile(); 9502 FileInputStream fis = null; 9503 try { 9504 fis = new FileInputStream(file); 9505 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9506 int fvers = dis.readInt(); 9507 if (fvers == LAST_DONE_VERSION) { 9508 String vers = dis.readUTF(); 9509 String codename = dis.readUTF(); 9510 String build = dis.readUTF(); 9511 if (android.os.Build.VERSION.RELEASE.equals(vers) 9512 && android.os.Build.VERSION.CODENAME.equals(codename) 9513 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9514 int num = dis.readInt(); 9515 while (num > 0) { 9516 num--; 9517 String pkg = dis.readUTF(); 9518 String cls = dis.readUTF(); 9519 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9520 } 9521 } 9522 } 9523 } catch (FileNotFoundException e) { 9524 } catch (IOException e) { 9525 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9526 } finally { 9527 if (fis != null) { 9528 try { 9529 fis.close(); 9530 } catch (IOException e) { 9531 } 9532 } 9533 } 9534 return lastDoneReceivers; 9535 } 9536 9537 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9538 File file = getCalledPreBootReceiversFile(); 9539 FileOutputStream fos = null; 9540 DataOutputStream dos = null; 9541 try { 9542 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9543 fos = new FileOutputStream(file); 9544 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9545 dos.writeInt(LAST_DONE_VERSION); 9546 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9547 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9548 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9549 dos.writeInt(list.size()); 9550 for (int i=0; i<list.size(); i++) { 9551 dos.writeUTF(list.get(i).getPackageName()); 9552 dos.writeUTF(list.get(i).getClassName()); 9553 } 9554 } catch (IOException e) { 9555 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9556 file.delete(); 9557 } finally { 9558 FileUtils.sync(fos); 9559 if (dos != null) { 9560 try { 9561 dos.close(); 9562 } catch (IOException e) { 9563 // TODO Auto-generated catch block 9564 e.printStackTrace(); 9565 } 9566 } 9567 } 9568 } 9569 9570 public void systemReady(final Runnable goingCallback) { 9571 synchronized(this) { 9572 if (mSystemReady) { 9573 if (goingCallback != null) goingCallback.run(); 9574 return; 9575 } 9576 9577 mRecentTasks = mTaskPersister.restoreTasksLocked(); 9578 if (!mRecentTasks.isEmpty()) { 9579 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 9580 } 9581 mTaskPersister.startPersisting(); 9582 9583 // Check to see if there are any update receivers to run. 9584 if (!mDidUpdate) { 9585 if (mWaitingUpdate) { 9586 return; 9587 } 9588 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9589 List<ResolveInfo> ris = null; 9590 try { 9591 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9592 intent, null, 0, 0); 9593 } catch (RemoteException e) { 9594 } 9595 if (ris != null) { 9596 for (int i=ris.size()-1; i>=0; i--) { 9597 if ((ris.get(i).activityInfo.applicationInfo.flags 9598 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9599 ris.remove(i); 9600 } 9601 } 9602 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9603 9604 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9605 9606 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9607 for (int i=0; i<ris.size(); i++) { 9608 ActivityInfo ai = ris.get(i).activityInfo; 9609 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9610 if (lastDoneReceivers.contains(comp)) { 9611 // We already did the pre boot receiver for this app with the current 9612 // platform version, so don't do it again... 9613 ris.remove(i); 9614 i--; 9615 // ...however, do keep it as one that has been done, so we don't 9616 // forget about it when rewriting the file of last done receivers. 9617 doneReceivers.add(comp); 9618 } 9619 } 9620 9621 final int[] users = getUsersLocked(); 9622 for (int i=0; i<ris.size(); i++) { 9623 ActivityInfo ai = ris.get(i).activityInfo; 9624 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9625 doneReceivers.add(comp); 9626 intent.setComponent(comp); 9627 for (int j=0; j<users.length; j++) { 9628 IIntentReceiver finisher = null; 9629 if (i == ris.size()-1 && j == users.length-1) { 9630 finisher = new IIntentReceiver.Stub() { 9631 public void performReceive(Intent intent, int resultCode, 9632 String data, Bundle extras, boolean ordered, 9633 boolean sticky, int sendingUser) { 9634 // The raw IIntentReceiver interface is called 9635 // with the AM lock held, so redispatch to 9636 // execute our code without the lock. 9637 mHandler.post(new Runnable() { 9638 public void run() { 9639 synchronized (ActivityManagerService.this) { 9640 mDidUpdate = true; 9641 } 9642 writeLastDonePreBootReceivers(doneReceivers); 9643 showBootMessage(mContext.getText( 9644 R.string.android_upgrading_complete), 9645 false); 9646 systemReady(goingCallback); 9647 } 9648 }); 9649 } 9650 }; 9651 } 9652 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9653 + " for user " + users[j]); 9654 broadcastIntentLocked(null, null, intent, null, finisher, 9655 0, null, null, null, AppOpsManager.OP_NONE, 9656 true, false, MY_PID, Process.SYSTEM_UID, 9657 users[j]); 9658 if (finisher != null) { 9659 mWaitingUpdate = true; 9660 } 9661 } 9662 } 9663 } 9664 if (mWaitingUpdate) { 9665 return; 9666 } 9667 mDidUpdate = true; 9668 } 9669 9670 mAppOpsService.systemReady(); 9671 mUsageStatsService.systemReady(); 9672 mSystemReady = true; 9673 } 9674 9675 ArrayList<ProcessRecord> procsToKill = null; 9676 synchronized(mPidsSelfLocked) { 9677 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9678 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9679 if (!isAllowedWhileBooting(proc.info)){ 9680 if (procsToKill == null) { 9681 procsToKill = new ArrayList<ProcessRecord>(); 9682 } 9683 procsToKill.add(proc); 9684 } 9685 } 9686 } 9687 9688 synchronized(this) { 9689 if (procsToKill != null) { 9690 for (int i=procsToKill.size()-1; i>=0; i--) { 9691 ProcessRecord proc = procsToKill.get(i); 9692 Slog.i(TAG, "Removing system update proc: " + proc); 9693 removeProcessLocked(proc, true, false, "system update done"); 9694 } 9695 } 9696 9697 // Now that we have cleaned up any update processes, we 9698 // are ready to start launching real processes and know that 9699 // we won't trample on them any more. 9700 mProcessesReady = true; 9701 } 9702 9703 Slog.i(TAG, "System now ready"); 9704 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9705 SystemClock.uptimeMillis()); 9706 9707 synchronized(this) { 9708 // Make sure we have no pre-ready processes sitting around. 9709 9710 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9711 ResolveInfo ri = mContext.getPackageManager() 9712 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9713 STOCK_PM_FLAGS); 9714 CharSequence errorMsg = null; 9715 if (ri != null) { 9716 ActivityInfo ai = ri.activityInfo; 9717 ApplicationInfo app = ai.applicationInfo; 9718 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9719 mTopAction = Intent.ACTION_FACTORY_TEST; 9720 mTopData = null; 9721 mTopComponent = new ComponentName(app.packageName, 9722 ai.name); 9723 } else { 9724 errorMsg = mContext.getResources().getText( 9725 com.android.internal.R.string.factorytest_not_system); 9726 } 9727 } else { 9728 errorMsg = mContext.getResources().getText( 9729 com.android.internal.R.string.factorytest_no_action); 9730 } 9731 if (errorMsg != null) { 9732 mTopAction = null; 9733 mTopData = null; 9734 mTopComponent = null; 9735 Message msg = Message.obtain(); 9736 msg.what = SHOW_FACTORY_ERROR_MSG; 9737 msg.getData().putCharSequence("msg", errorMsg); 9738 mHandler.sendMessage(msg); 9739 } 9740 } 9741 } 9742 9743 retrieveSettings(); 9744 9745 synchronized (this) { 9746 readGrantedUriPermissionsLocked(); 9747 } 9748 9749 if (goingCallback != null) goingCallback.run(); 9750 9751 mSystemServiceManager.startUser(mCurrentUserId); 9752 9753 synchronized (this) { 9754 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9755 try { 9756 List apps = AppGlobals.getPackageManager(). 9757 getPersistentApplications(STOCK_PM_FLAGS); 9758 if (apps != null) { 9759 int N = apps.size(); 9760 int i; 9761 for (i=0; i<N; i++) { 9762 ApplicationInfo info 9763 = (ApplicationInfo)apps.get(i); 9764 if (info != null && 9765 !info.packageName.equals("android")) { 9766 addAppLocked(info, false); 9767 } 9768 } 9769 } 9770 } catch (RemoteException ex) { 9771 // pm is in same process, this will never happen. 9772 } 9773 } 9774 9775 // Start up initial activity. 9776 mBooting = true; 9777 9778 try { 9779 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9780 Message msg = Message.obtain(); 9781 msg.what = SHOW_UID_ERROR_MSG; 9782 mHandler.sendMessage(msg); 9783 } 9784 } catch (RemoteException e) { 9785 } 9786 9787 long ident = Binder.clearCallingIdentity(); 9788 try { 9789 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9790 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9791 | Intent.FLAG_RECEIVER_FOREGROUND); 9792 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9793 broadcastIntentLocked(null, null, intent, 9794 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9795 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9796 intent = new Intent(Intent.ACTION_USER_STARTING); 9797 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9798 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9799 broadcastIntentLocked(null, null, intent, 9800 null, new IIntentReceiver.Stub() { 9801 @Override 9802 public void performReceive(Intent intent, int resultCode, String data, 9803 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9804 throws RemoteException { 9805 } 9806 }, 0, null, null, 9807 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9808 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9809 } catch (Throwable t) { 9810 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 9811 } finally { 9812 Binder.restoreCallingIdentity(ident); 9813 } 9814 mStackSupervisor.resumeTopActivitiesLocked(); 9815 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9816 } 9817 } 9818 9819 private boolean makeAppCrashingLocked(ProcessRecord app, 9820 String shortMsg, String longMsg, String stackTrace) { 9821 app.crashing = true; 9822 app.crashingReport = generateProcessError(app, 9823 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9824 startAppProblemLocked(app); 9825 app.stopFreezingAllLocked(); 9826 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9827 } 9828 9829 private void makeAppNotRespondingLocked(ProcessRecord app, 9830 String activity, String shortMsg, String longMsg) { 9831 app.notResponding = true; 9832 app.notRespondingReport = generateProcessError(app, 9833 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9834 activity, shortMsg, longMsg, null); 9835 startAppProblemLocked(app); 9836 app.stopFreezingAllLocked(); 9837 } 9838 9839 /** 9840 * Generate a process error record, suitable for attachment to a ProcessRecord. 9841 * 9842 * @param app The ProcessRecord in which the error occurred. 9843 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9844 * ActivityManager.AppErrorStateInfo 9845 * @param activity The activity associated with the crash, if known. 9846 * @param shortMsg Short message describing the crash. 9847 * @param longMsg Long message describing the crash. 9848 * @param stackTrace Full crash stack trace, may be null. 9849 * 9850 * @return Returns a fully-formed AppErrorStateInfo record. 9851 */ 9852 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9853 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9854 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9855 9856 report.condition = condition; 9857 report.processName = app.processName; 9858 report.pid = app.pid; 9859 report.uid = app.info.uid; 9860 report.tag = activity; 9861 report.shortMsg = shortMsg; 9862 report.longMsg = longMsg; 9863 report.stackTrace = stackTrace; 9864 9865 return report; 9866 } 9867 9868 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9869 synchronized (this) { 9870 app.crashing = false; 9871 app.crashingReport = null; 9872 app.notResponding = false; 9873 app.notRespondingReport = null; 9874 if (app.anrDialog == fromDialog) { 9875 app.anrDialog = null; 9876 } 9877 if (app.waitDialog == fromDialog) { 9878 app.waitDialog = null; 9879 } 9880 if (app.pid > 0 && app.pid != MY_PID) { 9881 handleAppCrashLocked(app, null, null, null); 9882 killUnneededProcessLocked(app, "user request after error"); 9883 } 9884 } 9885 } 9886 9887 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9888 String stackTrace) { 9889 long now = SystemClock.uptimeMillis(); 9890 9891 Long crashTime; 9892 if (!app.isolated) { 9893 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9894 } else { 9895 crashTime = null; 9896 } 9897 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9898 // This process loses! 9899 Slog.w(TAG, "Process " + app.info.processName 9900 + " has crashed too many times: killing!"); 9901 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9902 app.userId, app.info.processName, app.uid); 9903 mStackSupervisor.handleAppCrashLocked(app); 9904 if (!app.persistent) { 9905 // We don't want to start this process again until the user 9906 // explicitly does so... but for persistent process, we really 9907 // need to keep it running. If a persistent process is actually 9908 // repeatedly crashing, then badness for everyone. 9909 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9910 app.info.processName); 9911 if (!app.isolated) { 9912 // XXX We don't have a way to mark isolated processes 9913 // as bad, since they don't have a peristent identity. 9914 mBadProcesses.put(app.info.processName, app.uid, 9915 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9916 mProcessCrashTimes.remove(app.info.processName, app.uid); 9917 } 9918 app.bad = true; 9919 app.removed = true; 9920 // Don't let services in this process be restarted and potentially 9921 // annoy the user repeatedly. Unless it is persistent, since those 9922 // processes run critical code. 9923 removeProcessLocked(app, false, false, "crash"); 9924 mStackSupervisor.resumeTopActivitiesLocked(); 9925 return false; 9926 } 9927 mStackSupervisor.resumeTopActivitiesLocked(); 9928 } else { 9929 mStackSupervisor.finishTopRunningActivityLocked(app); 9930 } 9931 9932 // Bump up the crash count of any services currently running in the proc. 9933 for (int i=app.services.size()-1; i>=0; i--) { 9934 // Any services running in the application need to be placed 9935 // back in the pending list. 9936 ServiceRecord sr = app.services.valueAt(i); 9937 sr.crashCount++; 9938 } 9939 9940 // If the crashing process is what we consider to be the "home process" and it has been 9941 // replaced by a third-party app, clear the package preferred activities from packages 9942 // with a home activity running in the process to prevent a repeatedly crashing app 9943 // from blocking the user to manually clear the list. 9944 final ArrayList<ActivityRecord> activities = app.activities; 9945 if (app == mHomeProcess && activities.size() > 0 9946 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9947 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9948 final ActivityRecord r = activities.get(activityNdx); 9949 if (r.isHomeActivity()) { 9950 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9951 try { 9952 ActivityThread.getPackageManager() 9953 .clearPackagePreferredActivities(r.packageName); 9954 } catch (RemoteException c) { 9955 // pm is in same process, this will never happen. 9956 } 9957 } 9958 } 9959 } 9960 9961 if (!app.isolated) { 9962 // XXX Can't keep track of crash times for isolated processes, 9963 // because they don't have a perisistent identity. 9964 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9965 } 9966 9967 return true; 9968 } 9969 9970 void startAppProblemLocked(ProcessRecord app) { 9971 if (app.userId == mCurrentUserId) { 9972 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9973 mContext, app.info.packageName, app.info.flags); 9974 } else { 9975 // If this app is not running under the current user, then we 9976 // can't give it a report button because that would require 9977 // launching the report UI under a different user. 9978 app.errorReportReceiver = null; 9979 } 9980 skipCurrentReceiverLocked(app); 9981 } 9982 9983 void skipCurrentReceiverLocked(ProcessRecord app) { 9984 for (BroadcastQueue queue : mBroadcastQueues) { 9985 queue.skipCurrentReceiverLocked(app); 9986 } 9987 } 9988 9989 /** 9990 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9991 * The application process will exit immediately after this call returns. 9992 * @param app object of the crashing app, null for the system server 9993 * @param crashInfo describing the exception 9994 */ 9995 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9996 ProcessRecord r = findAppProcess(app, "Crash"); 9997 final String processName = app == null ? "system_server" 9998 : (r == null ? "unknown" : r.processName); 9999 10000 handleApplicationCrashInner("crash", r, processName, crashInfo); 10001 } 10002 10003 /* Native crash reporting uses this inner version because it needs to be somewhat 10004 * decoupled from the AM-managed cleanup lifecycle 10005 */ 10006 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 10007 ApplicationErrorReport.CrashInfo crashInfo) { 10008 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10009 UserHandle.getUserId(Binder.getCallingUid()), processName, 10010 r == null ? -1 : r.info.flags, 10011 crashInfo.exceptionClassName, 10012 crashInfo.exceptionMessage, 10013 crashInfo.throwFileName, 10014 crashInfo.throwLineNumber); 10015 10016 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10017 10018 crashApplication(r, crashInfo); 10019 } 10020 10021 public void handleApplicationStrictModeViolation( 10022 IBinder app, 10023 int violationMask, 10024 StrictMode.ViolationInfo info) { 10025 ProcessRecord r = findAppProcess(app, "StrictMode"); 10026 if (r == null) { 10027 return; 10028 } 10029 10030 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10031 Integer stackFingerprint = info.hashCode(); 10032 boolean logIt = true; 10033 synchronized (mAlreadyLoggedViolatedStacks) { 10034 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10035 logIt = false; 10036 // TODO: sub-sample into EventLog for these, with 10037 // the info.durationMillis? Then we'd get 10038 // the relative pain numbers, without logging all 10039 // the stack traces repeatedly. We'd want to do 10040 // likewise in the client code, which also does 10041 // dup suppression, before the Binder call. 10042 } else { 10043 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10044 mAlreadyLoggedViolatedStacks.clear(); 10045 } 10046 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10047 } 10048 } 10049 if (logIt) { 10050 logStrictModeViolationToDropBox(r, info); 10051 } 10052 } 10053 10054 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10055 AppErrorResult result = new AppErrorResult(); 10056 synchronized (this) { 10057 final long origId = Binder.clearCallingIdentity(); 10058 10059 Message msg = Message.obtain(); 10060 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10061 HashMap<String, Object> data = new HashMap<String, Object>(); 10062 data.put("result", result); 10063 data.put("app", r); 10064 data.put("violationMask", violationMask); 10065 data.put("info", info); 10066 msg.obj = data; 10067 mHandler.sendMessage(msg); 10068 10069 Binder.restoreCallingIdentity(origId); 10070 } 10071 int res = result.get(); 10072 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10073 } 10074 } 10075 10076 // Depending on the policy in effect, there could be a bunch of 10077 // these in quick succession so we try to batch these together to 10078 // minimize disk writes, number of dropbox entries, and maximize 10079 // compression, by having more fewer, larger records. 10080 private void logStrictModeViolationToDropBox( 10081 ProcessRecord process, 10082 StrictMode.ViolationInfo info) { 10083 if (info == null) { 10084 return; 10085 } 10086 final boolean isSystemApp = process == null || 10087 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10088 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10089 final String processName = process == null ? "unknown" : process.processName; 10090 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10091 final DropBoxManager dbox = (DropBoxManager) 10092 mContext.getSystemService(Context.DROPBOX_SERVICE); 10093 10094 // Exit early if the dropbox isn't configured to accept this report type. 10095 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10096 10097 boolean bufferWasEmpty; 10098 boolean needsFlush; 10099 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10100 synchronized (sb) { 10101 bufferWasEmpty = sb.length() == 0; 10102 appendDropBoxProcessHeaders(process, processName, sb); 10103 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10104 sb.append("System-App: ").append(isSystemApp).append("\n"); 10105 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10106 if (info.violationNumThisLoop != 0) { 10107 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10108 } 10109 if (info.numAnimationsRunning != 0) { 10110 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10111 } 10112 if (info.broadcastIntentAction != null) { 10113 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10114 } 10115 if (info.durationMillis != -1) { 10116 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10117 } 10118 if (info.numInstances != -1) { 10119 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10120 } 10121 if (info.tags != null) { 10122 for (String tag : info.tags) { 10123 sb.append("Span-Tag: ").append(tag).append("\n"); 10124 } 10125 } 10126 sb.append("\n"); 10127 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10128 sb.append(info.crashInfo.stackTrace); 10129 } 10130 sb.append("\n"); 10131 10132 // Only buffer up to ~64k. Various logging bits truncate 10133 // things at 128k. 10134 needsFlush = (sb.length() > 64 * 1024); 10135 } 10136 10137 // Flush immediately if the buffer's grown too large, or this 10138 // is a non-system app. Non-system apps are isolated with a 10139 // different tag & policy and not batched. 10140 // 10141 // Batching is useful during internal testing with 10142 // StrictMode settings turned up high. Without batching, 10143 // thousands of separate files could be created on boot. 10144 if (!isSystemApp || needsFlush) { 10145 new Thread("Error dump: " + dropboxTag) { 10146 @Override 10147 public void run() { 10148 String report; 10149 synchronized (sb) { 10150 report = sb.toString(); 10151 sb.delete(0, sb.length()); 10152 sb.trimToSize(); 10153 } 10154 if (report.length() != 0) { 10155 dbox.addText(dropboxTag, report); 10156 } 10157 } 10158 }.start(); 10159 return; 10160 } 10161 10162 // System app batching: 10163 if (!bufferWasEmpty) { 10164 // An existing dropbox-writing thread is outstanding, so 10165 // we don't need to start it up. The existing thread will 10166 // catch the buffer appends we just did. 10167 return; 10168 } 10169 10170 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10171 // (After this point, we shouldn't access AMS internal data structures.) 10172 new Thread("Error dump: " + dropboxTag) { 10173 @Override 10174 public void run() { 10175 // 5 second sleep to let stacks arrive and be batched together 10176 try { 10177 Thread.sleep(5000); // 5 seconds 10178 } catch (InterruptedException e) {} 10179 10180 String errorReport; 10181 synchronized (mStrictModeBuffer) { 10182 errorReport = mStrictModeBuffer.toString(); 10183 if (errorReport.length() == 0) { 10184 return; 10185 } 10186 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10187 mStrictModeBuffer.trimToSize(); 10188 } 10189 dbox.addText(dropboxTag, errorReport); 10190 } 10191 }.start(); 10192 } 10193 10194 /** 10195 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10196 * @param app object of the crashing app, null for the system server 10197 * @param tag reported by the caller 10198 * @param crashInfo describing the context of the error 10199 * @return true if the process should exit immediately (WTF is fatal) 10200 */ 10201 public boolean handleApplicationWtf(IBinder app, String tag, 10202 ApplicationErrorReport.CrashInfo crashInfo) { 10203 ProcessRecord r = findAppProcess(app, "WTF"); 10204 final String processName = app == null ? "system_server" 10205 : (r == null ? "unknown" : r.processName); 10206 10207 EventLog.writeEvent(EventLogTags.AM_WTF, 10208 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10209 processName, 10210 r == null ? -1 : r.info.flags, 10211 tag, crashInfo.exceptionMessage); 10212 10213 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10214 10215 if (r != null && r.pid != Process.myPid() && 10216 Settings.Global.getInt(mContext.getContentResolver(), 10217 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10218 crashApplication(r, crashInfo); 10219 return true; 10220 } else { 10221 return false; 10222 } 10223 } 10224 10225 /** 10226 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10227 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10228 */ 10229 private ProcessRecord findAppProcess(IBinder app, String reason) { 10230 if (app == null) { 10231 return null; 10232 } 10233 10234 synchronized (this) { 10235 final int NP = mProcessNames.getMap().size(); 10236 for (int ip=0; ip<NP; ip++) { 10237 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10238 final int NA = apps.size(); 10239 for (int ia=0; ia<NA; ia++) { 10240 ProcessRecord p = apps.valueAt(ia); 10241 if (p.thread != null && p.thread.asBinder() == app) { 10242 return p; 10243 } 10244 } 10245 } 10246 10247 Slog.w(TAG, "Can't find mystery application for " + reason 10248 + " from pid=" + Binder.getCallingPid() 10249 + " uid=" + Binder.getCallingUid() + ": " + app); 10250 return null; 10251 } 10252 } 10253 10254 /** 10255 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10256 * to append various headers to the dropbox log text. 10257 */ 10258 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10259 StringBuilder sb) { 10260 // Watchdog thread ends up invoking this function (with 10261 // a null ProcessRecord) to add the stack file to dropbox. 10262 // Do not acquire a lock on this (am) in such cases, as it 10263 // could cause a potential deadlock, if and when watchdog 10264 // is invoked due to unavailability of lock on am and it 10265 // would prevent watchdog from killing system_server. 10266 if (process == null) { 10267 sb.append("Process: ").append(processName).append("\n"); 10268 return; 10269 } 10270 // Note: ProcessRecord 'process' is guarded by the service 10271 // instance. (notably process.pkgList, which could otherwise change 10272 // concurrently during execution of this method) 10273 synchronized (this) { 10274 sb.append("Process: ").append(processName).append("\n"); 10275 int flags = process.info.flags; 10276 IPackageManager pm = AppGlobals.getPackageManager(); 10277 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10278 for (int ip=0; ip<process.pkgList.size(); ip++) { 10279 String pkg = process.pkgList.keyAt(ip); 10280 sb.append("Package: ").append(pkg); 10281 try { 10282 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10283 if (pi != null) { 10284 sb.append(" v").append(pi.versionCode); 10285 if (pi.versionName != null) { 10286 sb.append(" (").append(pi.versionName).append(")"); 10287 } 10288 } 10289 } catch (RemoteException e) { 10290 Slog.e(TAG, "Error getting package info: " + pkg, e); 10291 } 10292 sb.append("\n"); 10293 } 10294 } 10295 } 10296 10297 private static String processClass(ProcessRecord process) { 10298 if (process == null || process.pid == MY_PID) { 10299 return "system_server"; 10300 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10301 return "system_app"; 10302 } else { 10303 return "data_app"; 10304 } 10305 } 10306 10307 /** 10308 * Write a description of an error (crash, WTF, ANR) to the drop box. 10309 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10310 * @param process which caused the error, null means the system server 10311 * @param activity which triggered the error, null if unknown 10312 * @param parent activity related to the error, null if unknown 10313 * @param subject line related to the error, null if absent 10314 * @param report in long form describing the error, null if absent 10315 * @param logFile to include in the report, null if none 10316 * @param crashInfo giving an application stack trace, null if absent 10317 */ 10318 public void addErrorToDropBox(String eventType, 10319 ProcessRecord process, String processName, ActivityRecord activity, 10320 ActivityRecord parent, String subject, 10321 final String report, final File logFile, 10322 final ApplicationErrorReport.CrashInfo crashInfo) { 10323 // NOTE -- this must never acquire the ActivityManagerService lock, 10324 // otherwise the watchdog may be prevented from resetting the system. 10325 10326 final String dropboxTag = processClass(process) + "_" + eventType; 10327 final DropBoxManager dbox = (DropBoxManager) 10328 mContext.getSystemService(Context.DROPBOX_SERVICE); 10329 10330 // Exit early if the dropbox isn't configured to accept this report type. 10331 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10332 10333 final StringBuilder sb = new StringBuilder(1024); 10334 appendDropBoxProcessHeaders(process, processName, sb); 10335 if (activity != null) { 10336 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10337 } 10338 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10339 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10340 } 10341 if (parent != null && parent != activity) { 10342 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10343 } 10344 if (subject != null) { 10345 sb.append("Subject: ").append(subject).append("\n"); 10346 } 10347 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10348 if (Debug.isDebuggerConnected()) { 10349 sb.append("Debugger: Connected\n"); 10350 } 10351 sb.append("\n"); 10352 10353 // Do the rest in a worker thread to avoid blocking the caller on I/O 10354 // (After this point, we shouldn't access AMS internal data structures.) 10355 Thread worker = new Thread("Error dump: " + dropboxTag) { 10356 @Override 10357 public void run() { 10358 if (report != null) { 10359 sb.append(report); 10360 } 10361 if (logFile != null) { 10362 try { 10363 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10364 "\n\n[[TRUNCATED]]")); 10365 } catch (IOException e) { 10366 Slog.e(TAG, "Error reading " + logFile, e); 10367 } 10368 } 10369 if (crashInfo != null && crashInfo.stackTrace != null) { 10370 sb.append(crashInfo.stackTrace); 10371 } 10372 10373 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10374 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10375 if (lines > 0) { 10376 sb.append("\n"); 10377 10378 // Merge several logcat streams, and take the last N lines 10379 InputStreamReader input = null; 10380 try { 10381 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10382 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10383 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10384 10385 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10386 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10387 input = new InputStreamReader(logcat.getInputStream()); 10388 10389 int num; 10390 char[] buf = new char[8192]; 10391 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10392 } catch (IOException e) { 10393 Slog.e(TAG, "Error running logcat", e); 10394 } finally { 10395 if (input != null) try { input.close(); } catch (IOException e) {} 10396 } 10397 } 10398 10399 dbox.addText(dropboxTag, sb.toString()); 10400 } 10401 }; 10402 10403 if (process == null) { 10404 // If process is null, we are being called from some internal code 10405 // and may be about to die -- run this synchronously. 10406 worker.run(); 10407 } else { 10408 worker.start(); 10409 } 10410 } 10411 10412 /** 10413 * Bring up the "unexpected error" dialog box for a crashing app. 10414 * Deal with edge cases (intercepts from instrumented applications, 10415 * ActivityController, error intent receivers, that sort of thing). 10416 * @param r the application crashing 10417 * @param crashInfo describing the failure 10418 */ 10419 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10420 long timeMillis = System.currentTimeMillis(); 10421 String shortMsg = crashInfo.exceptionClassName; 10422 String longMsg = crashInfo.exceptionMessage; 10423 String stackTrace = crashInfo.stackTrace; 10424 if (shortMsg != null && longMsg != null) { 10425 longMsg = shortMsg + ": " + longMsg; 10426 } else if (shortMsg != null) { 10427 longMsg = shortMsg; 10428 } 10429 10430 AppErrorResult result = new AppErrorResult(); 10431 synchronized (this) { 10432 if (mController != null) { 10433 try { 10434 String name = r != null ? r.processName : null; 10435 int pid = r != null ? r.pid : Binder.getCallingPid(); 10436 if (!mController.appCrashed(name, pid, 10437 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10438 Slog.w(TAG, "Force-killing crashed app " + name 10439 + " at watcher's request"); 10440 Process.killProcess(pid); 10441 return; 10442 } 10443 } catch (RemoteException e) { 10444 mController = null; 10445 Watchdog.getInstance().setActivityController(null); 10446 } 10447 } 10448 10449 final long origId = Binder.clearCallingIdentity(); 10450 10451 // If this process is running instrumentation, finish it. 10452 if (r != null && r.instrumentationClass != null) { 10453 Slog.w(TAG, "Error in app " + r.processName 10454 + " running instrumentation " + r.instrumentationClass + ":"); 10455 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10456 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10457 Bundle info = new Bundle(); 10458 info.putString("shortMsg", shortMsg); 10459 info.putString("longMsg", longMsg); 10460 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10461 Binder.restoreCallingIdentity(origId); 10462 return; 10463 } 10464 10465 // If we can't identify the process or it's already exceeded its crash quota, 10466 // quit right away without showing a crash dialog. 10467 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10468 Binder.restoreCallingIdentity(origId); 10469 return; 10470 } 10471 10472 Message msg = Message.obtain(); 10473 msg.what = SHOW_ERROR_MSG; 10474 HashMap data = new HashMap(); 10475 data.put("result", result); 10476 data.put("app", r); 10477 msg.obj = data; 10478 mHandler.sendMessage(msg); 10479 10480 Binder.restoreCallingIdentity(origId); 10481 } 10482 10483 int res = result.get(); 10484 10485 Intent appErrorIntent = null; 10486 synchronized (this) { 10487 if (r != null && !r.isolated) { 10488 // XXX Can't keep track of crash time for isolated processes, 10489 // since they don't have a persistent identity. 10490 mProcessCrashTimes.put(r.info.processName, r.uid, 10491 SystemClock.uptimeMillis()); 10492 } 10493 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10494 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10495 } 10496 } 10497 10498 if (appErrorIntent != null) { 10499 try { 10500 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10501 } catch (ActivityNotFoundException e) { 10502 Slog.w(TAG, "bug report receiver dissappeared", e); 10503 } 10504 } 10505 } 10506 10507 Intent createAppErrorIntentLocked(ProcessRecord r, 10508 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10509 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10510 if (report == null) { 10511 return null; 10512 } 10513 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10514 result.setComponent(r.errorReportReceiver); 10515 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10516 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10517 return result; 10518 } 10519 10520 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10521 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10522 if (r.errorReportReceiver == null) { 10523 return null; 10524 } 10525 10526 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10527 return null; 10528 } 10529 10530 ApplicationErrorReport report = new ApplicationErrorReport(); 10531 report.packageName = r.info.packageName; 10532 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10533 report.processName = r.processName; 10534 report.time = timeMillis; 10535 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10536 10537 if (r.crashing || r.forceCrashReport) { 10538 report.type = ApplicationErrorReport.TYPE_CRASH; 10539 report.crashInfo = crashInfo; 10540 } else if (r.notResponding) { 10541 report.type = ApplicationErrorReport.TYPE_ANR; 10542 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10543 10544 report.anrInfo.activity = r.notRespondingReport.tag; 10545 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10546 report.anrInfo.info = r.notRespondingReport.longMsg; 10547 } 10548 10549 return report; 10550 } 10551 10552 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10553 enforceNotIsolatedCaller("getProcessesInErrorState"); 10554 // assume our apps are happy - lazy create the list 10555 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10556 10557 final boolean allUsers = ActivityManager.checkUidPermission( 10558 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10559 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10560 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10561 10562 synchronized (this) { 10563 10564 // iterate across all processes 10565 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10566 ProcessRecord app = mLruProcesses.get(i); 10567 if (!allUsers && app.userId != userId) { 10568 continue; 10569 } 10570 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10571 // This one's in trouble, so we'll generate a report for it 10572 // crashes are higher priority (in case there's a crash *and* an anr) 10573 ActivityManager.ProcessErrorStateInfo report = null; 10574 if (app.crashing) { 10575 report = app.crashingReport; 10576 } else if (app.notResponding) { 10577 report = app.notRespondingReport; 10578 } 10579 10580 if (report != null) { 10581 if (errList == null) { 10582 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10583 } 10584 errList.add(report); 10585 } else { 10586 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10587 " crashing = " + app.crashing + 10588 " notResponding = " + app.notResponding); 10589 } 10590 } 10591 } 10592 } 10593 10594 return errList; 10595 } 10596 10597 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10598 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10599 if (currApp != null) { 10600 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10601 } 10602 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10603 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10604 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10605 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10606 if (currApp != null) { 10607 currApp.lru = 0; 10608 } 10609 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10610 } else if (adj >= ProcessList.SERVICE_ADJ) { 10611 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10612 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10613 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10614 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10615 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10616 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10617 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10618 } else { 10619 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10620 } 10621 } 10622 10623 private void fillInProcMemInfo(ProcessRecord app, 10624 ActivityManager.RunningAppProcessInfo outInfo) { 10625 outInfo.pid = app.pid; 10626 outInfo.uid = app.info.uid; 10627 if (mHeavyWeightProcess == app) { 10628 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10629 } 10630 if (app.persistent) { 10631 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10632 } 10633 if (app.activities.size() > 0) { 10634 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10635 } 10636 outInfo.lastTrimLevel = app.trimMemoryLevel; 10637 int adj = app.curAdj; 10638 outInfo.importance = oomAdjToImportance(adj, outInfo); 10639 outInfo.importanceReasonCode = app.adjTypeCode; 10640 outInfo.processState = app.curProcState; 10641 } 10642 10643 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10644 enforceNotIsolatedCaller("getRunningAppProcesses"); 10645 // Lazy instantiation of list 10646 List<ActivityManager.RunningAppProcessInfo> runList = null; 10647 final boolean allUsers = ActivityManager.checkUidPermission( 10648 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10649 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10650 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10651 synchronized (this) { 10652 // Iterate across all processes 10653 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10654 ProcessRecord app = mLruProcesses.get(i); 10655 if (!allUsers && app.userId != userId) { 10656 continue; 10657 } 10658 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10659 // Generate process state info for running application 10660 ActivityManager.RunningAppProcessInfo currApp = 10661 new ActivityManager.RunningAppProcessInfo(app.processName, 10662 app.pid, app.getPackageList()); 10663 fillInProcMemInfo(app, currApp); 10664 if (app.adjSource instanceof ProcessRecord) { 10665 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10666 currApp.importanceReasonImportance = oomAdjToImportance( 10667 app.adjSourceOom, null); 10668 } else if (app.adjSource instanceof ActivityRecord) { 10669 ActivityRecord r = (ActivityRecord)app.adjSource; 10670 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10671 } 10672 if (app.adjTarget instanceof ComponentName) { 10673 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10674 } 10675 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10676 // + " lru=" + currApp.lru); 10677 if (runList == null) { 10678 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10679 } 10680 runList.add(currApp); 10681 } 10682 } 10683 } 10684 return runList; 10685 } 10686 10687 public List<ApplicationInfo> getRunningExternalApplications() { 10688 enforceNotIsolatedCaller("getRunningExternalApplications"); 10689 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10690 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10691 if (runningApps != null && runningApps.size() > 0) { 10692 Set<String> extList = new HashSet<String>(); 10693 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10694 if (app.pkgList != null) { 10695 for (String pkg : app.pkgList) { 10696 extList.add(pkg); 10697 } 10698 } 10699 } 10700 IPackageManager pm = AppGlobals.getPackageManager(); 10701 for (String pkg : extList) { 10702 try { 10703 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10704 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10705 retList.add(info); 10706 } 10707 } catch (RemoteException e) { 10708 } 10709 } 10710 } 10711 return retList; 10712 } 10713 10714 @Override 10715 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10716 enforceNotIsolatedCaller("getMyMemoryState"); 10717 synchronized (this) { 10718 ProcessRecord proc; 10719 synchronized (mPidsSelfLocked) { 10720 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10721 } 10722 fillInProcMemInfo(proc, outInfo); 10723 } 10724 } 10725 10726 @Override 10727 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10728 if (checkCallingPermission(android.Manifest.permission.DUMP) 10729 != PackageManager.PERMISSION_GRANTED) { 10730 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10731 + Binder.getCallingPid() 10732 + ", uid=" + Binder.getCallingUid() 10733 + " without permission " 10734 + android.Manifest.permission.DUMP); 10735 return; 10736 } 10737 10738 boolean dumpAll = false; 10739 boolean dumpClient = false; 10740 String dumpPackage = null; 10741 10742 int opti = 0; 10743 while (opti < args.length) { 10744 String opt = args[opti]; 10745 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10746 break; 10747 } 10748 opti++; 10749 if ("-a".equals(opt)) { 10750 dumpAll = true; 10751 } else if ("-c".equals(opt)) { 10752 dumpClient = true; 10753 } else if ("-h".equals(opt)) { 10754 pw.println("Activity manager dump options:"); 10755 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10756 pw.println(" cmd may be one of:"); 10757 pw.println(" a[ctivities]: activity stack state"); 10758 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10759 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10760 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10761 pw.println(" o[om]: out of memory management"); 10762 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10763 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10764 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10765 pw.println(" service [COMP_SPEC]: service client-side state"); 10766 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10767 pw.println(" all: dump all activities"); 10768 pw.println(" top: dump the top activity"); 10769 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10770 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10771 pw.println(" a partial substring in a component name, a"); 10772 pw.println(" hex object identifier."); 10773 pw.println(" -a: include all available server state."); 10774 pw.println(" -c: include client state."); 10775 return; 10776 } else { 10777 pw.println("Unknown argument: " + opt + "; use -h for help"); 10778 } 10779 } 10780 10781 long origId = Binder.clearCallingIdentity(); 10782 boolean more = false; 10783 // Is the caller requesting to dump a particular piece of data? 10784 if (opti < args.length) { 10785 String cmd = args[opti]; 10786 opti++; 10787 if ("activities".equals(cmd) || "a".equals(cmd)) { 10788 synchronized (this) { 10789 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10790 } 10791 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10792 String[] newArgs; 10793 String name; 10794 if (opti >= args.length) { 10795 name = null; 10796 newArgs = EMPTY_STRING_ARRAY; 10797 } else { 10798 name = args[opti]; 10799 opti++; 10800 newArgs = new String[args.length - opti]; 10801 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10802 args.length - opti); 10803 } 10804 synchronized (this) { 10805 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10806 } 10807 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10808 String[] newArgs; 10809 String name; 10810 if (opti >= args.length) { 10811 name = null; 10812 newArgs = EMPTY_STRING_ARRAY; 10813 } else { 10814 name = args[opti]; 10815 opti++; 10816 newArgs = new String[args.length - opti]; 10817 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10818 args.length - opti); 10819 } 10820 synchronized (this) { 10821 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10822 } 10823 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10824 String[] newArgs; 10825 String name; 10826 if (opti >= args.length) { 10827 name = null; 10828 newArgs = EMPTY_STRING_ARRAY; 10829 } else { 10830 name = args[opti]; 10831 opti++; 10832 newArgs = new String[args.length - opti]; 10833 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10834 args.length - opti); 10835 } 10836 synchronized (this) { 10837 dumpProcessesLocked(fd, pw, args, opti, true, name); 10838 } 10839 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10840 synchronized (this) { 10841 dumpOomLocked(fd, pw, args, opti, true); 10842 } 10843 } else if ("provider".equals(cmd)) { 10844 String[] newArgs; 10845 String name; 10846 if (opti >= args.length) { 10847 name = null; 10848 newArgs = EMPTY_STRING_ARRAY; 10849 } else { 10850 name = args[opti]; 10851 opti++; 10852 newArgs = new String[args.length - opti]; 10853 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10854 } 10855 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10856 pw.println("No providers match: " + name); 10857 pw.println("Use -h for help."); 10858 } 10859 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10860 synchronized (this) { 10861 dumpProvidersLocked(fd, pw, args, opti, true, null); 10862 } 10863 } else if ("service".equals(cmd)) { 10864 String[] newArgs; 10865 String name; 10866 if (opti >= args.length) { 10867 name = null; 10868 newArgs = EMPTY_STRING_ARRAY; 10869 } else { 10870 name = args[opti]; 10871 opti++; 10872 newArgs = new String[args.length - opti]; 10873 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10874 args.length - opti); 10875 } 10876 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10877 pw.println("No services match: " + name); 10878 pw.println("Use -h for help."); 10879 } 10880 } else if ("package".equals(cmd)) { 10881 String[] newArgs; 10882 if (opti >= args.length) { 10883 pw.println("package: no package name specified"); 10884 pw.println("Use -h for help."); 10885 } else { 10886 dumpPackage = args[opti]; 10887 opti++; 10888 newArgs = new String[args.length - opti]; 10889 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10890 args.length - opti); 10891 args = newArgs; 10892 opti = 0; 10893 more = true; 10894 } 10895 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10896 synchronized (this) { 10897 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10898 } 10899 } else { 10900 // Dumping a single activity? 10901 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10902 pw.println("Bad activity command, or no activities match: " + cmd); 10903 pw.println("Use -h for help."); 10904 } 10905 } 10906 if (!more) { 10907 Binder.restoreCallingIdentity(origId); 10908 return; 10909 } 10910 } 10911 10912 // No piece of data specified, dump everything. 10913 synchronized (this) { 10914 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10915 pw.println(); 10916 if (dumpAll) { 10917 pw.println("-------------------------------------------------------------------------------"); 10918 } 10919 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10920 pw.println(); 10921 if (dumpAll) { 10922 pw.println("-------------------------------------------------------------------------------"); 10923 } 10924 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10925 pw.println(); 10926 if (dumpAll) { 10927 pw.println("-------------------------------------------------------------------------------"); 10928 } 10929 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10930 pw.println(); 10931 if (dumpAll) { 10932 pw.println("-------------------------------------------------------------------------------"); 10933 } 10934 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10935 pw.println(); 10936 if (dumpAll) { 10937 pw.println("-------------------------------------------------------------------------------"); 10938 } 10939 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10940 } 10941 Binder.restoreCallingIdentity(origId); 10942 } 10943 10944 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10945 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10946 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10947 10948 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10949 dumpPackage); 10950 boolean needSep = printedAnything; 10951 10952 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10953 dumpPackage, needSep, " mFocusedActivity: "); 10954 if (printed) { 10955 printedAnything = true; 10956 needSep = false; 10957 } 10958 10959 if (dumpPackage == null) { 10960 if (needSep) { 10961 pw.println(); 10962 } 10963 needSep = true; 10964 printedAnything = true; 10965 mStackSupervisor.dump(pw, " "); 10966 } 10967 10968 if (mRecentTasks.size() > 0) { 10969 boolean printedHeader = false; 10970 10971 final int N = mRecentTasks.size(); 10972 for (int i=0; i<N; i++) { 10973 TaskRecord tr = mRecentTasks.get(i); 10974 if (dumpPackage != null) { 10975 if (tr.realActivity == null || 10976 !dumpPackage.equals(tr.realActivity)) { 10977 continue; 10978 } 10979 } 10980 if (!printedHeader) { 10981 if (needSep) { 10982 pw.println(); 10983 } 10984 pw.println(" Recent tasks:"); 10985 printedHeader = true; 10986 printedAnything = true; 10987 } 10988 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10989 pw.println(tr); 10990 if (dumpAll) { 10991 mRecentTasks.get(i).dump(pw, " "); 10992 } 10993 } 10994 } 10995 10996 if (!printedAnything) { 10997 pw.println(" (nothing)"); 10998 } 10999 } 11000 11001 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11002 int opti, boolean dumpAll, String dumpPackage) { 11003 boolean needSep = false; 11004 boolean printedAnything = false; 11005 int numPers = 0; 11006 11007 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11008 11009 if (dumpAll) { 11010 final int NP = mProcessNames.getMap().size(); 11011 for (int ip=0; ip<NP; ip++) { 11012 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11013 final int NA = procs.size(); 11014 for (int ia=0; ia<NA; ia++) { 11015 ProcessRecord r = procs.valueAt(ia); 11016 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11017 continue; 11018 } 11019 if (!needSep) { 11020 pw.println(" All known processes:"); 11021 needSep = true; 11022 printedAnything = true; 11023 } 11024 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11025 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11026 pw.print(" "); pw.println(r); 11027 r.dump(pw, " "); 11028 if (r.persistent) { 11029 numPers++; 11030 } 11031 } 11032 } 11033 } 11034 11035 if (mIsolatedProcesses.size() > 0) { 11036 boolean printed = false; 11037 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11038 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11039 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11040 continue; 11041 } 11042 if (!printed) { 11043 if (needSep) { 11044 pw.println(); 11045 } 11046 pw.println(" Isolated process list (sorted by uid):"); 11047 printedAnything = true; 11048 printed = true; 11049 needSep = true; 11050 } 11051 pw.println(String.format("%sIsolated #%2d: %s", 11052 " ", i, r.toString())); 11053 } 11054 } 11055 11056 if (mLruProcesses.size() > 0) { 11057 if (needSep) { 11058 pw.println(); 11059 } 11060 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11061 pw.print(" total, non-act at "); 11062 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11063 pw.print(", non-svc at "); 11064 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11065 pw.println("):"); 11066 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11067 needSep = true; 11068 printedAnything = true; 11069 } 11070 11071 if (dumpAll || dumpPackage != null) { 11072 synchronized (mPidsSelfLocked) { 11073 boolean printed = false; 11074 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11075 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11076 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11077 continue; 11078 } 11079 if (!printed) { 11080 if (needSep) pw.println(); 11081 needSep = true; 11082 pw.println(" PID mappings:"); 11083 printed = true; 11084 printedAnything = true; 11085 } 11086 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11087 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11088 } 11089 } 11090 } 11091 11092 if (mForegroundProcesses.size() > 0) { 11093 synchronized (mPidsSelfLocked) { 11094 boolean printed = false; 11095 for (int i=0; i<mForegroundProcesses.size(); i++) { 11096 ProcessRecord r = mPidsSelfLocked.get( 11097 mForegroundProcesses.valueAt(i).pid); 11098 if (dumpPackage != null && (r == null 11099 || !r.pkgList.containsKey(dumpPackage))) { 11100 continue; 11101 } 11102 if (!printed) { 11103 if (needSep) pw.println(); 11104 needSep = true; 11105 pw.println(" Foreground Processes:"); 11106 printed = true; 11107 printedAnything = true; 11108 } 11109 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11110 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11111 } 11112 } 11113 } 11114 11115 if (mPersistentStartingProcesses.size() > 0) { 11116 if (needSep) pw.println(); 11117 needSep = true; 11118 printedAnything = true; 11119 pw.println(" Persisent processes that are starting:"); 11120 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11121 "Starting Norm", "Restarting PERS", dumpPackage); 11122 } 11123 11124 if (mRemovedProcesses.size() > 0) { 11125 if (needSep) pw.println(); 11126 needSep = true; 11127 printedAnything = true; 11128 pw.println(" Processes that are being removed:"); 11129 dumpProcessList(pw, this, mRemovedProcesses, " ", 11130 "Removed Norm", "Removed PERS", dumpPackage); 11131 } 11132 11133 if (mProcessesOnHold.size() > 0) { 11134 if (needSep) pw.println(); 11135 needSep = true; 11136 printedAnything = true; 11137 pw.println(" Processes that are on old until the system is ready:"); 11138 dumpProcessList(pw, this, mProcessesOnHold, " ", 11139 "OnHold Norm", "OnHold PERS", dumpPackage); 11140 } 11141 11142 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11143 11144 if (mProcessCrashTimes.getMap().size() > 0) { 11145 boolean printed = false; 11146 long now = SystemClock.uptimeMillis(); 11147 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11148 final int NP = pmap.size(); 11149 for (int ip=0; ip<NP; ip++) { 11150 String pname = pmap.keyAt(ip); 11151 SparseArray<Long> uids = pmap.valueAt(ip); 11152 final int N = uids.size(); 11153 for (int i=0; i<N; i++) { 11154 int puid = uids.keyAt(i); 11155 ProcessRecord r = mProcessNames.get(pname, puid); 11156 if (dumpPackage != null && (r == null 11157 || !r.pkgList.containsKey(dumpPackage))) { 11158 continue; 11159 } 11160 if (!printed) { 11161 if (needSep) pw.println(); 11162 needSep = true; 11163 pw.println(" Time since processes crashed:"); 11164 printed = true; 11165 printedAnything = true; 11166 } 11167 pw.print(" Process "); pw.print(pname); 11168 pw.print(" uid "); pw.print(puid); 11169 pw.print(": last crashed "); 11170 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11171 pw.println(" ago"); 11172 } 11173 } 11174 } 11175 11176 if (mBadProcesses.getMap().size() > 0) { 11177 boolean printed = false; 11178 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11179 final int NP = pmap.size(); 11180 for (int ip=0; ip<NP; ip++) { 11181 String pname = pmap.keyAt(ip); 11182 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11183 final int N = uids.size(); 11184 for (int i=0; i<N; i++) { 11185 int puid = uids.keyAt(i); 11186 ProcessRecord r = mProcessNames.get(pname, puid); 11187 if (dumpPackage != null && (r == null 11188 || !r.pkgList.containsKey(dumpPackage))) { 11189 continue; 11190 } 11191 if (!printed) { 11192 if (needSep) pw.println(); 11193 needSep = true; 11194 pw.println(" Bad processes:"); 11195 printedAnything = true; 11196 } 11197 BadProcessInfo info = uids.valueAt(i); 11198 pw.print(" Bad process "); pw.print(pname); 11199 pw.print(" uid "); pw.print(puid); 11200 pw.print(": crashed at time "); pw.println(info.time); 11201 if (info.shortMsg != null) { 11202 pw.print(" Short msg: "); pw.println(info.shortMsg); 11203 } 11204 if (info.longMsg != null) { 11205 pw.print(" Long msg: "); pw.println(info.longMsg); 11206 } 11207 if (info.stack != null) { 11208 pw.println(" Stack:"); 11209 int lastPos = 0; 11210 for (int pos=0; pos<info.stack.length(); pos++) { 11211 if (info.stack.charAt(pos) == '\n') { 11212 pw.print(" "); 11213 pw.write(info.stack, lastPos, pos-lastPos); 11214 pw.println(); 11215 lastPos = pos+1; 11216 } 11217 } 11218 if (lastPos < info.stack.length()) { 11219 pw.print(" "); 11220 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11221 pw.println(); 11222 } 11223 } 11224 } 11225 } 11226 } 11227 11228 if (dumpPackage == null) { 11229 pw.println(); 11230 needSep = false; 11231 pw.println(" mStartedUsers:"); 11232 for (int i=0; i<mStartedUsers.size(); i++) { 11233 UserStartedState uss = mStartedUsers.valueAt(i); 11234 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11235 pw.print(": "); uss.dump("", pw); 11236 } 11237 pw.print(" mStartedUserArray: ["); 11238 for (int i=0; i<mStartedUserArray.length; i++) { 11239 if (i > 0) pw.print(", "); 11240 pw.print(mStartedUserArray[i]); 11241 } 11242 pw.println("]"); 11243 pw.print(" mUserLru: ["); 11244 for (int i=0; i<mUserLru.size(); i++) { 11245 if (i > 0) pw.print(", "); 11246 pw.print(mUserLru.get(i)); 11247 } 11248 pw.println("]"); 11249 if (dumpAll) { 11250 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11251 } 11252 } 11253 if (mHomeProcess != null && (dumpPackage == null 11254 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11255 if (needSep) { 11256 pw.println(); 11257 needSep = false; 11258 } 11259 pw.println(" mHomeProcess: " + mHomeProcess); 11260 } 11261 if (mPreviousProcess != null && (dumpPackage == null 11262 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11263 if (needSep) { 11264 pw.println(); 11265 needSep = false; 11266 } 11267 pw.println(" mPreviousProcess: " + mPreviousProcess); 11268 } 11269 if (dumpAll) { 11270 StringBuilder sb = new StringBuilder(128); 11271 sb.append(" mPreviousProcessVisibleTime: "); 11272 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11273 pw.println(sb); 11274 } 11275 if (mHeavyWeightProcess != null && (dumpPackage == null 11276 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11277 if (needSep) { 11278 pw.println(); 11279 needSep = false; 11280 } 11281 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11282 } 11283 if (dumpPackage == null) { 11284 pw.println(" mConfiguration: " + mConfiguration); 11285 } 11286 if (dumpAll) { 11287 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11288 if (mCompatModePackages.getPackages().size() > 0) { 11289 boolean printed = false; 11290 for (Map.Entry<String, Integer> entry 11291 : mCompatModePackages.getPackages().entrySet()) { 11292 String pkg = entry.getKey(); 11293 int mode = entry.getValue(); 11294 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11295 continue; 11296 } 11297 if (!printed) { 11298 pw.println(" mScreenCompatPackages:"); 11299 printed = true; 11300 } 11301 pw.print(" "); pw.print(pkg); pw.print(": "); 11302 pw.print(mode); pw.println(); 11303 } 11304 } 11305 } 11306 if (dumpPackage == null) { 11307 if (mSleeping || mWentToSleep || mLockScreenShown) { 11308 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11309 + " mLockScreenShown " + mLockScreenShown); 11310 } 11311 if (mShuttingDown || mRunningVoice) { 11312 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11313 } 11314 } 11315 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11316 || mOrigWaitForDebugger) { 11317 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11318 || dumpPackage.equals(mOrigDebugApp)) { 11319 if (needSep) { 11320 pw.println(); 11321 needSep = false; 11322 } 11323 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11324 + " mDebugTransient=" + mDebugTransient 11325 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11326 } 11327 } 11328 if (mOpenGlTraceApp != null) { 11329 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11330 if (needSep) { 11331 pw.println(); 11332 needSep = false; 11333 } 11334 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11335 } 11336 } 11337 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11338 || mProfileFd != null) { 11339 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11340 if (needSep) { 11341 pw.println(); 11342 needSep = false; 11343 } 11344 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11345 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11346 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11347 + mAutoStopProfiler); 11348 } 11349 } 11350 if (dumpPackage == null) { 11351 if (mAlwaysFinishActivities || mController != null) { 11352 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11353 + " mController=" + mController); 11354 } 11355 if (dumpAll) { 11356 pw.println(" Total persistent processes: " + numPers); 11357 pw.println(" mProcessesReady=" + mProcessesReady 11358 + " mSystemReady=" + mSystemReady); 11359 pw.println(" mBooting=" + mBooting 11360 + " mBooted=" + mBooted 11361 + " mFactoryTest=" + mFactoryTest); 11362 pw.print(" mLastPowerCheckRealtime="); 11363 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11364 pw.println(""); 11365 pw.print(" mLastPowerCheckUptime="); 11366 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11367 pw.println(""); 11368 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11369 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11370 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11371 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11372 + " (" + mLruProcesses.size() + " total)" 11373 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11374 + " mNumServiceProcs=" + mNumServiceProcs 11375 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11376 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11377 + " mLastMemoryLevel" + mLastMemoryLevel 11378 + " mLastNumProcesses" + mLastNumProcesses); 11379 long now = SystemClock.uptimeMillis(); 11380 pw.print(" mLastIdleTime="); 11381 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11382 pw.print(" mLowRamSinceLastIdle="); 11383 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11384 pw.println(); 11385 } 11386 } 11387 11388 if (!printedAnything) { 11389 pw.println(" (nothing)"); 11390 } 11391 } 11392 11393 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11394 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11395 if (mProcessesToGc.size() > 0) { 11396 boolean printed = false; 11397 long now = SystemClock.uptimeMillis(); 11398 for (int i=0; i<mProcessesToGc.size(); i++) { 11399 ProcessRecord proc = mProcessesToGc.get(i); 11400 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11401 continue; 11402 } 11403 if (!printed) { 11404 if (needSep) pw.println(); 11405 needSep = true; 11406 pw.println(" Processes that are waiting to GC:"); 11407 printed = true; 11408 } 11409 pw.print(" Process "); pw.println(proc); 11410 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11411 pw.print(", last gced="); 11412 pw.print(now-proc.lastRequestedGc); 11413 pw.print(" ms ago, last lowMem="); 11414 pw.print(now-proc.lastLowMemory); 11415 pw.println(" ms ago"); 11416 11417 } 11418 } 11419 return needSep; 11420 } 11421 11422 void printOomLevel(PrintWriter pw, String name, int adj) { 11423 pw.print(" "); 11424 if (adj >= 0) { 11425 pw.print(' '); 11426 if (adj < 10) pw.print(' '); 11427 } else { 11428 if (adj > -10) pw.print(' '); 11429 } 11430 pw.print(adj); 11431 pw.print(": "); 11432 pw.print(name); 11433 pw.print(" ("); 11434 pw.print(mProcessList.getMemLevel(adj)/1024); 11435 pw.println(" kB)"); 11436 } 11437 11438 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11439 int opti, boolean dumpAll) { 11440 boolean needSep = false; 11441 11442 if (mLruProcesses.size() > 0) { 11443 if (needSep) pw.println(); 11444 needSep = true; 11445 pw.println(" OOM levels:"); 11446 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11447 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11448 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11449 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11450 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11451 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11452 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11453 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11454 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11455 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11456 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11457 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11458 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11459 11460 if (needSep) pw.println(); 11461 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11462 pw.print(" total, non-act at "); 11463 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11464 pw.print(", non-svc at "); 11465 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11466 pw.println("):"); 11467 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11468 needSep = true; 11469 } 11470 11471 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11472 11473 pw.println(); 11474 pw.println(" mHomeProcess: " + mHomeProcess); 11475 pw.println(" mPreviousProcess: " + mPreviousProcess); 11476 if (mHeavyWeightProcess != null) { 11477 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11478 } 11479 11480 return true; 11481 } 11482 11483 /** 11484 * There are three ways to call this: 11485 * - no provider specified: dump all the providers 11486 * - a flattened component name that matched an existing provider was specified as the 11487 * first arg: dump that one provider 11488 * - the first arg isn't the flattened component name of an existing provider: 11489 * dump all providers whose component contains the first arg as a substring 11490 */ 11491 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11492 int opti, boolean dumpAll) { 11493 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11494 } 11495 11496 static class ItemMatcher { 11497 ArrayList<ComponentName> components; 11498 ArrayList<String> strings; 11499 ArrayList<Integer> objects; 11500 boolean all; 11501 11502 ItemMatcher() { 11503 all = true; 11504 } 11505 11506 void build(String name) { 11507 ComponentName componentName = ComponentName.unflattenFromString(name); 11508 if (componentName != null) { 11509 if (components == null) { 11510 components = new ArrayList<ComponentName>(); 11511 } 11512 components.add(componentName); 11513 all = false; 11514 } else { 11515 int objectId = 0; 11516 // Not a '/' separated full component name; maybe an object ID? 11517 try { 11518 objectId = Integer.parseInt(name, 16); 11519 if (objects == null) { 11520 objects = new ArrayList<Integer>(); 11521 } 11522 objects.add(objectId); 11523 all = false; 11524 } catch (RuntimeException e) { 11525 // Not an integer; just do string match. 11526 if (strings == null) { 11527 strings = new ArrayList<String>(); 11528 } 11529 strings.add(name); 11530 all = false; 11531 } 11532 } 11533 } 11534 11535 int build(String[] args, int opti) { 11536 for (; opti<args.length; opti++) { 11537 String name = args[opti]; 11538 if ("--".equals(name)) { 11539 return opti+1; 11540 } 11541 build(name); 11542 } 11543 return opti; 11544 } 11545 11546 boolean match(Object object, ComponentName comp) { 11547 if (all) { 11548 return true; 11549 } 11550 if (components != null) { 11551 for (int i=0; i<components.size(); i++) { 11552 if (components.get(i).equals(comp)) { 11553 return true; 11554 } 11555 } 11556 } 11557 if (objects != null) { 11558 for (int i=0; i<objects.size(); i++) { 11559 if (System.identityHashCode(object) == objects.get(i)) { 11560 return true; 11561 } 11562 } 11563 } 11564 if (strings != null) { 11565 String flat = comp.flattenToString(); 11566 for (int i=0; i<strings.size(); i++) { 11567 if (flat.contains(strings.get(i))) { 11568 return true; 11569 } 11570 } 11571 } 11572 return false; 11573 } 11574 } 11575 11576 /** 11577 * There are three things that cmd can be: 11578 * - a flattened component name that matches an existing activity 11579 * - the cmd arg isn't the flattened component name of an existing activity: 11580 * dump all activity whose component contains the cmd as a substring 11581 * - A hex number of the ActivityRecord object instance. 11582 */ 11583 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11584 int opti, boolean dumpAll) { 11585 ArrayList<ActivityRecord> activities; 11586 11587 synchronized (this) { 11588 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11589 } 11590 11591 if (activities.size() <= 0) { 11592 return false; 11593 } 11594 11595 String[] newArgs = new String[args.length - opti]; 11596 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11597 11598 TaskRecord lastTask = null; 11599 boolean needSep = false; 11600 for (int i=activities.size()-1; i>=0; i--) { 11601 ActivityRecord r = activities.get(i); 11602 if (needSep) { 11603 pw.println(); 11604 } 11605 needSep = true; 11606 synchronized (this) { 11607 if (lastTask != r.task) { 11608 lastTask = r.task; 11609 pw.print("TASK "); pw.print(lastTask.affinity); 11610 pw.print(" id="); pw.println(lastTask.taskId); 11611 if (dumpAll) { 11612 lastTask.dump(pw, " "); 11613 } 11614 } 11615 } 11616 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11617 } 11618 return true; 11619 } 11620 11621 /** 11622 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11623 * there is a thread associated with the activity. 11624 */ 11625 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11626 final ActivityRecord r, String[] args, boolean dumpAll) { 11627 String innerPrefix = prefix + " "; 11628 synchronized (this) { 11629 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11630 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11631 pw.print(" pid="); 11632 if (r.app != null) pw.println(r.app.pid); 11633 else pw.println("(not running)"); 11634 if (dumpAll) { 11635 r.dump(pw, innerPrefix); 11636 } 11637 } 11638 if (r.app != null && r.app.thread != null) { 11639 // flush anything that is already in the PrintWriter since the thread is going 11640 // to write to the file descriptor directly 11641 pw.flush(); 11642 try { 11643 TransferPipe tp = new TransferPipe(); 11644 try { 11645 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11646 r.appToken, innerPrefix, args); 11647 tp.go(fd); 11648 } finally { 11649 tp.kill(); 11650 } 11651 } catch (IOException e) { 11652 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11653 } catch (RemoteException e) { 11654 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11655 } 11656 } 11657 } 11658 11659 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11660 int opti, boolean dumpAll, String dumpPackage) { 11661 boolean needSep = false; 11662 boolean onlyHistory = false; 11663 boolean printedAnything = false; 11664 11665 if ("history".equals(dumpPackage)) { 11666 if (opti < args.length && "-s".equals(args[opti])) { 11667 dumpAll = false; 11668 } 11669 onlyHistory = true; 11670 dumpPackage = null; 11671 } 11672 11673 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11674 if (!onlyHistory && dumpAll) { 11675 if (mRegisteredReceivers.size() > 0) { 11676 boolean printed = false; 11677 Iterator it = mRegisteredReceivers.values().iterator(); 11678 while (it.hasNext()) { 11679 ReceiverList r = (ReceiverList)it.next(); 11680 if (dumpPackage != null && (r.app == null || 11681 !dumpPackage.equals(r.app.info.packageName))) { 11682 continue; 11683 } 11684 if (!printed) { 11685 pw.println(" Registered Receivers:"); 11686 needSep = true; 11687 printed = true; 11688 printedAnything = true; 11689 } 11690 pw.print(" * "); pw.println(r); 11691 r.dump(pw, " "); 11692 } 11693 } 11694 11695 if (mReceiverResolver.dump(pw, needSep ? 11696 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11697 " ", dumpPackage, false)) { 11698 needSep = true; 11699 printedAnything = true; 11700 } 11701 } 11702 11703 for (BroadcastQueue q : mBroadcastQueues) { 11704 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11705 printedAnything |= needSep; 11706 } 11707 11708 needSep = true; 11709 11710 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11711 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11712 if (needSep) { 11713 pw.println(); 11714 } 11715 needSep = true; 11716 printedAnything = true; 11717 pw.print(" Sticky broadcasts for user "); 11718 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11719 StringBuilder sb = new StringBuilder(128); 11720 for (Map.Entry<String, ArrayList<Intent>> ent 11721 : mStickyBroadcasts.valueAt(user).entrySet()) { 11722 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11723 if (dumpAll) { 11724 pw.println(":"); 11725 ArrayList<Intent> intents = ent.getValue(); 11726 final int N = intents.size(); 11727 for (int i=0; i<N; i++) { 11728 sb.setLength(0); 11729 sb.append(" Intent: "); 11730 intents.get(i).toShortString(sb, false, true, false, false); 11731 pw.println(sb.toString()); 11732 Bundle bundle = intents.get(i).getExtras(); 11733 if (bundle != null) { 11734 pw.print(" "); 11735 pw.println(bundle.toString()); 11736 } 11737 } 11738 } else { 11739 pw.println(""); 11740 } 11741 } 11742 } 11743 } 11744 11745 if (!onlyHistory && dumpAll) { 11746 pw.println(); 11747 for (BroadcastQueue queue : mBroadcastQueues) { 11748 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11749 + queue.mBroadcastsScheduled); 11750 } 11751 pw.println(" mHandler:"); 11752 mHandler.dump(new PrintWriterPrinter(pw), " "); 11753 needSep = true; 11754 printedAnything = true; 11755 } 11756 11757 if (!printedAnything) { 11758 pw.println(" (nothing)"); 11759 } 11760 } 11761 11762 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11763 int opti, boolean dumpAll, String dumpPackage) { 11764 boolean needSep; 11765 boolean printedAnything = false; 11766 11767 ItemMatcher matcher = new ItemMatcher(); 11768 matcher.build(args, opti); 11769 11770 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11771 11772 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11773 printedAnything |= needSep; 11774 11775 if (mLaunchingProviders.size() > 0) { 11776 boolean printed = false; 11777 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11778 ContentProviderRecord r = mLaunchingProviders.get(i); 11779 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11780 continue; 11781 } 11782 if (!printed) { 11783 if (needSep) pw.println(); 11784 needSep = true; 11785 pw.println(" Launching content providers:"); 11786 printed = true; 11787 printedAnything = true; 11788 } 11789 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11790 pw.println(r); 11791 } 11792 } 11793 11794 if (mGrantedUriPermissions.size() > 0) { 11795 boolean printed = false; 11796 int dumpUid = -2; 11797 if (dumpPackage != null) { 11798 try { 11799 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11800 } catch (NameNotFoundException e) { 11801 dumpUid = -1; 11802 } 11803 } 11804 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11805 int uid = mGrantedUriPermissions.keyAt(i); 11806 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11807 continue; 11808 } 11809 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11810 if (!printed) { 11811 if (needSep) pw.println(); 11812 needSep = true; 11813 pw.println(" Granted Uri Permissions:"); 11814 printed = true; 11815 printedAnything = true; 11816 } 11817 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11818 for (UriPermission perm : perms.values()) { 11819 pw.print(" "); pw.println(perm); 11820 if (dumpAll) { 11821 perm.dump(pw, " "); 11822 } 11823 } 11824 } 11825 } 11826 11827 if (!printedAnything) { 11828 pw.println(" (nothing)"); 11829 } 11830 } 11831 11832 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11833 int opti, boolean dumpAll, String dumpPackage) { 11834 boolean printed = false; 11835 11836 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11837 11838 if (mIntentSenderRecords.size() > 0) { 11839 Iterator<WeakReference<PendingIntentRecord>> it 11840 = mIntentSenderRecords.values().iterator(); 11841 while (it.hasNext()) { 11842 WeakReference<PendingIntentRecord> ref = it.next(); 11843 PendingIntentRecord rec = ref != null ? ref.get(): null; 11844 if (dumpPackage != null && (rec == null 11845 || !dumpPackage.equals(rec.key.packageName))) { 11846 continue; 11847 } 11848 printed = true; 11849 if (rec != null) { 11850 pw.print(" * "); pw.println(rec); 11851 if (dumpAll) { 11852 rec.dump(pw, " "); 11853 } 11854 } else { 11855 pw.print(" * "); pw.println(ref); 11856 } 11857 } 11858 } 11859 11860 if (!printed) { 11861 pw.println(" (nothing)"); 11862 } 11863 } 11864 11865 private static final int dumpProcessList(PrintWriter pw, 11866 ActivityManagerService service, List list, 11867 String prefix, String normalLabel, String persistentLabel, 11868 String dumpPackage) { 11869 int numPers = 0; 11870 final int N = list.size()-1; 11871 for (int i=N; i>=0; i--) { 11872 ProcessRecord r = (ProcessRecord)list.get(i); 11873 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11874 continue; 11875 } 11876 pw.println(String.format("%s%s #%2d: %s", 11877 prefix, (r.persistent ? persistentLabel : normalLabel), 11878 i, r.toString())); 11879 if (r.persistent) { 11880 numPers++; 11881 } 11882 } 11883 return numPers; 11884 } 11885 11886 private static final boolean dumpProcessOomList(PrintWriter pw, 11887 ActivityManagerService service, List<ProcessRecord> origList, 11888 String prefix, String normalLabel, String persistentLabel, 11889 boolean inclDetails, String dumpPackage) { 11890 11891 ArrayList<Pair<ProcessRecord, Integer>> list 11892 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11893 for (int i=0; i<origList.size(); i++) { 11894 ProcessRecord r = origList.get(i); 11895 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11896 continue; 11897 } 11898 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11899 } 11900 11901 if (list.size() <= 0) { 11902 return false; 11903 } 11904 11905 Comparator<Pair<ProcessRecord, Integer>> comparator 11906 = new Comparator<Pair<ProcessRecord, Integer>>() { 11907 @Override 11908 public int compare(Pair<ProcessRecord, Integer> object1, 11909 Pair<ProcessRecord, Integer> object2) { 11910 if (object1.first.setAdj != object2.first.setAdj) { 11911 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11912 } 11913 if (object1.second.intValue() != object2.second.intValue()) { 11914 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11915 } 11916 return 0; 11917 } 11918 }; 11919 11920 Collections.sort(list, comparator); 11921 11922 final long curRealtime = SystemClock.elapsedRealtime(); 11923 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11924 final long curUptime = SystemClock.uptimeMillis(); 11925 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11926 11927 for (int i=list.size()-1; i>=0; i--) { 11928 ProcessRecord r = list.get(i).first; 11929 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11930 char schedGroup; 11931 switch (r.setSchedGroup) { 11932 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11933 schedGroup = 'B'; 11934 break; 11935 case Process.THREAD_GROUP_DEFAULT: 11936 schedGroup = 'F'; 11937 break; 11938 default: 11939 schedGroup = '?'; 11940 break; 11941 } 11942 char foreground; 11943 if (r.foregroundActivities) { 11944 foreground = 'A'; 11945 } else if (r.foregroundServices) { 11946 foreground = 'S'; 11947 } else { 11948 foreground = ' '; 11949 } 11950 String procState = ProcessList.makeProcStateString(r.curProcState); 11951 pw.print(prefix); 11952 pw.print(r.persistent ? persistentLabel : normalLabel); 11953 pw.print(" #"); 11954 int num = (origList.size()-1)-list.get(i).second; 11955 if (num < 10) pw.print(' '); 11956 pw.print(num); 11957 pw.print(": "); 11958 pw.print(oomAdj); 11959 pw.print(' '); 11960 pw.print(schedGroup); 11961 pw.print('/'); 11962 pw.print(foreground); 11963 pw.print('/'); 11964 pw.print(procState); 11965 pw.print(" trm:"); 11966 if (r.trimMemoryLevel < 10) pw.print(' '); 11967 pw.print(r.trimMemoryLevel); 11968 pw.print(' '); 11969 pw.print(r.toShortString()); 11970 pw.print(" ("); 11971 pw.print(r.adjType); 11972 pw.println(')'); 11973 if (r.adjSource != null || r.adjTarget != null) { 11974 pw.print(prefix); 11975 pw.print(" "); 11976 if (r.adjTarget instanceof ComponentName) { 11977 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11978 } else if (r.adjTarget != null) { 11979 pw.print(r.adjTarget.toString()); 11980 } else { 11981 pw.print("{null}"); 11982 } 11983 pw.print("<="); 11984 if (r.adjSource instanceof ProcessRecord) { 11985 pw.print("Proc{"); 11986 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11987 pw.println("}"); 11988 } else if (r.adjSource != null) { 11989 pw.println(r.adjSource.toString()); 11990 } else { 11991 pw.println("{null}"); 11992 } 11993 } 11994 if (inclDetails) { 11995 pw.print(prefix); 11996 pw.print(" "); 11997 pw.print("oom: max="); pw.print(r.maxAdj); 11998 pw.print(" curRaw="); pw.print(r.curRawAdj); 11999 pw.print(" setRaw="); pw.print(r.setRawAdj); 12000 pw.print(" cur="); pw.print(r.curAdj); 12001 pw.print(" set="); pw.println(r.setAdj); 12002 pw.print(prefix); 12003 pw.print(" "); 12004 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 12005 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 12006 pw.print(" lastPss="); pw.print(r.lastPss); 12007 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12008 pw.print(prefix); 12009 pw.print(" "); 12010 pw.print("keeping="); pw.print(r.keeping); 12011 pw.print(" cached="); pw.print(r.cached); 12012 pw.print(" empty="); pw.print(r.empty); 12013 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12014 12015 if (!r.keeping) { 12016 if (r.lastWakeTime != 0) { 12017 long wtime; 12018 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12019 synchronized (stats) { 12020 wtime = stats.getProcessWakeTime(r.info.uid, 12021 r.pid, curRealtime); 12022 } 12023 long timeUsed = wtime - r.lastWakeTime; 12024 pw.print(prefix); 12025 pw.print(" "); 12026 pw.print("keep awake over "); 12027 TimeUtils.formatDuration(realtimeSince, pw); 12028 pw.print(" used "); 12029 TimeUtils.formatDuration(timeUsed, pw); 12030 pw.print(" ("); 12031 pw.print((timeUsed*100)/realtimeSince); 12032 pw.println("%)"); 12033 } 12034 if (r.lastCpuTime != 0) { 12035 long timeUsed = r.curCpuTime - r.lastCpuTime; 12036 pw.print(prefix); 12037 pw.print(" "); 12038 pw.print("run cpu over "); 12039 TimeUtils.formatDuration(uptimeSince, pw); 12040 pw.print(" used "); 12041 TimeUtils.formatDuration(timeUsed, pw); 12042 pw.print(" ("); 12043 pw.print((timeUsed*100)/uptimeSince); 12044 pw.println("%)"); 12045 } 12046 } 12047 } 12048 } 12049 return true; 12050 } 12051 12052 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12053 ArrayList<ProcessRecord> procs; 12054 synchronized (this) { 12055 if (args != null && args.length > start 12056 && args[start].charAt(0) != '-') { 12057 procs = new ArrayList<ProcessRecord>(); 12058 int pid = -1; 12059 try { 12060 pid = Integer.parseInt(args[start]); 12061 } catch (NumberFormatException e) { 12062 } 12063 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12064 ProcessRecord proc = mLruProcesses.get(i); 12065 if (proc.pid == pid) { 12066 procs.add(proc); 12067 } else if (proc.processName.equals(args[start])) { 12068 procs.add(proc); 12069 } 12070 } 12071 if (procs.size() <= 0) { 12072 return null; 12073 } 12074 } else { 12075 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12076 } 12077 } 12078 return procs; 12079 } 12080 12081 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12082 PrintWriter pw, String[] args) { 12083 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12084 if (procs == null) { 12085 pw.println("No process found for: " + args[0]); 12086 return; 12087 } 12088 12089 long uptime = SystemClock.uptimeMillis(); 12090 long realtime = SystemClock.elapsedRealtime(); 12091 pw.println("Applications Graphics Acceleration Info:"); 12092 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12093 12094 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12095 ProcessRecord r = procs.get(i); 12096 if (r.thread != null) { 12097 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12098 pw.flush(); 12099 try { 12100 TransferPipe tp = new TransferPipe(); 12101 try { 12102 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12103 tp.go(fd); 12104 } finally { 12105 tp.kill(); 12106 } 12107 } catch (IOException e) { 12108 pw.println("Failure while dumping the app: " + r); 12109 pw.flush(); 12110 } catch (RemoteException e) { 12111 pw.println("Got a RemoteException while dumping the app " + r); 12112 pw.flush(); 12113 } 12114 } 12115 } 12116 } 12117 12118 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12119 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12120 if (procs == null) { 12121 pw.println("No process found for: " + args[0]); 12122 return; 12123 } 12124 12125 pw.println("Applications Database Info:"); 12126 12127 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12128 ProcessRecord r = procs.get(i); 12129 if (r.thread != null) { 12130 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12131 pw.flush(); 12132 try { 12133 TransferPipe tp = new TransferPipe(); 12134 try { 12135 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12136 tp.go(fd); 12137 } finally { 12138 tp.kill(); 12139 } 12140 } catch (IOException e) { 12141 pw.println("Failure while dumping the app: " + r); 12142 pw.flush(); 12143 } catch (RemoteException e) { 12144 pw.println("Got a RemoteException while dumping the app " + r); 12145 pw.flush(); 12146 } 12147 } 12148 } 12149 } 12150 12151 final static class MemItem { 12152 final boolean isProc; 12153 final String label; 12154 final String shortLabel; 12155 final long pss; 12156 final int id; 12157 final boolean hasActivities; 12158 ArrayList<MemItem> subitems; 12159 12160 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12161 boolean _hasActivities) { 12162 isProc = true; 12163 label = _label; 12164 shortLabel = _shortLabel; 12165 pss = _pss; 12166 id = _id; 12167 hasActivities = _hasActivities; 12168 } 12169 12170 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12171 isProc = false; 12172 label = _label; 12173 shortLabel = _shortLabel; 12174 pss = _pss; 12175 id = _id; 12176 hasActivities = false; 12177 } 12178 } 12179 12180 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12181 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12182 if (sort && !isCompact) { 12183 Collections.sort(items, new Comparator<MemItem>() { 12184 @Override 12185 public int compare(MemItem lhs, MemItem rhs) { 12186 if (lhs.pss < rhs.pss) { 12187 return 1; 12188 } else if (lhs.pss > rhs.pss) { 12189 return -1; 12190 } 12191 return 0; 12192 } 12193 }); 12194 } 12195 12196 for (int i=0; i<items.size(); i++) { 12197 MemItem mi = items.get(i); 12198 if (!isCompact) { 12199 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12200 } else if (mi.isProc) { 12201 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12202 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12203 pw.println(mi.hasActivities ? ",a" : ",e"); 12204 } else { 12205 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12206 pw.println(mi.pss); 12207 } 12208 if (mi.subitems != null) { 12209 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12210 true, isCompact); 12211 } 12212 } 12213 } 12214 12215 // These are in KB. 12216 static final long[] DUMP_MEM_BUCKETS = new long[] { 12217 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12218 120*1024, 160*1024, 200*1024, 12219 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12220 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12221 }; 12222 12223 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12224 boolean stackLike) { 12225 int start = label.lastIndexOf('.'); 12226 if (start >= 0) start++; 12227 else start = 0; 12228 int end = label.length(); 12229 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12230 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12231 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12232 out.append(bucket); 12233 out.append(stackLike ? "MB." : "MB "); 12234 out.append(label, start, end); 12235 return; 12236 } 12237 } 12238 out.append(memKB/1024); 12239 out.append(stackLike ? "MB." : "MB "); 12240 out.append(label, start, end); 12241 } 12242 12243 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12244 ProcessList.NATIVE_ADJ, 12245 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12246 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12247 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12248 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12249 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12250 }; 12251 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12252 "Native", 12253 "System", "Persistent", "Foreground", 12254 "Visible", "Perceptible", 12255 "Heavy Weight", "Backup", 12256 "A Services", "Home", 12257 "Previous", "B Services", "Cached" 12258 }; 12259 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12260 "native", 12261 "sys", "pers", "fore", 12262 "vis", "percept", 12263 "heavy", "backup", 12264 "servicea", "home", 12265 "prev", "serviceb", "cached" 12266 }; 12267 12268 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12269 long realtime, boolean isCheckinRequest, boolean isCompact) { 12270 if (isCheckinRequest || isCompact) { 12271 // short checkin version 12272 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12273 } else { 12274 pw.println("Applications Memory Usage (kB):"); 12275 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12276 } 12277 } 12278 12279 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12280 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12281 boolean dumpDetails = false; 12282 boolean dumpFullDetails = false; 12283 boolean dumpDalvik = false; 12284 boolean oomOnly = false; 12285 boolean isCompact = false; 12286 boolean localOnly = false; 12287 12288 int opti = 0; 12289 while (opti < args.length) { 12290 String opt = args[opti]; 12291 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12292 break; 12293 } 12294 opti++; 12295 if ("-a".equals(opt)) { 12296 dumpDetails = true; 12297 dumpFullDetails = true; 12298 dumpDalvik = true; 12299 } else if ("-d".equals(opt)) { 12300 dumpDalvik = true; 12301 } else if ("-c".equals(opt)) { 12302 isCompact = true; 12303 } else if ("--oom".equals(opt)) { 12304 oomOnly = true; 12305 } else if ("--local".equals(opt)) { 12306 localOnly = true; 12307 } else if ("-h".equals(opt)) { 12308 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12309 pw.println(" -a: include all available information for each process."); 12310 pw.println(" -d: include dalvik details when dumping process details."); 12311 pw.println(" -c: dump in a compact machine-parseable representation."); 12312 pw.println(" --oom: only show processes organized by oom adj."); 12313 pw.println(" --local: only collect details locally, don't call process."); 12314 pw.println("If [process] is specified it can be the name or "); 12315 pw.println("pid of a specific process to dump."); 12316 return; 12317 } else { 12318 pw.println("Unknown argument: " + opt + "; use -h for help"); 12319 } 12320 } 12321 12322 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12323 long uptime = SystemClock.uptimeMillis(); 12324 long realtime = SystemClock.elapsedRealtime(); 12325 final long[] tmpLong = new long[1]; 12326 12327 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12328 if (procs == null) { 12329 // No Java processes. Maybe they want to print a native process. 12330 if (args != null && args.length > opti 12331 && args[opti].charAt(0) != '-') { 12332 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12333 = new ArrayList<ProcessCpuTracker.Stats>(); 12334 updateCpuStatsNow(); 12335 int findPid = -1; 12336 try { 12337 findPid = Integer.parseInt(args[opti]); 12338 } catch (NumberFormatException e) { 12339 } 12340 synchronized (mProcessCpuThread) { 12341 final int N = mProcessCpuTracker.countStats(); 12342 for (int i=0; i<N; i++) { 12343 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12344 if (st.pid == findPid || (st.baseName != null 12345 && st.baseName.equals(args[opti]))) { 12346 nativeProcs.add(st); 12347 } 12348 } 12349 } 12350 if (nativeProcs.size() > 0) { 12351 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12352 isCompact); 12353 Debug.MemoryInfo mi = null; 12354 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12355 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12356 final int pid = r.pid; 12357 if (!isCheckinRequest && dumpDetails) { 12358 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12359 } 12360 if (mi == null) { 12361 mi = new Debug.MemoryInfo(); 12362 } 12363 if (dumpDetails || (!brief && !oomOnly)) { 12364 Debug.getMemoryInfo(pid, mi); 12365 } else { 12366 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12367 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12368 } 12369 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12370 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12371 if (isCheckinRequest) { 12372 pw.println(); 12373 } 12374 } 12375 return; 12376 } 12377 } 12378 pw.println("No process found for: " + args[opti]); 12379 return; 12380 } 12381 12382 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12383 dumpDetails = true; 12384 } 12385 12386 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12387 12388 String[] innerArgs = new String[args.length-opti]; 12389 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12390 12391 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12392 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12393 long nativePss=0, dalvikPss=0, otherPss=0; 12394 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12395 12396 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12397 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12398 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12399 12400 long totalPss = 0; 12401 long cachedPss = 0; 12402 12403 Debug.MemoryInfo mi = null; 12404 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12405 final ProcessRecord r = procs.get(i); 12406 final IApplicationThread thread; 12407 final int pid; 12408 final int oomAdj; 12409 final boolean hasActivities; 12410 synchronized (this) { 12411 thread = r.thread; 12412 pid = r.pid; 12413 oomAdj = r.getSetAdjWithServices(); 12414 hasActivities = r.activities.size() > 0; 12415 } 12416 if (thread != null) { 12417 if (!isCheckinRequest && dumpDetails) { 12418 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12419 } 12420 if (mi == null) { 12421 mi = new Debug.MemoryInfo(); 12422 } 12423 if (dumpDetails || (!brief && !oomOnly)) { 12424 Debug.getMemoryInfo(pid, mi); 12425 } else { 12426 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12427 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12428 } 12429 if (dumpDetails) { 12430 if (localOnly) { 12431 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12432 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12433 if (isCheckinRequest) { 12434 pw.println(); 12435 } 12436 } else { 12437 try { 12438 pw.flush(); 12439 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12440 dumpDalvik, innerArgs); 12441 } catch (RemoteException e) { 12442 if (!isCheckinRequest) { 12443 pw.println("Got RemoteException!"); 12444 pw.flush(); 12445 } 12446 } 12447 } 12448 } 12449 12450 final long myTotalPss = mi.getTotalPss(); 12451 final long myTotalUss = mi.getTotalUss(); 12452 12453 synchronized (this) { 12454 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12455 // Record this for posterity if the process has been stable. 12456 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12457 } 12458 } 12459 12460 if (!isCheckinRequest && mi != null) { 12461 totalPss += myTotalPss; 12462 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12463 (hasActivities ? " / activities)" : ")"), 12464 r.processName, myTotalPss, pid, hasActivities); 12465 procMems.add(pssItem); 12466 procMemsMap.put(pid, pssItem); 12467 12468 nativePss += mi.nativePss; 12469 dalvikPss += mi.dalvikPss; 12470 otherPss += mi.otherPss; 12471 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12472 long mem = mi.getOtherPss(j); 12473 miscPss[j] += mem; 12474 otherPss -= mem; 12475 } 12476 12477 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12478 cachedPss += myTotalPss; 12479 } 12480 12481 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12482 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12483 || oomIndex == (oomPss.length-1)) { 12484 oomPss[oomIndex] += myTotalPss; 12485 if (oomProcs[oomIndex] == null) { 12486 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12487 } 12488 oomProcs[oomIndex].add(pssItem); 12489 break; 12490 } 12491 } 12492 } 12493 } 12494 } 12495 12496 if (!isCheckinRequest && procs.size() > 1) { 12497 // If we are showing aggregations, also look for native processes to 12498 // include so that our aggregations are more accurate. 12499 updateCpuStatsNow(); 12500 synchronized (mProcessCpuThread) { 12501 final int N = mProcessCpuTracker.countStats(); 12502 for (int i=0; i<N; i++) { 12503 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12504 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12505 if (mi == null) { 12506 mi = new Debug.MemoryInfo(); 12507 } 12508 if (!brief && !oomOnly) { 12509 Debug.getMemoryInfo(st.pid, mi); 12510 } else { 12511 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12512 mi.nativePrivateDirty = (int)tmpLong[0]; 12513 } 12514 12515 final long myTotalPss = mi.getTotalPss(); 12516 totalPss += myTotalPss; 12517 12518 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12519 st.name, myTotalPss, st.pid, false); 12520 procMems.add(pssItem); 12521 12522 nativePss += mi.nativePss; 12523 dalvikPss += mi.dalvikPss; 12524 otherPss += mi.otherPss; 12525 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12526 long mem = mi.getOtherPss(j); 12527 miscPss[j] += mem; 12528 otherPss -= mem; 12529 } 12530 oomPss[0] += myTotalPss; 12531 if (oomProcs[0] == null) { 12532 oomProcs[0] = new ArrayList<MemItem>(); 12533 } 12534 oomProcs[0].add(pssItem); 12535 } 12536 } 12537 } 12538 12539 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12540 12541 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12542 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12543 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12544 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12545 String label = Debug.MemoryInfo.getOtherLabel(j); 12546 catMems.add(new MemItem(label, label, miscPss[j], j)); 12547 } 12548 12549 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12550 for (int j=0; j<oomPss.length; j++) { 12551 if (oomPss[j] != 0) { 12552 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12553 : DUMP_MEM_OOM_LABEL[j]; 12554 MemItem item = new MemItem(label, label, oomPss[j], 12555 DUMP_MEM_OOM_ADJ[j]); 12556 item.subitems = oomProcs[j]; 12557 oomMems.add(item); 12558 } 12559 } 12560 12561 if (!brief && !oomOnly && !isCompact) { 12562 pw.println(); 12563 pw.println("Total PSS by process:"); 12564 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12565 pw.println(); 12566 } 12567 if (!isCompact) { 12568 pw.println("Total PSS by OOM adjustment:"); 12569 } 12570 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12571 if (!brief && !oomOnly) { 12572 PrintWriter out = categoryPw != null ? categoryPw : pw; 12573 if (!isCompact) { 12574 out.println(); 12575 out.println("Total PSS by category:"); 12576 } 12577 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12578 } 12579 if (!isCompact) { 12580 pw.println(); 12581 } 12582 MemInfoReader memInfo = new MemInfoReader(); 12583 memInfo.readMemInfo(); 12584 if (!brief) { 12585 if (!isCompact) { 12586 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12587 pw.print(" kB (status "); 12588 switch (mLastMemoryLevel) { 12589 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12590 pw.println("normal)"); 12591 break; 12592 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12593 pw.println("moderate)"); 12594 break; 12595 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12596 pw.println("low)"); 12597 break; 12598 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12599 pw.println("critical)"); 12600 break; 12601 default: 12602 pw.print(mLastMemoryLevel); 12603 pw.println(")"); 12604 break; 12605 } 12606 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12607 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12608 pw.print(cachedPss); pw.print(" cached pss + "); 12609 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12610 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12611 } else { 12612 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12613 pw.print(cachedPss + memInfo.getCachedSizeKb() 12614 + memInfo.getFreeSizeKb()); pw.print(","); 12615 pw.println(totalPss - cachedPss); 12616 } 12617 } 12618 if (!isCompact) { 12619 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12620 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12621 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12622 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12623 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12624 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12625 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12626 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12627 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12628 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12629 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12630 } 12631 if (!brief) { 12632 if (memInfo.getZramTotalSizeKb() != 0) { 12633 if (!isCompact) { 12634 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12635 pw.print(" kB physical used for "); 12636 pw.print(memInfo.getSwapTotalSizeKb() 12637 - memInfo.getSwapFreeSizeKb()); 12638 pw.print(" kB in swap ("); 12639 pw.print(memInfo.getSwapTotalSizeKb()); 12640 pw.println(" kB total swap)"); 12641 } else { 12642 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12643 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12644 pw.println(memInfo.getSwapFreeSizeKb()); 12645 } 12646 } 12647 final int[] SINGLE_LONG_FORMAT = new int[] { 12648 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12649 }; 12650 long[] longOut = new long[1]; 12651 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12652 SINGLE_LONG_FORMAT, null, longOut, null); 12653 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12654 longOut[0] = 0; 12655 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12656 SINGLE_LONG_FORMAT, null, longOut, null); 12657 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12658 longOut[0] = 0; 12659 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12660 SINGLE_LONG_FORMAT, null, longOut, null); 12661 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12662 longOut[0] = 0; 12663 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12664 SINGLE_LONG_FORMAT, null, longOut, null); 12665 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12666 if (!isCompact) { 12667 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12668 pw.print(" KSM: "); pw.print(sharing); 12669 pw.print(" kB saved from shared "); 12670 pw.print(shared); pw.println(" kB"); 12671 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12672 pw.print(voltile); pw.println(" kB volatile"); 12673 } 12674 pw.print(" Tuning: "); 12675 pw.print(ActivityManager.staticGetMemoryClass()); 12676 pw.print(" (large "); 12677 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12678 pw.print("), oom "); 12679 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12680 pw.print(" kB"); 12681 pw.print(", restore limit "); 12682 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12683 pw.print(" kB"); 12684 if (ActivityManager.isLowRamDeviceStatic()) { 12685 pw.print(" (low-ram)"); 12686 } 12687 if (ActivityManager.isHighEndGfx()) { 12688 pw.print(" (high-end-gfx)"); 12689 } 12690 pw.println(); 12691 } else { 12692 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12693 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12694 pw.println(voltile); 12695 pw.print("tuning,"); 12696 pw.print(ActivityManager.staticGetMemoryClass()); 12697 pw.print(','); 12698 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12699 pw.print(','); 12700 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12701 if (ActivityManager.isLowRamDeviceStatic()) { 12702 pw.print(",low-ram"); 12703 } 12704 if (ActivityManager.isHighEndGfx()) { 12705 pw.print(",high-end-gfx"); 12706 } 12707 pw.println(); 12708 } 12709 } 12710 } 12711 } 12712 12713 /** 12714 * Searches array of arguments for the specified string 12715 * @param args array of argument strings 12716 * @param value value to search for 12717 * @return true if the value is contained in the array 12718 */ 12719 private static boolean scanArgs(String[] args, String value) { 12720 if (args != null) { 12721 for (String arg : args) { 12722 if (value.equals(arg)) { 12723 return true; 12724 } 12725 } 12726 } 12727 return false; 12728 } 12729 12730 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12731 ContentProviderRecord cpr, boolean always) { 12732 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12733 12734 if (!inLaunching || always) { 12735 synchronized (cpr) { 12736 cpr.launchingApp = null; 12737 cpr.notifyAll(); 12738 } 12739 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12740 String names[] = cpr.info.authority.split(";"); 12741 for (int j = 0; j < names.length; j++) { 12742 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12743 } 12744 } 12745 12746 for (int i=0; i<cpr.connections.size(); i++) { 12747 ContentProviderConnection conn = cpr.connections.get(i); 12748 if (conn.waiting) { 12749 // If this connection is waiting for the provider, then we don't 12750 // need to mess with its process unless we are always removing 12751 // or for some reason the provider is not currently launching. 12752 if (inLaunching && !always) { 12753 continue; 12754 } 12755 } 12756 ProcessRecord capp = conn.client; 12757 conn.dead = true; 12758 if (conn.stableCount > 0) { 12759 if (!capp.persistent && capp.thread != null 12760 && capp.pid != 0 12761 && capp.pid != MY_PID) { 12762 killUnneededProcessLocked(capp, "depends on provider " 12763 + cpr.name.flattenToShortString() 12764 + " in dying proc " + (proc != null ? proc.processName : "??")); 12765 } 12766 } else if (capp.thread != null && conn.provider.provider != null) { 12767 try { 12768 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12769 } catch (RemoteException e) { 12770 } 12771 // In the protocol here, we don't expect the client to correctly 12772 // clean up this connection, we'll just remove it. 12773 cpr.connections.remove(i); 12774 conn.client.conProviders.remove(conn); 12775 } 12776 } 12777 12778 if (inLaunching && always) { 12779 mLaunchingProviders.remove(cpr); 12780 } 12781 return inLaunching; 12782 } 12783 12784 /** 12785 * Main code for cleaning up a process when it has gone away. This is 12786 * called both as a result of the process dying, or directly when stopping 12787 * a process when running in single process mode. 12788 */ 12789 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12790 boolean restarting, boolean allowRestart, int index) { 12791 if (index >= 0) { 12792 removeLruProcessLocked(app); 12793 ProcessList.remove(app.pid); 12794 } 12795 12796 mProcessesToGc.remove(app); 12797 mPendingPssProcesses.remove(app); 12798 12799 // Dismiss any open dialogs. 12800 if (app.crashDialog != null && !app.forceCrashReport) { 12801 app.crashDialog.dismiss(); 12802 app.crashDialog = null; 12803 } 12804 if (app.anrDialog != null) { 12805 app.anrDialog.dismiss(); 12806 app.anrDialog = null; 12807 } 12808 if (app.waitDialog != null) { 12809 app.waitDialog.dismiss(); 12810 app.waitDialog = null; 12811 } 12812 12813 app.crashing = false; 12814 app.notResponding = false; 12815 12816 app.resetPackageList(mProcessStats); 12817 app.unlinkDeathRecipient(); 12818 app.makeInactive(mProcessStats); 12819 app.forcingToForeground = null; 12820 updateProcessForegroundLocked(app, false, false); 12821 app.foregroundActivities = false; 12822 app.hasShownUi = false; 12823 app.treatLikeActivity = false; 12824 app.hasAboveClient = false; 12825 app.hasClientActivities = false; 12826 12827 mServices.killServicesLocked(app, allowRestart); 12828 12829 boolean restart = false; 12830 12831 // Remove published content providers. 12832 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12833 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12834 final boolean always = app.bad || !allowRestart; 12835 if (removeDyingProviderLocked(app, cpr, always) || always) { 12836 // We left the provider in the launching list, need to 12837 // restart it. 12838 restart = true; 12839 } 12840 12841 cpr.provider = null; 12842 cpr.proc = null; 12843 } 12844 app.pubProviders.clear(); 12845 12846 // Take care of any launching providers waiting for this process. 12847 if (checkAppInLaunchingProvidersLocked(app, false)) { 12848 restart = true; 12849 } 12850 12851 // Unregister from connected content providers. 12852 if (!app.conProviders.isEmpty()) { 12853 for (int i=0; i<app.conProviders.size(); i++) { 12854 ContentProviderConnection conn = app.conProviders.get(i); 12855 conn.provider.connections.remove(conn); 12856 } 12857 app.conProviders.clear(); 12858 } 12859 12860 // At this point there may be remaining entries in mLaunchingProviders 12861 // where we were the only one waiting, so they are no longer of use. 12862 // Look for these and clean up if found. 12863 // XXX Commented out for now. Trying to figure out a way to reproduce 12864 // the actual situation to identify what is actually going on. 12865 if (false) { 12866 for (int i=0; i<mLaunchingProviders.size(); i++) { 12867 ContentProviderRecord cpr = (ContentProviderRecord) 12868 mLaunchingProviders.get(i); 12869 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12870 synchronized (cpr) { 12871 cpr.launchingApp = null; 12872 cpr.notifyAll(); 12873 } 12874 } 12875 } 12876 } 12877 12878 skipCurrentReceiverLocked(app); 12879 12880 // Unregister any receivers. 12881 for (int i=app.receivers.size()-1; i>=0; i--) { 12882 removeReceiverLocked(app.receivers.valueAt(i)); 12883 } 12884 app.receivers.clear(); 12885 12886 // If the app is undergoing backup, tell the backup manager about it 12887 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12888 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12889 + mBackupTarget.appInfo + " died during backup"); 12890 try { 12891 IBackupManager bm = IBackupManager.Stub.asInterface( 12892 ServiceManager.getService(Context.BACKUP_SERVICE)); 12893 bm.agentDisconnected(app.info.packageName); 12894 } catch (RemoteException e) { 12895 // can't happen; backup manager is local 12896 } 12897 } 12898 12899 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12900 ProcessChangeItem item = mPendingProcessChanges.get(i); 12901 if (item.pid == app.pid) { 12902 mPendingProcessChanges.remove(i); 12903 mAvailProcessChanges.add(item); 12904 } 12905 } 12906 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12907 12908 // If the caller is restarting this app, then leave it in its 12909 // current lists and let the caller take care of it. 12910 if (restarting) { 12911 return; 12912 } 12913 12914 if (!app.persistent || app.isolated) { 12915 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12916 "Removing non-persistent process during cleanup: " + app); 12917 mProcessNames.remove(app.processName, app.uid); 12918 mIsolatedProcesses.remove(app.uid); 12919 if (mHeavyWeightProcess == app) { 12920 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12921 mHeavyWeightProcess.userId, 0)); 12922 mHeavyWeightProcess = null; 12923 } 12924 } else if (!app.removed) { 12925 // This app is persistent, so we need to keep its record around. 12926 // If it is not already on the pending app list, add it there 12927 // and start a new process for it. 12928 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12929 mPersistentStartingProcesses.add(app); 12930 restart = true; 12931 } 12932 } 12933 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12934 "Clean-up removing on hold: " + app); 12935 mProcessesOnHold.remove(app); 12936 12937 if (app == mHomeProcess) { 12938 mHomeProcess = null; 12939 } 12940 if (app == mPreviousProcess) { 12941 mPreviousProcess = null; 12942 } 12943 12944 if (restart && !app.isolated) { 12945 // We have components that still need to be running in the 12946 // process, so re-launch it. 12947 mProcessNames.put(app.processName, app.uid, app); 12948 startProcessLocked(app, "restart", app.processName); 12949 } else if (app.pid > 0 && app.pid != MY_PID) { 12950 // Goodbye! 12951 boolean removed; 12952 synchronized (mPidsSelfLocked) { 12953 mPidsSelfLocked.remove(app.pid); 12954 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12955 } 12956 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12957 app.processName, app.info.uid); 12958 if (app.isolated) { 12959 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12960 } 12961 app.setPid(0); 12962 } 12963 } 12964 12965 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12966 // Look through the content providers we are waiting to have launched, 12967 // and if any run in this process then either schedule a restart of 12968 // the process or kill the client waiting for it if this process has 12969 // gone bad. 12970 int NL = mLaunchingProviders.size(); 12971 boolean restart = false; 12972 for (int i=0; i<NL; i++) { 12973 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12974 if (cpr.launchingApp == app) { 12975 if (!alwaysBad && !app.bad) { 12976 restart = true; 12977 } else { 12978 removeDyingProviderLocked(app, cpr, true); 12979 // cpr should have been removed from mLaunchingProviders 12980 NL = mLaunchingProviders.size(); 12981 i--; 12982 } 12983 } 12984 } 12985 return restart; 12986 } 12987 12988 // ========================================================= 12989 // SERVICES 12990 // ========================================================= 12991 12992 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12993 int flags) { 12994 enforceNotIsolatedCaller("getServices"); 12995 synchronized (this) { 12996 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12997 } 12998 } 12999 13000 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 13001 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 13002 synchronized (this) { 13003 return mServices.getRunningServiceControlPanelLocked(name); 13004 } 13005 } 13006 13007 public ComponentName startService(IApplicationThread caller, Intent service, 13008 String resolvedType, int userId) { 13009 enforceNotIsolatedCaller("startService"); 13010 // Refuse possible leaked file descriptors 13011 if (service != null && service.hasFileDescriptors() == true) { 13012 throw new IllegalArgumentException("File descriptors passed in Intent"); 13013 } 13014 13015 if (DEBUG_SERVICE) 13016 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13017 synchronized(this) { 13018 final int callingPid = Binder.getCallingPid(); 13019 final int callingUid = Binder.getCallingUid(); 13020 final long origId = Binder.clearCallingIdentity(); 13021 ComponentName res = mServices.startServiceLocked(caller, service, 13022 resolvedType, callingPid, callingUid, userId); 13023 Binder.restoreCallingIdentity(origId); 13024 return res; 13025 } 13026 } 13027 13028 ComponentName startServiceInPackage(int uid, 13029 Intent service, String resolvedType, int userId) { 13030 synchronized(this) { 13031 if (DEBUG_SERVICE) 13032 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13033 final long origId = Binder.clearCallingIdentity(); 13034 ComponentName res = mServices.startServiceLocked(null, service, 13035 resolvedType, -1, uid, userId); 13036 Binder.restoreCallingIdentity(origId); 13037 return res; 13038 } 13039 } 13040 13041 public int stopService(IApplicationThread caller, Intent service, 13042 String resolvedType, int userId) { 13043 enforceNotIsolatedCaller("stopService"); 13044 // Refuse possible leaked file descriptors 13045 if (service != null && service.hasFileDescriptors() == true) { 13046 throw new IllegalArgumentException("File descriptors passed in Intent"); 13047 } 13048 13049 synchronized(this) { 13050 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13051 } 13052 } 13053 13054 public IBinder peekService(Intent service, String resolvedType) { 13055 enforceNotIsolatedCaller("peekService"); 13056 // Refuse possible leaked file descriptors 13057 if (service != null && service.hasFileDescriptors() == true) { 13058 throw new IllegalArgumentException("File descriptors passed in Intent"); 13059 } 13060 synchronized(this) { 13061 return mServices.peekServiceLocked(service, resolvedType); 13062 } 13063 } 13064 13065 public boolean stopServiceToken(ComponentName className, IBinder token, 13066 int startId) { 13067 synchronized(this) { 13068 return mServices.stopServiceTokenLocked(className, token, startId); 13069 } 13070 } 13071 13072 public void setServiceForeground(ComponentName className, IBinder token, 13073 int id, Notification notification, boolean removeNotification) { 13074 synchronized(this) { 13075 mServices.setServiceForegroundLocked(className, token, id, notification, 13076 removeNotification); 13077 } 13078 } 13079 13080 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13081 boolean requireFull, String name, String callerPackage) { 13082 final int callingUserId = UserHandle.getUserId(callingUid); 13083 if (callingUserId != userId) { 13084 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13085 if ((requireFull || checkComponentPermission( 13086 android.Manifest.permission.INTERACT_ACROSS_USERS, 13087 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 13088 && checkComponentPermission( 13089 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 13090 callingPid, callingUid, -1, true) 13091 != PackageManager.PERMISSION_GRANTED) { 13092 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13093 // In this case, they would like to just execute as their 13094 // owner user instead of failing. 13095 userId = callingUserId; 13096 } else { 13097 StringBuilder builder = new StringBuilder(128); 13098 builder.append("Permission Denial: "); 13099 builder.append(name); 13100 if (callerPackage != null) { 13101 builder.append(" from "); 13102 builder.append(callerPackage); 13103 } 13104 builder.append(" asks to run as user "); 13105 builder.append(userId); 13106 builder.append(" but is calling from user "); 13107 builder.append(UserHandle.getUserId(callingUid)); 13108 builder.append("; this requires "); 13109 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 13110 if (!requireFull) { 13111 builder.append(" or "); 13112 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13113 } 13114 String msg = builder.toString(); 13115 Slog.w(TAG, msg); 13116 throw new SecurityException(msg); 13117 } 13118 } 13119 } 13120 if (userId == UserHandle.USER_CURRENT 13121 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13122 // Note that we may be accessing this outside of a lock... 13123 // shouldn't be a big deal, if this is being called outside 13124 // of a locked context there is intrinsically a race with 13125 // the value the caller will receive and someone else changing it. 13126 userId = mCurrentUserId; 13127 } 13128 if (!allowAll && userId < 0) { 13129 throw new IllegalArgumentException( 13130 "Call does not support special user #" + userId); 13131 } 13132 } 13133 return userId; 13134 } 13135 13136 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13137 String className, int flags) { 13138 boolean result = false; 13139 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13140 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 13141 if (ActivityManager.checkUidPermission( 13142 android.Manifest.permission.INTERACT_ACROSS_USERS, 13143 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13144 ComponentName comp = new ComponentName(aInfo.packageName, className); 13145 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13146 + " requests FLAG_SINGLE_USER, but app does not hold " 13147 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13148 Slog.w(TAG, msg); 13149 throw new SecurityException(msg); 13150 } 13151 result = true; 13152 } 13153 } else if (componentProcessName == aInfo.packageName) { 13154 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13155 } else if ("system".equals(componentProcessName)) { 13156 result = true; 13157 } 13158 if (DEBUG_MU) { 13159 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13160 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13161 } 13162 return result; 13163 } 13164 13165 public int bindService(IApplicationThread caller, IBinder token, 13166 Intent service, String resolvedType, 13167 IServiceConnection connection, int flags, int userId) { 13168 enforceNotIsolatedCaller("bindService"); 13169 // Refuse possible leaked file descriptors 13170 if (service != null && service.hasFileDescriptors() == true) { 13171 throw new IllegalArgumentException("File descriptors passed in Intent"); 13172 } 13173 13174 synchronized(this) { 13175 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13176 connection, flags, userId); 13177 } 13178 } 13179 13180 public boolean unbindService(IServiceConnection connection) { 13181 synchronized (this) { 13182 return mServices.unbindServiceLocked(connection); 13183 } 13184 } 13185 13186 public void publishService(IBinder token, Intent intent, IBinder service) { 13187 // Refuse possible leaked file descriptors 13188 if (intent != null && intent.hasFileDescriptors() == true) { 13189 throw new IllegalArgumentException("File descriptors passed in Intent"); 13190 } 13191 13192 synchronized(this) { 13193 if (!(token instanceof ServiceRecord)) { 13194 throw new IllegalArgumentException("Invalid service token"); 13195 } 13196 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13197 } 13198 } 13199 13200 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13201 // Refuse possible leaked file descriptors 13202 if (intent != null && intent.hasFileDescriptors() == true) { 13203 throw new IllegalArgumentException("File descriptors passed in Intent"); 13204 } 13205 13206 synchronized(this) { 13207 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13208 } 13209 } 13210 13211 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13212 synchronized(this) { 13213 if (!(token instanceof ServiceRecord)) { 13214 throw new IllegalArgumentException("Invalid service token"); 13215 } 13216 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13217 } 13218 } 13219 13220 // ========================================================= 13221 // BACKUP AND RESTORE 13222 // ========================================================= 13223 13224 // Cause the target app to be launched if necessary and its backup agent 13225 // instantiated. The backup agent will invoke backupAgentCreated() on the 13226 // activity manager to announce its creation. 13227 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13228 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13229 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13230 13231 synchronized(this) { 13232 // !!! TODO: currently no check here that we're already bound 13233 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13234 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13235 synchronized (stats) { 13236 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13237 } 13238 13239 // Backup agent is now in use, its package can't be stopped. 13240 try { 13241 AppGlobals.getPackageManager().setPackageStoppedState( 13242 app.packageName, false, UserHandle.getUserId(app.uid)); 13243 } catch (RemoteException e) { 13244 } catch (IllegalArgumentException e) { 13245 Slog.w(TAG, "Failed trying to unstop package " 13246 + app.packageName + ": " + e); 13247 } 13248 13249 BackupRecord r = new BackupRecord(ss, app, backupMode); 13250 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13251 ? new ComponentName(app.packageName, app.backupAgentName) 13252 : new ComponentName("android", "FullBackupAgent"); 13253 // startProcessLocked() returns existing proc's record if it's already running 13254 ProcessRecord proc = startProcessLocked(app.processName, app, 13255 false, 0, "backup", hostingName, false, false, false); 13256 if (proc == null) { 13257 Slog.e(TAG, "Unable to start backup agent process " + r); 13258 return false; 13259 } 13260 13261 r.app = proc; 13262 mBackupTarget = r; 13263 mBackupAppName = app.packageName; 13264 13265 // Try not to kill the process during backup 13266 updateOomAdjLocked(proc); 13267 13268 // If the process is already attached, schedule the creation of the backup agent now. 13269 // If it is not yet live, this will be done when it attaches to the framework. 13270 if (proc.thread != null) { 13271 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13272 try { 13273 proc.thread.scheduleCreateBackupAgent(app, 13274 compatibilityInfoForPackageLocked(app), backupMode); 13275 } catch (RemoteException e) { 13276 // Will time out on the backup manager side 13277 } 13278 } else { 13279 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13280 } 13281 // Invariants: at this point, the target app process exists and the application 13282 // is either already running or in the process of coming up. mBackupTarget and 13283 // mBackupAppName describe the app, so that when it binds back to the AM we 13284 // know that it's scheduled for a backup-agent operation. 13285 } 13286 13287 return true; 13288 } 13289 13290 @Override 13291 public void clearPendingBackup() { 13292 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13293 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13294 13295 synchronized (this) { 13296 mBackupTarget = null; 13297 mBackupAppName = null; 13298 } 13299 } 13300 13301 // A backup agent has just come up 13302 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13303 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13304 + " = " + agent); 13305 13306 synchronized(this) { 13307 if (!agentPackageName.equals(mBackupAppName)) { 13308 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13309 return; 13310 } 13311 } 13312 13313 long oldIdent = Binder.clearCallingIdentity(); 13314 try { 13315 IBackupManager bm = IBackupManager.Stub.asInterface( 13316 ServiceManager.getService(Context.BACKUP_SERVICE)); 13317 bm.agentConnected(agentPackageName, agent); 13318 } catch (RemoteException e) { 13319 // can't happen; the backup manager service is local 13320 } catch (Exception e) { 13321 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13322 e.printStackTrace(); 13323 } finally { 13324 Binder.restoreCallingIdentity(oldIdent); 13325 } 13326 } 13327 13328 // done with this agent 13329 public void unbindBackupAgent(ApplicationInfo appInfo) { 13330 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13331 if (appInfo == null) { 13332 Slog.w(TAG, "unbind backup agent for null app"); 13333 return; 13334 } 13335 13336 synchronized(this) { 13337 try { 13338 if (mBackupAppName == null) { 13339 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13340 return; 13341 } 13342 13343 if (!mBackupAppName.equals(appInfo.packageName)) { 13344 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13345 return; 13346 } 13347 13348 // Not backing this app up any more; reset its OOM adjustment 13349 final ProcessRecord proc = mBackupTarget.app; 13350 updateOomAdjLocked(proc); 13351 13352 // If the app crashed during backup, 'thread' will be null here 13353 if (proc.thread != null) { 13354 try { 13355 proc.thread.scheduleDestroyBackupAgent(appInfo, 13356 compatibilityInfoForPackageLocked(appInfo)); 13357 } catch (Exception e) { 13358 Slog.e(TAG, "Exception when unbinding backup agent:"); 13359 e.printStackTrace(); 13360 } 13361 } 13362 } finally { 13363 mBackupTarget = null; 13364 mBackupAppName = null; 13365 } 13366 } 13367 } 13368 // ========================================================= 13369 // BROADCASTS 13370 // ========================================================= 13371 13372 private final List getStickiesLocked(String action, IntentFilter filter, 13373 List cur, int userId) { 13374 final ContentResolver resolver = mContext.getContentResolver(); 13375 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13376 if (stickies == null) { 13377 return cur; 13378 } 13379 final ArrayList<Intent> list = stickies.get(action); 13380 if (list == null) { 13381 return cur; 13382 } 13383 int N = list.size(); 13384 for (int i=0; i<N; i++) { 13385 Intent intent = list.get(i); 13386 if (filter.match(resolver, intent, true, TAG) >= 0) { 13387 if (cur == null) { 13388 cur = new ArrayList<Intent>(); 13389 } 13390 cur.add(intent); 13391 } 13392 } 13393 return cur; 13394 } 13395 13396 boolean isPendingBroadcastProcessLocked(int pid) { 13397 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13398 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13399 } 13400 13401 void skipPendingBroadcastLocked(int pid) { 13402 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13403 for (BroadcastQueue queue : mBroadcastQueues) { 13404 queue.skipPendingBroadcastLocked(pid); 13405 } 13406 } 13407 13408 // The app just attached; send any pending broadcasts that it should receive 13409 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13410 boolean didSomething = false; 13411 for (BroadcastQueue queue : mBroadcastQueues) { 13412 didSomething |= queue.sendPendingBroadcastsLocked(app); 13413 } 13414 return didSomething; 13415 } 13416 13417 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13418 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13419 enforceNotIsolatedCaller("registerReceiver"); 13420 int callingUid; 13421 int callingPid; 13422 synchronized(this) { 13423 ProcessRecord callerApp = null; 13424 if (caller != null) { 13425 callerApp = getRecordForAppLocked(caller); 13426 if (callerApp == null) { 13427 throw new SecurityException( 13428 "Unable to find app for caller " + caller 13429 + " (pid=" + Binder.getCallingPid() 13430 + ") when registering receiver " + receiver); 13431 } 13432 if (callerApp.info.uid != Process.SYSTEM_UID && 13433 !callerApp.pkgList.containsKey(callerPackage) && 13434 !"android".equals(callerPackage)) { 13435 throw new SecurityException("Given caller package " + callerPackage 13436 + " is not running in process " + callerApp); 13437 } 13438 callingUid = callerApp.info.uid; 13439 callingPid = callerApp.pid; 13440 } else { 13441 callerPackage = null; 13442 callingUid = Binder.getCallingUid(); 13443 callingPid = Binder.getCallingPid(); 13444 } 13445 13446 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13447 true, true, "registerReceiver", callerPackage); 13448 13449 List allSticky = null; 13450 13451 // Look for any matching sticky broadcasts... 13452 Iterator actions = filter.actionsIterator(); 13453 if (actions != null) { 13454 while (actions.hasNext()) { 13455 String action = (String)actions.next(); 13456 allSticky = getStickiesLocked(action, filter, allSticky, 13457 UserHandle.USER_ALL); 13458 allSticky = getStickiesLocked(action, filter, allSticky, 13459 UserHandle.getUserId(callingUid)); 13460 } 13461 } else { 13462 allSticky = getStickiesLocked(null, filter, allSticky, 13463 UserHandle.USER_ALL); 13464 allSticky = getStickiesLocked(null, filter, allSticky, 13465 UserHandle.getUserId(callingUid)); 13466 } 13467 13468 // The first sticky in the list is returned directly back to 13469 // the client. 13470 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13471 13472 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13473 + ": " + sticky); 13474 13475 if (receiver == null) { 13476 return sticky; 13477 } 13478 13479 ReceiverList rl 13480 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13481 if (rl == null) { 13482 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13483 userId, receiver); 13484 if (rl.app != null) { 13485 rl.app.receivers.add(rl); 13486 } else { 13487 try { 13488 receiver.asBinder().linkToDeath(rl, 0); 13489 } catch (RemoteException e) { 13490 return sticky; 13491 } 13492 rl.linkedToDeath = true; 13493 } 13494 mRegisteredReceivers.put(receiver.asBinder(), rl); 13495 } else if (rl.uid != callingUid) { 13496 throw new IllegalArgumentException( 13497 "Receiver requested to register for uid " + callingUid 13498 + " was previously registered for uid " + rl.uid); 13499 } else if (rl.pid != callingPid) { 13500 throw new IllegalArgumentException( 13501 "Receiver requested to register for pid " + callingPid 13502 + " was previously registered for pid " + rl.pid); 13503 } else if (rl.userId != userId) { 13504 throw new IllegalArgumentException( 13505 "Receiver requested to register for user " + userId 13506 + " was previously registered for user " + rl.userId); 13507 } 13508 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13509 permission, callingUid, userId); 13510 rl.add(bf); 13511 if (!bf.debugCheck()) { 13512 Slog.w(TAG, "==> For Dynamic broadast"); 13513 } 13514 mReceiverResolver.addFilter(bf); 13515 13516 // Enqueue broadcasts for all existing stickies that match 13517 // this filter. 13518 if (allSticky != null) { 13519 ArrayList receivers = new ArrayList(); 13520 receivers.add(bf); 13521 13522 int N = allSticky.size(); 13523 for (int i=0; i<N; i++) { 13524 Intent intent = (Intent)allSticky.get(i); 13525 BroadcastQueue queue = broadcastQueueForIntent(intent); 13526 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13527 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13528 null, null, false, true, true, -1); 13529 queue.enqueueParallelBroadcastLocked(r); 13530 queue.scheduleBroadcastsLocked(); 13531 } 13532 } 13533 13534 return sticky; 13535 } 13536 } 13537 13538 public void unregisterReceiver(IIntentReceiver receiver) { 13539 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13540 13541 final long origId = Binder.clearCallingIdentity(); 13542 try { 13543 boolean doTrim = false; 13544 13545 synchronized(this) { 13546 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13547 if (rl != null) { 13548 if (rl.curBroadcast != null) { 13549 BroadcastRecord r = rl.curBroadcast; 13550 final boolean doNext = finishReceiverLocked( 13551 receiver.asBinder(), r.resultCode, r.resultData, 13552 r.resultExtras, r.resultAbort); 13553 if (doNext) { 13554 doTrim = true; 13555 r.queue.processNextBroadcast(false); 13556 } 13557 } 13558 13559 if (rl.app != null) { 13560 rl.app.receivers.remove(rl); 13561 } 13562 removeReceiverLocked(rl); 13563 if (rl.linkedToDeath) { 13564 rl.linkedToDeath = false; 13565 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13566 } 13567 } 13568 } 13569 13570 // If we actually concluded any broadcasts, we might now be able 13571 // to trim the recipients' apps from our working set 13572 if (doTrim) { 13573 trimApplications(); 13574 return; 13575 } 13576 13577 } finally { 13578 Binder.restoreCallingIdentity(origId); 13579 } 13580 } 13581 13582 void removeReceiverLocked(ReceiverList rl) { 13583 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13584 int N = rl.size(); 13585 for (int i=0; i<N; i++) { 13586 mReceiverResolver.removeFilter(rl.get(i)); 13587 } 13588 } 13589 13590 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13591 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13592 ProcessRecord r = mLruProcesses.get(i); 13593 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13594 try { 13595 r.thread.dispatchPackageBroadcast(cmd, packages); 13596 } catch (RemoteException ex) { 13597 } 13598 } 13599 } 13600 } 13601 13602 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13603 int[] users) { 13604 List<ResolveInfo> receivers = null; 13605 try { 13606 HashSet<ComponentName> singleUserReceivers = null; 13607 boolean scannedFirstReceivers = false; 13608 for (int user : users) { 13609 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13610 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13611 if (user != 0 && newReceivers != null) { 13612 // If this is not the primary user, we need to check for 13613 // any receivers that should be filtered out. 13614 for (int i=0; i<newReceivers.size(); i++) { 13615 ResolveInfo ri = newReceivers.get(i); 13616 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13617 newReceivers.remove(i); 13618 i--; 13619 } 13620 } 13621 } 13622 if (newReceivers != null && newReceivers.size() == 0) { 13623 newReceivers = null; 13624 } 13625 if (receivers == null) { 13626 receivers = newReceivers; 13627 } else if (newReceivers != null) { 13628 // We need to concatenate the additional receivers 13629 // found with what we have do far. This would be easy, 13630 // but we also need to de-dup any receivers that are 13631 // singleUser. 13632 if (!scannedFirstReceivers) { 13633 // Collect any single user receivers we had already retrieved. 13634 scannedFirstReceivers = true; 13635 for (int i=0; i<receivers.size(); i++) { 13636 ResolveInfo ri = receivers.get(i); 13637 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13638 ComponentName cn = new ComponentName( 13639 ri.activityInfo.packageName, ri.activityInfo.name); 13640 if (singleUserReceivers == null) { 13641 singleUserReceivers = new HashSet<ComponentName>(); 13642 } 13643 singleUserReceivers.add(cn); 13644 } 13645 } 13646 } 13647 // Add the new results to the existing results, tracking 13648 // and de-dupping single user receivers. 13649 for (int i=0; i<newReceivers.size(); i++) { 13650 ResolveInfo ri = newReceivers.get(i); 13651 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13652 ComponentName cn = new ComponentName( 13653 ri.activityInfo.packageName, ri.activityInfo.name); 13654 if (singleUserReceivers == null) { 13655 singleUserReceivers = new HashSet<ComponentName>(); 13656 } 13657 if (!singleUserReceivers.contains(cn)) { 13658 singleUserReceivers.add(cn); 13659 receivers.add(ri); 13660 } 13661 } else { 13662 receivers.add(ri); 13663 } 13664 } 13665 } 13666 } 13667 } catch (RemoteException ex) { 13668 // pm is in same process, this will never happen. 13669 } 13670 return receivers; 13671 } 13672 13673 private final int broadcastIntentLocked(ProcessRecord callerApp, 13674 String callerPackage, Intent intent, String resolvedType, 13675 IIntentReceiver resultTo, int resultCode, String resultData, 13676 Bundle map, String requiredPermission, int appOp, 13677 boolean ordered, boolean sticky, int callingPid, int callingUid, 13678 int userId) { 13679 intent = new Intent(intent); 13680 13681 // By default broadcasts do not go to stopped apps. 13682 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13683 13684 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13685 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13686 + " ordered=" + ordered + " userid=" + userId); 13687 if ((resultTo != null) && !ordered) { 13688 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13689 } 13690 13691 userId = handleIncomingUser(callingPid, callingUid, userId, 13692 true, false, "broadcast", callerPackage); 13693 13694 // Make sure that the user who is receiving this broadcast is started. 13695 // If not, we will just skip it. 13696 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13697 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13698 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13699 Slog.w(TAG, "Skipping broadcast of " + intent 13700 + ": user " + userId + " is stopped"); 13701 return ActivityManager.BROADCAST_SUCCESS; 13702 } 13703 } 13704 13705 /* 13706 * Prevent non-system code (defined here to be non-persistent 13707 * processes) from sending protected broadcasts. 13708 */ 13709 int callingAppId = UserHandle.getAppId(callingUid); 13710 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13711 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13712 callingUid == 0) { 13713 // Always okay. 13714 } else if (callerApp == null || !callerApp.persistent) { 13715 try { 13716 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13717 intent.getAction())) { 13718 String msg = "Permission Denial: not allowed to send broadcast " 13719 + intent.getAction() + " from pid=" 13720 + callingPid + ", uid=" + callingUid; 13721 Slog.w(TAG, msg); 13722 throw new SecurityException(msg); 13723 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13724 // Special case for compatibility: we don't want apps to send this, 13725 // but historically it has not been protected and apps may be using it 13726 // to poke their own app widget. So, instead of making it protected, 13727 // just limit it to the caller. 13728 if (callerApp == null) { 13729 String msg = "Permission Denial: not allowed to send broadcast " 13730 + intent.getAction() + " from unknown caller."; 13731 Slog.w(TAG, msg); 13732 throw new SecurityException(msg); 13733 } else if (intent.getComponent() != null) { 13734 // They are good enough to send to an explicit component... verify 13735 // it is being sent to the calling app. 13736 if (!intent.getComponent().getPackageName().equals( 13737 callerApp.info.packageName)) { 13738 String msg = "Permission Denial: not allowed to send broadcast " 13739 + intent.getAction() + " to " 13740 + intent.getComponent().getPackageName() + " from " 13741 + callerApp.info.packageName; 13742 Slog.w(TAG, msg); 13743 throw new SecurityException(msg); 13744 } 13745 } else { 13746 // Limit broadcast to their own package. 13747 intent.setPackage(callerApp.info.packageName); 13748 } 13749 } 13750 } catch (RemoteException e) { 13751 Slog.w(TAG, "Remote exception", e); 13752 return ActivityManager.BROADCAST_SUCCESS; 13753 } 13754 } 13755 13756 // Handle special intents: if this broadcast is from the package 13757 // manager about a package being removed, we need to remove all of 13758 // its activities from the history stack. 13759 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13760 intent.getAction()); 13761 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13762 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13763 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13764 || uidRemoved) { 13765 if (checkComponentPermission( 13766 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13767 callingPid, callingUid, -1, true) 13768 == PackageManager.PERMISSION_GRANTED) { 13769 if (uidRemoved) { 13770 final Bundle intentExtras = intent.getExtras(); 13771 final int uid = intentExtras != null 13772 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13773 if (uid >= 0) { 13774 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13775 synchronized (bs) { 13776 bs.removeUidStatsLocked(uid); 13777 } 13778 mAppOpsService.uidRemoved(uid); 13779 } 13780 } else { 13781 // If resources are unavailable just force stop all 13782 // those packages and flush the attribute cache as well. 13783 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13784 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13785 if (list != null && (list.length > 0)) { 13786 for (String pkg : list) { 13787 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13788 "storage unmount"); 13789 } 13790 sendPackageBroadcastLocked( 13791 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13792 } 13793 } else { 13794 Uri data = intent.getData(); 13795 String ssp; 13796 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13797 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13798 intent.getAction()); 13799 boolean fullUninstall = removed && 13800 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13801 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13802 forceStopPackageLocked(ssp, UserHandle.getAppId( 13803 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13804 false, fullUninstall, userId, 13805 removed ? "pkg removed" : "pkg changed"); 13806 } 13807 if (removed) { 13808 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13809 new String[] {ssp}, userId); 13810 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13811 mAppOpsService.packageRemoved( 13812 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13813 13814 // Remove all permissions granted from/to this package 13815 removeUriPermissionsForPackageLocked(ssp, userId, true); 13816 } 13817 } 13818 } 13819 } 13820 } 13821 } else { 13822 String msg = "Permission Denial: " + intent.getAction() 13823 + " broadcast from " + callerPackage + " (pid=" + callingPid 13824 + ", uid=" + callingUid + ")" 13825 + " requires " 13826 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13827 Slog.w(TAG, msg); 13828 throw new SecurityException(msg); 13829 } 13830 13831 // Special case for adding a package: by default turn on compatibility 13832 // mode. 13833 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13834 Uri data = intent.getData(); 13835 String ssp; 13836 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13837 mCompatModePackages.handlePackageAddedLocked(ssp, 13838 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13839 } 13840 } 13841 13842 /* 13843 * If this is the time zone changed action, queue up a message that will reset the timezone 13844 * of all currently running processes. This message will get queued up before the broadcast 13845 * happens. 13846 */ 13847 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13848 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13849 } 13850 13851 /* 13852 * If the user set the time, let all running processes know. 13853 */ 13854 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13855 final int is24Hour = intent.getBooleanExtra( 13856 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13857 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13858 } 13859 13860 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13861 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13862 } 13863 13864 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13865 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 13866 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13867 } 13868 13869 // Add to the sticky list if requested. 13870 if (sticky) { 13871 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13872 callingPid, callingUid) 13873 != PackageManager.PERMISSION_GRANTED) { 13874 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13875 + callingPid + ", uid=" + callingUid 13876 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13877 Slog.w(TAG, msg); 13878 throw new SecurityException(msg); 13879 } 13880 if (requiredPermission != null) { 13881 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13882 + " and enforce permission " + requiredPermission); 13883 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13884 } 13885 if (intent.getComponent() != null) { 13886 throw new SecurityException( 13887 "Sticky broadcasts can't target a specific component"); 13888 } 13889 // We use userId directly here, since the "all" target is maintained 13890 // as a separate set of sticky broadcasts. 13891 if (userId != UserHandle.USER_ALL) { 13892 // But first, if this is not a broadcast to all users, then 13893 // make sure it doesn't conflict with an existing broadcast to 13894 // all users. 13895 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13896 UserHandle.USER_ALL); 13897 if (stickies != null) { 13898 ArrayList<Intent> list = stickies.get(intent.getAction()); 13899 if (list != null) { 13900 int N = list.size(); 13901 int i; 13902 for (i=0; i<N; i++) { 13903 if (intent.filterEquals(list.get(i))) { 13904 throw new IllegalArgumentException( 13905 "Sticky broadcast " + intent + " for user " 13906 + userId + " conflicts with existing global broadcast"); 13907 } 13908 } 13909 } 13910 } 13911 } 13912 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13913 if (stickies == null) { 13914 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13915 mStickyBroadcasts.put(userId, stickies); 13916 } 13917 ArrayList<Intent> list = stickies.get(intent.getAction()); 13918 if (list == null) { 13919 list = new ArrayList<Intent>(); 13920 stickies.put(intent.getAction(), list); 13921 } 13922 int N = list.size(); 13923 int i; 13924 for (i=0; i<N; i++) { 13925 if (intent.filterEquals(list.get(i))) { 13926 // This sticky already exists, replace it. 13927 list.set(i, new Intent(intent)); 13928 break; 13929 } 13930 } 13931 if (i >= N) { 13932 list.add(new Intent(intent)); 13933 } 13934 } 13935 13936 int[] users; 13937 if (userId == UserHandle.USER_ALL) { 13938 // Caller wants broadcast to go to all started users. 13939 users = mStartedUserArray; 13940 } else { 13941 // Caller wants broadcast to go to one specific user. 13942 users = new int[] {userId}; 13943 } 13944 13945 // Figure out who all will receive this broadcast. 13946 List receivers = null; 13947 List<BroadcastFilter> registeredReceivers = null; 13948 // Need to resolve the intent to interested receivers... 13949 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13950 == 0) { 13951 receivers = collectReceiverComponents(intent, resolvedType, users); 13952 } 13953 if (intent.getComponent() == null) { 13954 registeredReceivers = mReceiverResolver.queryIntent(intent, 13955 resolvedType, false, userId); 13956 } 13957 13958 final boolean replacePending = 13959 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13960 13961 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13962 + " replacePending=" + replacePending); 13963 13964 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13965 if (!ordered && NR > 0) { 13966 // If we are not serializing this broadcast, then send the 13967 // registered receivers separately so they don't wait for the 13968 // components to be launched. 13969 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13970 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13971 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13972 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13973 ordered, sticky, false, userId); 13974 if (DEBUG_BROADCAST) Slog.v( 13975 TAG, "Enqueueing parallel broadcast " + r); 13976 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13977 if (!replaced) { 13978 queue.enqueueParallelBroadcastLocked(r); 13979 queue.scheduleBroadcastsLocked(); 13980 } 13981 registeredReceivers = null; 13982 NR = 0; 13983 } 13984 13985 // Merge into one list. 13986 int ir = 0; 13987 if (receivers != null) { 13988 // A special case for PACKAGE_ADDED: do not allow the package 13989 // being added to see this broadcast. This prevents them from 13990 // using this as a back door to get run as soon as they are 13991 // installed. Maybe in the future we want to have a special install 13992 // broadcast or such for apps, but we'd like to deliberately make 13993 // this decision. 13994 String skipPackages[] = null; 13995 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13996 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13997 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13998 Uri data = intent.getData(); 13999 if (data != null) { 14000 String pkgName = data.getSchemeSpecificPart(); 14001 if (pkgName != null) { 14002 skipPackages = new String[] { pkgName }; 14003 } 14004 } 14005 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 14006 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14007 } 14008 if (skipPackages != null && (skipPackages.length > 0)) { 14009 for (String skipPackage : skipPackages) { 14010 if (skipPackage != null) { 14011 int NT = receivers.size(); 14012 for (int it=0; it<NT; it++) { 14013 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14014 if (curt.activityInfo.packageName.equals(skipPackage)) { 14015 receivers.remove(it); 14016 it--; 14017 NT--; 14018 } 14019 } 14020 } 14021 } 14022 } 14023 14024 int NT = receivers != null ? receivers.size() : 0; 14025 int it = 0; 14026 ResolveInfo curt = null; 14027 BroadcastFilter curr = null; 14028 while (it < NT && ir < NR) { 14029 if (curt == null) { 14030 curt = (ResolveInfo)receivers.get(it); 14031 } 14032 if (curr == null) { 14033 curr = registeredReceivers.get(ir); 14034 } 14035 if (curr.getPriority() >= curt.priority) { 14036 // Insert this broadcast record into the final list. 14037 receivers.add(it, curr); 14038 ir++; 14039 curr = null; 14040 it++; 14041 NT++; 14042 } else { 14043 // Skip to the next ResolveInfo in the final list. 14044 it++; 14045 curt = null; 14046 } 14047 } 14048 } 14049 while (ir < NR) { 14050 if (receivers == null) { 14051 receivers = new ArrayList(); 14052 } 14053 receivers.add(registeredReceivers.get(ir)); 14054 ir++; 14055 } 14056 14057 if ((receivers != null && receivers.size() > 0) 14058 || resultTo != null) { 14059 BroadcastQueue queue = broadcastQueueForIntent(intent); 14060 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14061 callerPackage, callingPid, callingUid, resolvedType, 14062 requiredPermission, appOp, receivers, resultTo, resultCode, 14063 resultData, map, ordered, sticky, false, userId); 14064 if (DEBUG_BROADCAST) Slog.v( 14065 TAG, "Enqueueing ordered broadcast " + r 14066 + ": prev had " + queue.mOrderedBroadcasts.size()); 14067 if (DEBUG_BROADCAST) { 14068 int seq = r.intent.getIntExtra("seq", -1); 14069 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14070 } 14071 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14072 if (!replaced) { 14073 queue.enqueueOrderedBroadcastLocked(r); 14074 queue.scheduleBroadcastsLocked(); 14075 } 14076 } 14077 14078 return ActivityManager.BROADCAST_SUCCESS; 14079 } 14080 14081 final Intent verifyBroadcastLocked(Intent intent) { 14082 // Refuse possible leaked file descriptors 14083 if (intent != null && intent.hasFileDescriptors() == true) { 14084 throw new IllegalArgumentException("File descriptors passed in Intent"); 14085 } 14086 14087 int flags = intent.getFlags(); 14088 14089 if (!mProcessesReady) { 14090 // if the caller really truly claims to know what they're doing, go 14091 // ahead and allow the broadcast without launching any receivers 14092 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14093 intent = new Intent(intent); 14094 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14095 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14096 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14097 + " before boot completion"); 14098 throw new IllegalStateException("Cannot broadcast before boot completed"); 14099 } 14100 } 14101 14102 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14103 throw new IllegalArgumentException( 14104 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14105 } 14106 14107 return intent; 14108 } 14109 14110 public final int broadcastIntent(IApplicationThread caller, 14111 Intent intent, String resolvedType, IIntentReceiver resultTo, 14112 int resultCode, String resultData, Bundle map, 14113 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14114 enforceNotIsolatedCaller("broadcastIntent"); 14115 synchronized(this) { 14116 intent = verifyBroadcastLocked(intent); 14117 14118 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14119 final int callingPid = Binder.getCallingPid(); 14120 final int callingUid = Binder.getCallingUid(); 14121 final long origId = Binder.clearCallingIdentity(); 14122 int res = broadcastIntentLocked(callerApp, 14123 callerApp != null ? callerApp.info.packageName : null, 14124 intent, resolvedType, resultTo, 14125 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14126 callingPid, callingUid, userId); 14127 Binder.restoreCallingIdentity(origId); 14128 return res; 14129 } 14130 } 14131 14132 int broadcastIntentInPackage(String packageName, int uid, 14133 Intent intent, String resolvedType, IIntentReceiver resultTo, 14134 int resultCode, String resultData, Bundle map, 14135 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14136 synchronized(this) { 14137 intent = verifyBroadcastLocked(intent); 14138 14139 final long origId = Binder.clearCallingIdentity(); 14140 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14141 resultTo, resultCode, resultData, map, requiredPermission, 14142 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14143 Binder.restoreCallingIdentity(origId); 14144 return res; 14145 } 14146 } 14147 14148 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14149 // Refuse possible leaked file descriptors 14150 if (intent != null && intent.hasFileDescriptors() == true) { 14151 throw new IllegalArgumentException("File descriptors passed in Intent"); 14152 } 14153 14154 userId = handleIncomingUser(Binder.getCallingPid(), 14155 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14156 14157 synchronized(this) { 14158 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14159 != PackageManager.PERMISSION_GRANTED) { 14160 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14161 + Binder.getCallingPid() 14162 + ", uid=" + Binder.getCallingUid() 14163 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14164 Slog.w(TAG, msg); 14165 throw new SecurityException(msg); 14166 } 14167 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14168 if (stickies != null) { 14169 ArrayList<Intent> list = stickies.get(intent.getAction()); 14170 if (list != null) { 14171 int N = list.size(); 14172 int i; 14173 for (i=0; i<N; i++) { 14174 if (intent.filterEquals(list.get(i))) { 14175 list.remove(i); 14176 break; 14177 } 14178 } 14179 if (list.size() <= 0) { 14180 stickies.remove(intent.getAction()); 14181 } 14182 } 14183 if (stickies.size() <= 0) { 14184 mStickyBroadcasts.remove(userId); 14185 } 14186 } 14187 } 14188 } 14189 14190 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14191 String resultData, Bundle resultExtras, boolean resultAbort) { 14192 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14193 if (r == null) { 14194 Slog.w(TAG, "finishReceiver called but not found on queue"); 14195 return false; 14196 } 14197 14198 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14199 } 14200 14201 void backgroundServicesFinishedLocked(int userId) { 14202 for (BroadcastQueue queue : mBroadcastQueues) { 14203 queue.backgroundServicesFinishedLocked(userId); 14204 } 14205 } 14206 14207 public void finishReceiver(IBinder who, int resultCode, String resultData, 14208 Bundle resultExtras, boolean resultAbort) { 14209 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14210 14211 // Refuse possible leaked file descriptors 14212 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14213 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14214 } 14215 14216 final long origId = Binder.clearCallingIdentity(); 14217 try { 14218 boolean doNext = false; 14219 BroadcastRecord r; 14220 14221 synchronized(this) { 14222 r = broadcastRecordForReceiverLocked(who); 14223 if (r != null) { 14224 doNext = r.queue.finishReceiverLocked(r, resultCode, 14225 resultData, resultExtras, resultAbort, true); 14226 } 14227 } 14228 14229 if (doNext) { 14230 r.queue.processNextBroadcast(false); 14231 } 14232 trimApplications(); 14233 } finally { 14234 Binder.restoreCallingIdentity(origId); 14235 } 14236 } 14237 14238 // ========================================================= 14239 // INSTRUMENTATION 14240 // ========================================================= 14241 14242 public boolean startInstrumentation(ComponentName className, 14243 String profileFile, int flags, Bundle arguments, 14244 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14245 int userId) { 14246 enforceNotIsolatedCaller("startInstrumentation"); 14247 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14248 userId, false, true, "startInstrumentation", null); 14249 // Refuse possible leaked file descriptors 14250 if (arguments != null && arguments.hasFileDescriptors()) { 14251 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14252 } 14253 14254 synchronized(this) { 14255 InstrumentationInfo ii = null; 14256 ApplicationInfo ai = null; 14257 try { 14258 ii = mContext.getPackageManager().getInstrumentationInfo( 14259 className, STOCK_PM_FLAGS); 14260 ai = AppGlobals.getPackageManager().getApplicationInfo( 14261 ii.targetPackage, STOCK_PM_FLAGS, userId); 14262 } catch (PackageManager.NameNotFoundException e) { 14263 } catch (RemoteException e) { 14264 } 14265 if (ii == null) { 14266 reportStartInstrumentationFailure(watcher, className, 14267 "Unable to find instrumentation info for: " + className); 14268 return false; 14269 } 14270 if (ai == null) { 14271 reportStartInstrumentationFailure(watcher, className, 14272 "Unable to find instrumentation target package: " + ii.targetPackage); 14273 return false; 14274 } 14275 14276 int match = mContext.getPackageManager().checkSignatures( 14277 ii.targetPackage, ii.packageName); 14278 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14279 String msg = "Permission Denial: starting instrumentation " 14280 + className + " from pid=" 14281 + Binder.getCallingPid() 14282 + ", uid=" + Binder.getCallingPid() 14283 + " not allowed because package " + ii.packageName 14284 + " does not have a signature matching the target " 14285 + ii.targetPackage; 14286 reportStartInstrumentationFailure(watcher, className, msg); 14287 throw new SecurityException(msg); 14288 } 14289 14290 final long origId = Binder.clearCallingIdentity(); 14291 // Instrumentation can kill and relaunch even persistent processes 14292 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14293 "start instr"); 14294 ProcessRecord app = addAppLocked(ai, false); 14295 app.instrumentationClass = className; 14296 app.instrumentationInfo = ai; 14297 app.instrumentationProfileFile = profileFile; 14298 app.instrumentationArguments = arguments; 14299 app.instrumentationWatcher = watcher; 14300 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14301 app.instrumentationResultClass = className; 14302 Binder.restoreCallingIdentity(origId); 14303 } 14304 14305 return true; 14306 } 14307 14308 /** 14309 * Report errors that occur while attempting to start Instrumentation. Always writes the 14310 * error to the logs, but if somebody is watching, send the report there too. This enables 14311 * the "am" command to report errors with more information. 14312 * 14313 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14314 * @param cn The component name of the instrumentation. 14315 * @param report The error report. 14316 */ 14317 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14318 ComponentName cn, String report) { 14319 Slog.w(TAG, report); 14320 try { 14321 if (watcher != null) { 14322 Bundle results = new Bundle(); 14323 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14324 results.putString("Error", report); 14325 watcher.instrumentationStatus(cn, -1, results); 14326 } 14327 } catch (RemoteException e) { 14328 Slog.w(TAG, e); 14329 } 14330 } 14331 14332 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14333 if (app.instrumentationWatcher != null) { 14334 try { 14335 // NOTE: IInstrumentationWatcher *must* be oneway here 14336 app.instrumentationWatcher.instrumentationFinished( 14337 app.instrumentationClass, 14338 resultCode, 14339 results); 14340 } catch (RemoteException e) { 14341 } 14342 } 14343 if (app.instrumentationUiAutomationConnection != null) { 14344 try { 14345 app.instrumentationUiAutomationConnection.shutdown(); 14346 } catch (RemoteException re) { 14347 /* ignore */ 14348 } 14349 // Only a UiAutomation can set this flag and now that 14350 // it is finished we make sure it is reset to its default. 14351 mUserIsMonkey = false; 14352 } 14353 app.instrumentationWatcher = null; 14354 app.instrumentationUiAutomationConnection = null; 14355 app.instrumentationClass = null; 14356 app.instrumentationInfo = null; 14357 app.instrumentationProfileFile = null; 14358 app.instrumentationArguments = null; 14359 14360 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14361 "finished inst"); 14362 } 14363 14364 public void finishInstrumentation(IApplicationThread target, 14365 int resultCode, Bundle results) { 14366 int userId = UserHandle.getCallingUserId(); 14367 // Refuse possible leaked file descriptors 14368 if (results != null && results.hasFileDescriptors()) { 14369 throw new IllegalArgumentException("File descriptors passed in Intent"); 14370 } 14371 14372 synchronized(this) { 14373 ProcessRecord app = getRecordForAppLocked(target); 14374 if (app == null) { 14375 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14376 return; 14377 } 14378 final long origId = Binder.clearCallingIdentity(); 14379 finishInstrumentationLocked(app, resultCode, results); 14380 Binder.restoreCallingIdentity(origId); 14381 } 14382 } 14383 14384 // ========================================================= 14385 // CONFIGURATION 14386 // ========================================================= 14387 14388 public ConfigurationInfo getDeviceConfigurationInfo() { 14389 ConfigurationInfo config = new ConfigurationInfo(); 14390 synchronized (this) { 14391 config.reqTouchScreen = mConfiguration.touchscreen; 14392 config.reqKeyboardType = mConfiguration.keyboard; 14393 config.reqNavigation = mConfiguration.navigation; 14394 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14395 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14396 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14397 } 14398 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14399 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14400 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14401 } 14402 config.reqGlEsVersion = GL_ES_VERSION; 14403 } 14404 return config; 14405 } 14406 14407 ActivityStack getFocusedStack() { 14408 return mStackSupervisor.getFocusedStack(); 14409 } 14410 14411 public Configuration getConfiguration() { 14412 Configuration ci; 14413 synchronized(this) { 14414 ci = new Configuration(mConfiguration); 14415 } 14416 return ci; 14417 } 14418 14419 public void updatePersistentConfiguration(Configuration values) { 14420 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14421 "updateConfiguration()"); 14422 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14423 "updateConfiguration()"); 14424 if (values == null) { 14425 throw new NullPointerException("Configuration must not be null"); 14426 } 14427 14428 synchronized(this) { 14429 final long origId = Binder.clearCallingIdentity(); 14430 updateConfigurationLocked(values, null, true, false); 14431 Binder.restoreCallingIdentity(origId); 14432 } 14433 } 14434 14435 public void updateConfiguration(Configuration values) { 14436 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14437 "updateConfiguration()"); 14438 14439 synchronized(this) { 14440 if (values == null && mWindowManager != null) { 14441 // sentinel: fetch the current configuration from the window manager 14442 values = mWindowManager.computeNewConfiguration(); 14443 } 14444 14445 if (mWindowManager != null) { 14446 mProcessList.applyDisplaySize(mWindowManager); 14447 } 14448 14449 final long origId = Binder.clearCallingIdentity(); 14450 if (values != null) { 14451 Settings.System.clearConfiguration(values); 14452 } 14453 updateConfigurationLocked(values, null, false, false); 14454 Binder.restoreCallingIdentity(origId); 14455 } 14456 } 14457 14458 /** 14459 * Do either or both things: (1) change the current configuration, and (2) 14460 * make sure the given activity is running with the (now) current 14461 * configuration. Returns true if the activity has been left running, or 14462 * false if <var>starting</var> is being destroyed to match the new 14463 * configuration. 14464 * @param persistent TODO 14465 */ 14466 boolean updateConfigurationLocked(Configuration values, 14467 ActivityRecord starting, boolean persistent, boolean initLocale) { 14468 int changes = 0; 14469 14470 if (values != null) { 14471 Configuration newConfig = new Configuration(mConfiguration); 14472 changes = newConfig.updateFrom(values); 14473 if (changes != 0) { 14474 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14475 Slog.i(TAG, "Updating configuration to: " + values); 14476 } 14477 14478 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14479 14480 if (values.locale != null && !initLocale) { 14481 saveLocaleLocked(values.locale, 14482 !values.locale.equals(mConfiguration.locale), 14483 values.userSetLocale); 14484 } 14485 14486 mConfigurationSeq++; 14487 if (mConfigurationSeq <= 0) { 14488 mConfigurationSeq = 1; 14489 } 14490 newConfig.seq = mConfigurationSeq; 14491 mConfiguration = newConfig; 14492 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14493 mUsageStatsService.noteStartConfig(newConfig); 14494 14495 final Configuration configCopy = new Configuration(mConfiguration); 14496 14497 // TODO: If our config changes, should we auto dismiss any currently 14498 // showing dialogs? 14499 mShowDialogs = shouldShowDialogs(newConfig); 14500 14501 AttributeCache ac = AttributeCache.instance(); 14502 if (ac != null) { 14503 ac.updateConfiguration(configCopy); 14504 } 14505 14506 // Make sure all resources in our process are updated 14507 // right now, so that anyone who is going to retrieve 14508 // resource values after we return will be sure to get 14509 // the new ones. This is especially important during 14510 // boot, where the first config change needs to guarantee 14511 // all resources have that config before following boot 14512 // code is executed. 14513 mSystemThread.applyConfigurationToResources(configCopy); 14514 14515 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14516 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14517 msg.obj = new Configuration(configCopy); 14518 mHandler.sendMessage(msg); 14519 } 14520 14521 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14522 ProcessRecord app = mLruProcesses.get(i); 14523 try { 14524 if (app.thread != null) { 14525 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14526 + app.processName + " new config " + mConfiguration); 14527 app.thread.scheduleConfigurationChanged(configCopy); 14528 } 14529 } catch (Exception e) { 14530 } 14531 } 14532 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14533 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14534 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14535 | Intent.FLAG_RECEIVER_FOREGROUND); 14536 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14537 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14538 Process.SYSTEM_UID, UserHandle.USER_ALL); 14539 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14540 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14541 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14542 broadcastIntentLocked(null, null, intent, 14543 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14544 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14545 } 14546 } 14547 } 14548 14549 boolean kept = true; 14550 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14551 // mainStack is null during startup. 14552 if (mainStack != null) { 14553 if (changes != 0 && starting == null) { 14554 // If the configuration changed, and the caller is not already 14555 // in the process of starting an activity, then find the top 14556 // activity to check if its configuration needs to change. 14557 starting = mainStack.topRunningActivityLocked(null); 14558 } 14559 14560 if (starting != null) { 14561 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14562 // And we need to make sure at this point that all other activities 14563 // are made visible with the correct configuration. 14564 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14565 } 14566 } 14567 14568 if (values != null && mWindowManager != null) { 14569 mWindowManager.setNewConfiguration(mConfiguration); 14570 } 14571 14572 return kept; 14573 } 14574 14575 /** 14576 * Decide based on the configuration whether we should shouw the ANR, 14577 * crash, etc dialogs. The idea is that if there is no affordnace to 14578 * press the on-screen buttons, we shouldn't show the dialog. 14579 * 14580 * A thought: SystemUI might also want to get told about this, the Power 14581 * dialog / global actions also might want different behaviors. 14582 */ 14583 private static final boolean shouldShowDialogs(Configuration config) { 14584 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14585 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14586 } 14587 14588 /** 14589 * Save the locale. You must be inside a synchronized (this) block. 14590 */ 14591 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14592 if(isDiff) { 14593 SystemProperties.set("user.language", l.getLanguage()); 14594 SystemProperties.set("user.region", l.getCountry()); 14595 } 14596 14597 if(isPersist) { 14598 SystemProperties.set("persist.sys.language", l.getLanguage()); 14599 SystemProperties.set("persist.sys.country", l.getCountry()); 14600 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14601 } 14602 } 14603 14604 @Override 14605 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14606 ActivityRecord srec = ActivityRecord.forToken(token); 14607 return srec != null && srec.task.affinity != null && 14608 srec.task.affinity.equals(destAffinity); 14609 } 14610 14611 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14612 Intent resultData) { 14613 14614 synchronized (this) { 14615 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14616 if (stack != null) { 14617 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14618 } 14619 return false; 14620 } 14621 } 14622 14623 public int getLaunchedFromUid(IBinder activityToken) { 14624 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14625 if (srec == null) { 14626 return -1; 14627 } 14628 return srec.launchedFromUid; 14629 } 14630 14631 public String getLaunchedFromPackage(IBinder activityToken) { 14632 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14633 if (srec == null) { 14634 return null; 14635 } 14636 return srec.launchedFromPackage; 14637 } 14638 14639 // ========================================================= 14640 // LIFETIME MANAGEMENT 14641 // ========================================================= 14642 14643 // Returns which broadcast queue the app is the current [or imminent] receiver 14644 // on, or 'null' if the app is not an active broadcast recipient. 14645 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14646 BroadcastRecord r = app.curReceiver; 14647 if (r != null) { 14648 return r.queue; 14649 } 14650 14651 // It's not the current receiver, but it might be starting up to become one 14652 synchronized (this) { 14653 for (BroadcastQueue queue : mBroadcastQueues) { 14654 r = queue.mPendingBroadcast; 14655 if (r != null && r.curApp == app) { 14656 // found it; report which queue it's in 14657 return queue; 14658 } 14659 } 14660 } 14661 14662 return null; 14663 } 14664 14665 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14666 boolean doingAll, long now) { 14667 if (mAdjSeq == app.adjSeq) { 14668 // This adjustment has already been computed. 14669 return app.curRawAdj; 14670 } 14671 14672 if (app.thread == null) { 14673 app.adjSeq = mAdjSeq; 14674 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14675 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14676 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14677 } 14678 14679 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14680 app.adjSource = null; 14681 app.adjTarget = null; 14682 app.empty = false; 14683 app.cached = false; 14684 14685 final int activitiesSize = app.activities.size(); 14686 14687 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14688 // The max adjustment doesn't allow this app to be anything 14689 // below foreground, so it is not worth doing work for it. 14690 app.adjType = "fixed"; 14691 app.adjSeq = mAdjSeq; 14692 app.curRawAdj = app.maxAdj; 14693 app.foregroundActivities = false; 14694 app.keeping = true; 14695 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14696 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14697 // System processes can do UI, and when they do we want to have 14698 // them trim their memory after the user leaves the UI. To 14699 // facilitate this, here we need to determine whether or not it 14700 // is currently showing UI. 14701 app.systemNoUi = true; 14702 if (app == TOP_APP) { 14703 app.systemNoUi = false; 14704 } else if (activitiesSize > 0) { 14705 for (int j = 0; j < activitiesSize; j++) { 14706 final ActivityRecord r = app.activities.get(j); 14707 if (r.visible) { 14708 app.systemNoUi = false; 14709 } 14710 } 14711 } 14712 if (!app.systemNoUi) { 14713 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14714 } 14715 return (app.curAdj=app.maxAdj); 14716 } 14717 14718 app.keeping = false; 14719 app.systemNoUi = false; 14720 14721 // Determine the importance of the process, starting with most 14722 // important to least, and assign an appropriate OOM adjustment. 14723 int adj; 14724 int schedGroup; 14725 int procState; 14726 boolean foregroundActivities = false; 14727 boolean interesting = false; 14728 BroadcastQueue queue; 14729 if (app == TOP_APP) { 14730 // The last app on the list is the foreground app. 14731 adj = ProcessList.FOREGROUND_APP_ADJ; 14732 schedGroup = Process.THREAD_GROUP_DEFAULT; 14733 app.adjType = "top-activity"; 14734 foregroundActivities = true; 14735 interesting = true; 14736 procState = ActivityManager.PROCESS_STATE_TOP; 14737 } else if (app.instrumentationClass != null) { 14738 // Don't want to kill running instrumentation. 14739 adj = ProcessList.FOREGROUND_APP_ADJ; 14740 schedGroup = Process.THREAD_GROUP_DEFAULT; 14741 app.adjType = "instrumentation"; 14742 interesting = true; 14743 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14744 } else if ((queue = isReceivingBroadcast(app)) != null) { 14745 // An app that is currently receiving a broadcast also 14746 // counts as being in the foreground for OOM killer purposes. 14747 // It's placed in a sched group based on the nature of the 14748 // broadcast as reflected by which queue it's active in. 14749 adj = ProcessList.FOREGROUND_APP_ADJ; 14750 schedGroup = (queue == mFgBroadcastQueue) 14751 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14752 app.adjType = "broadcast"; 14753 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14754 } else if (app.executingServices.size() > 0) { 14755 // An app that is currently executing a service callback also 14756 // counts as being in the foreground. 14757 adj = ProcessList.FOREGROUND_APP_ADJ; 14758 schedGroup = app.execServicesFg ? 14759 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14760 app.adjType = "exec-service"; 14761 procState = ActivityManager.PROCESS_STATE_SERVICE; 14762 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14763 } else { 14764 // As far as we know the process is empty. We may change our mind later. 14765 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14766 // At this point we don't actually know the adjustment. Use the cached adj 14767 // value that the caller wants us to. 14768 adj = cachedAdj; 14769 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14770 app.cached = true; 14771 app.empty = true; 14772 app.adjType = "cch-empty"; 14773 } 14774 14775 // Examine all activities if not already foreground. 14776 if (!foregroundActivities && activitiesSize > 0) { 14777 for (int j = 0; j < activitiesSize; j++) { 14778 final ActivityRecord r = app.activities.get(j); 14779 if (r.app != app) { 14780 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14781 + app + "?!?"); 14782 continue; 14783 } 14784 if (r.visible) { 14785 // App has a visible activity; only upgrade adjustment. 14786 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14787 adj = ProcessList.VISIBLE_APP_ADJ; 14788 app.adjType = "visible"; 14789 } 14790 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14791 procState = ActivityManager.PROCESS_STATE_TOP; 14792 } 14793 schedGroup = Process.THREAD_GROUP_DEFAULT; 14794 app.cached = false; 14795 app.empty = false; 14796 foregroundActivities = true; 14797 break; 14798 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14799 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14800 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14801 app.adjType = "pausing"; 14802 } 14803 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14804 procState = ActivityManager.PROCESS_STATE_TOP; 14805 } 14806 schedGroup = Process.THREAD_GROUP_DEFAULT; 14807 app.cached = false; 14808 app.empty = false; 14809 foregroundActivities = true; 14810 } else if (r.state == ActivityState.STOPPING) { 14811 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14812 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14813 app.adjType = "stopping"; 14814 } 14815 // For the process state, we will at this point consider the 14816 // process to be cached. It will be cached either as an activity 14817 // or empty depending on whether the activity is finishing. We do 14818 // this so that we can treat the process as cached for purposes of 14819 // memory trimming (determing current memory level, trim command to 14820 // send to process) since there can be an arbitrary number of stopping 14821 // processes and they should soon all go into the cached state. 14822 if (!r.finishing) { 14823 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14824 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14825 } 14826 } 14827 app.cached = false; 14828 app.empty = false; 14829 foregroundActivities = true; 14830 } else { 14831 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14832 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14833 app.adjType = "cch-act"; 14834 } 14835 } 14836 } 14837 } 14838 14839 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14840 if (app.foregroundServices) { 14841 // The user is aware of this app, so make it visible. 14842 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14843 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14844 app.cached = false; 14845 app.adjType = "fg-service"; 14846 schedGroup = Process.THREAD_GROUP_DEFAULT; 14847 } else if (app.forcingToForeground != null) { 14848 // The user is aware of this app, so make it visible. 14849 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14850 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14851 app.cached = false; 14852 app.adjType = "force-fg"; 14853 app.adjSource = app.forcingToForeground; 14854 schedGroup = Process.THREAD_GROUP_DEFAULT; 14855 } 14856 } 14857 14858 if (app.foregroundServices) { 14859 interesting = true; 14860 } 14861 14862 if (app == mHeavyWeightProcess) { 14863 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14864 // We don't want to kill the current heavy-weight process. 14865 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14866 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14867 app.cached = false; 14868 app.adjType = "heavy"; 14869 } 14870 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14871 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14872 } 14873 } 14874 14875 if (app == mHomeProcess) { 14876 if (adj > ProcessList.HOME_APP_ADJ) { 14877 // This process is hosting what we currently consider to be the 14878 // home app, so we don't want to let it go into the background. 14879 adj = ProcessList.HOME_APP_ADJ; 14880 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14881 app.cached = false; 14882 app.adjType = "home"; 14883 } 14884 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14885 procState = ActivityManager.PROCESS_STATE_HOME; 14886 } 14887 } 14888 14889 if (app == mPreviousProcess && app.activities.size() > 0) { 14890 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14891 // This was the previous process that showed UI to the user. 14892 // We want to try to keep it around more aggressively, to give 14893 // a good experience around switching between two apps. 14894 adj = ProcessList.PREVIOUS_APP_ADJ; 14895 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14896 app.cached = false; 14897 app.adjType = "previous"; 14898 } 14899 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14900 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14901 } 14902 } 14903 14904 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14905 + " reason=" + app.adjType); 14906 14907 // By default, we use the computed adjustment. It may be changed if 14908 // there are applications dependent on our services or providers, but 14909 // this gives us a baseline and makes sure we don't get into an 14910 // infinite recursion. 14911 app.adjSeq = mAdjSeq; 14912 app.curRawAdj = adj; 14913 app.hasStartedServices = false; 14914 14915 if (mBackupTarget != null && app == mBackupTarget.app) { 14916 // If possible we want to avoid killing apps while they're being backed up 14917 if (adj > ProcessList.BACKUP_APP_ADJ) { 14918 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14919 adj = ProcessList.BACKUP_APP_ADJ; 14920 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14921 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14922 } 14923 app.adjType = "backup"; 14924 app.cached = false; 14925 } 14926 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14927 procState = ActivityManager.PROCESS_STATE_BACKUP; 14928 } 14929 } 14930 14931 boolean mayBeTop = false; 14932 14933 for (int is = app.services.size()-1; 14934 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14935 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14936 || procState > ActivityManager.PROCESS_STATE_TOP); 14937 is--) { 14938 ServiceRecord s = app.services.valueAt(is); 14939 if (s.startRequested) { 14940 app.hasStartedServices = true; 14941 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14942 procState = ActivityManager.PROCESS_STATE_SERVICE; 14943 } 14944 if (app.hasShownUi && app != mHomeProcess) { 14945 // If this process has shown some UI, let it immediately 14946 // go to the LRU list because it may be pretty heavy with 14947 // UI stuff. We'll tag it with a label just to help 14948 // debug and understand what is going on. 14949 if (adj > ProcessList.SERVICE_ADJ) { 14950 app.adjType = "cch-started-ui-services"; 14951 } 14952 } else { 14953 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14954 // This service has seen some activity within 14955 // recent memory, so we will keep its process ahead 14956 // of the background processes. 14957 if (adj > ProcessList.SERVICE_ADJ) { 14958 adj = ProcessList.SERVICE_ADJ; 14959 app.adjType = "started-services"; 14960 app.cached = false; 14961 } 14962 } 14963 // If we have let the service slide into the background 14964 // state, still have some text describing what it is doing 14965 // even though the service no longer has an impact. 14966 if (adj > ProcessList.SERVICE_ADJ) { 14967 app.adjType = "cch-started-services"; 14968 } 14969 } 14970 // Don't kill this process because it is doing work; it 14971 // has said it is doing work. 14972 app.keeping = true; 14973 } 14974 for (int conni = s.connections.size()-1; 14975 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14976 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14977 || procState > ActivityManager.PROCESS_STATE_TOP); 14978 conni--) { 14979 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14980 for (int i = 0; 14981 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14982 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14983 || procState > ActivityManager.PROCESS_STATE_TOP); 14984 i++) { 14985 // XXX should compute this based on the max of 14986 // all connected clients. 14987 ConnectionRecord cr = clist.get(i); 14988 if (cr.binding.client == app) { 14989 // Binding to ourself is not interesting. 14990 continue; 14991 } 14992 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14993 ProcessRecord client = cr.binding.client; 14994 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14995 TOP_APP, doingAll, now); 14996 int clientProcState = client.curProcState; 14997 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14998 // If the other app is cached for any reason, for purposes here 14999 // we are going to consider it empty. The specific cached state 15000 // doesn't propagate except under certain conditions. 15001 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15002 } 15003 String adjType = null; 15004 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 15005 // Not doing bind OOM management, so treat 15006 // this guy more like a started service. 15007 if (app.hasShownUi && app != mHomeProcess) { 15008 // If this process has shown some UI, let it immediately 15009 // go to the LRU list because it may be pretty heavy with 15010 // UI stuff. We'll tag it with a label just to help 15011 // debug and understand what is going on. 15012 if (adj > clientAdj) { 15013 adjType = "cch-bound-ui-services"; 15014 } 15015 app.cached = false; 15016 clientAdj = adj; 15017 clientProcState = procState; 15018 } else { 15019 if (now >= (s.lastActivity 15020 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15021 // This service has not seen activity within 15022 // recent memory, so allow it to drop to the 15023 // LRU list if there is no other reason to keep 15024 // it around. We'll also tag it with a label just 15025 // to help debug and undertand what is going on. 15026 if (adj > clientAdj) { 15027 adjType = "cch-bound-services"; 15028 } 15029 clientAdj = adj; 15030 } 15031 } 15032 } 15033 if (adj > clientAdj) { 15034 // If this process has recently shown UI, and 15035 // the process that is binding to it is less 15036 // important than being visible, then we don't 15037 // care about the binding as much as we care 15038 // about letting this process get into the LRU 15039 // list to be killed and restarted if needed for 15040 // memory. 15041 if (app.hasShownUi && app != mHomeProcess 15042 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15043 adjType = "cch-bound-ui-services"; 15044 } else { 15045 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15046 |Context.BIND_IMPORTANT)) != 0) { 15047 adj = clientAdj; 15048 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15049 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15050 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15051 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15052 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15053 adj = clientAdj; 15054 } else { 15055 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15056 adj = ProcessList.VISIBLE_APP_ADJ; 15057 } 15058 } 15059 if (!client.cached) { 15060 app.cached = false; 15061 } 15062 if (client.keeping) { 15063 app.keeping = true; 15064 } 15065 adjType = "service"; 15066 } 15067 } 15068 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15069 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15070 schedGroup = Process.THREAD_GROUP_DEFAULT; 15071 } 15072 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15073 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15074 // Special handling of clients who are in the top state. 15075 // We *may* want to consider this process to be in the 15076 // top state as well, but only if there is not another 15077 // reason for it to be running. Being on the top is a 15078 // special state, meaning you are specifically running 15079 // for the current top app. If the process is already 15080 // running in the background for some other reason, it 15081 // is more important to continue considering it to be 15082 // in the background state. 15083 mayBeTop = true; 15084 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15085 } else { 15086 // Special handling for above-top states (persistent 15087 // processes). These should not bring the current process 15088 // into the top state, since they are not on top. Instead 15089 // give them the best state after that. 15090 clientProcState = 15091 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15092 } 15093 } 15094 } else { 15095 if (clientProcState < 15096 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15097 clientProcState = 15098 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15099 } 15100 } 15101 if (procState > clientProcState) { 15102 procState = clientProcState; 15103 } 15104 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15105 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15106 app.pendingUiClean = true; 15107 } 15108 if (adjType != null) { 15109 app.adjType = adjType; 15110 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15111 .REASON_SERVICE_IN_USE; 15112 app.adjSource = cr.binding.client; 15113 app.adjSourceOom = clientAdj; 15114 app.adjTarget = s.name; 15115 } 15116 } 15117 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15118 app.treatLikeActivity = true; 15119 } 15120 final ActivityRecord a = cr.activity; 15121 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15122 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15123 (a.visible || a.state == ActivityState.RESUMED 15124 || a.state == ActivityState.PAUSING)) { 15125 adj = ProcessList.FOREGROUND_APP_ADJ; 15126 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15127 schedGroup = Process.THREAD_GROUP_DEFAULT; 15128 } 15129 app.cached = false; 15130 app.adjType = "service"; 15131 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15132 .REASON_SERVICE_IN_USE; 15133 app.adjSource = a; 15134 app.adjSourceOom = adj; 15135 app.adjTarget = s.name; 15136 } 15137 } 15138 } 15139 } 15140 } 15141 15142 for (int provi = app.pubProviders.size()-1; 15143 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15144 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15145 || procState > ActivityManager.PROCESS_STATE_TOP); 15146 provi--) { 15147 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15148 for (int i = cpr.connections.size()-1; 15149 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15150 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15151 || procState > ActivityManager.PROCESS_STATE_TOP); 15152 i--) { 15153 ContentProviderConnection conn = cpr.connections.get(i); 15154 ProcessRecord client = conn.client; 15155 if (client == app) { 15156 // Being our own client is not interesting. 15157 continue; 15158 } 15159 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15160 int clientProcState = client.curProcState; 15161 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15162 // If the other app is cached for any reason, for purposes here 15163 // we are going to consider it empty. 15164 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15165 } 15166 if (adj > clientAdj) { 15167 if (app.hasShownUi && app != mHomeProcess 15168 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15169 app.adjType = "cch-ui-provider"; 15170 } else { 15171 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15172 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15173 app.adjType = "provider"; 15174 } 15175 app.cached &= client.cached; 15176 app.keeping |= client.keeping; 15177 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15178 .REASON_PROVIDER_IN_USE; 15179 app.adjSource = client; 15180 app.adjSourceOom = clientAdj; 15181 app.adjTarget = cpr.name; 15182 } 15183 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15184 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15185 // Special handling of clients who are in the top state. 15186 // We *may* want to consider this process to be in the 15187 // top state as well, but only if there is not another 15188 // reason for it to be running. Being on the top is a 15189 // special state, meaning you are specifically running 15190 // for the current top app. If the process is already 15191 // running in the background for some other reason, it 15192 // is more important to continue considering it to be 15193 // in the background state. 15194 mayBeTop = true; 15195 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15196 } else { 15197 // Special handling for above-top states (persistent 15198 // processes). These should not bring the current process 15199 // into the top state, since they are not on top. Instead 15200 // give them the best state after that. 15201 clientProcState = 15202 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15203 } 15204 } 15205 if (procState > clientProcState) { 15206 procState = clientProcState; 15207 } 15208 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15209 schedGroup = Process.THREAD_GROUP_DEFAULT; 15210 } 15211 } 15212 // If the provider has external (non-framework) process 15213 // dependencies, ensure that its adjustment is at least 15214 // FOREGROUND_APP_ADJ. 15215 if (cpr.hasExternalProcessHandles()) { 15216 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15217 adj = ProcessList.FOREGROUND_APP_ADJ; 15218 schedGroup = Process.THREAD_GROUP_DEFAULT; 15219 app.cached = false; 15220 app.keeping = true; 15221 app.adjType = "provider"; 15222 app.adjTarget = cpr.name; 15223 } 15224 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15225 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15226 } 15227 } 15228 } 15229 15230 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15231 // A client of one of our services or providers is in the top state. We 15232 // *may* want to be in the top state, but not if we are already running in 15233 // the background for some other reason. For the decision here, we are going 15234 // to pick out a few specific states that we want to remain in when a client 15235 // is top (states that tend to be longer-term) and otherwise allow it to go 15236 // to the top state. 15237 switch (procState) { 15238 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15239 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15240 case ActivityManager.PROCESS_STATE_SERVICE: 15241 // These all are longer-term states, so pull them up to the top 15242 // of the background states, but not all the way to the top state. 15243 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15244 break; 15245 default: 15246 // Otherwise, top is a better choice, so take it. 15247 procState = ActivityManager.PROCESS_STATE_TOP; 15248 break; 15249 } 15250 } 15251 15252 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15253 if (app.hasClientActivities) { 15254 // This is a cached process, but with client activities. Mark it so. 15255 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15256 app.adjType = "cch-client-act"; 15257 } else if (app.treatLikeActivity) { 15258 // This is a cached process, but somebody wants us to treat it like it has 15259 // an activity, okay! 15260 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15261 app.adjType = "cch-as-act"; 15262 } 15263 } 15264 15265 if (adj == ProcessList.SERVICE_ADJ) { 15266 if (doingAll) { 15267 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15268 mNewNumServiceProcs++; 15269 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15270 if (!app.serviceb) { 15271 // This service isn't far enough down on the LRU list to 15272 // normally be a B service, but if we are low on RAM and it 15273 // is large we want to force it down since we would prefer to 15274 // keep launcher over it. 15275 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15276 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15277 app.serviceHighRam = true; 15278 app.serviceb = true; 15279 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15280 } else { 15281 mNewNumAServiceProcs++; 15282 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15283 } 15284 } else { 15285 app.serviceHighRam = false; 15286 } 15287 } 15288 if (app.serviceb) { 15289 adj = ProcessList.SERVICE_B_ADJ; 15290 } 15291 } 15292 15293 app.curRawAdj = adj; 15294 15295 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15296 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15297 if (adj > app.maxAdj) { 15298 adj = app.maxAdj; 15299 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15300 schedGroup = Process.THREAD_GROUP_DEFAULT; 15301 } 15302 } 15303 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15304 app.keeping = true; 15305 } 15306 15307 // Do final modification to adj. Everything we do between here and applying 15308 // the final setAdj must be done in this function, because we will also use 15309 // it when computing the final cached adj later. Note that we don't need to 15310 // worry about this for max adj above, since max adj will always be used to 15311 // keep it out of the cached vaues. 15312 app.curAdj = app.modifyRawOomAdj(adj); 15313 app.curSchedGroup = schedGroup; 15314 app.curProcState = procState; 15315 app.foregroundActivities = foregroundActivities; 15316 15317 return app.curRawAdj; 15318 } 15319 15320 /** 15321 * Schedule PSS collection of a process. 15322 */ 15323 void requestPssLocked(ProcessRecord proc, int procState) { 15324 if (mPendingPssProcesses.contains(proc)) { 15325 return; 15326 } 15327 if (mPendingPssProcesses.size() == 0) { 15328 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15329 } 15330 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15331 proc.pssProcState = procState; 15332 mPendingPssProcesses.add(proc); 15333 } 15334 15335 /** 15336 * Schedule PSS collection of all processes. 15337 */ 15338 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15339 if (!always) { 15340 if (now < (mLastFullPssTime + 15341 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15342 return; 15343 } 15344 } 15345 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15346 mLastFullPssTime = now; 15347 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15348 mPendingPssProcesses.clear(); 15349 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15350 ProcessRecord app = mLruProcesses.get(i); 15351 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15352 app.pssProcState = app.setProcState; 15353 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15354 isSleeping(), now); 15355 mPendingPssProcesses.add(app); 15356 } 15357 } 15358 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15359 } 15360 15361 /** 15362 * Ask a given process to GC right now. 15363 */ 15364 final void performAppGcLocked(ProcessRecord app) { 15365 try { 15366 app.lastRequestedGc = SystemClock.uptimeMillis(); 15367 if (app.thread != null) { 15368 if (app.reportLowMemory) { 15369 app.reportLowMemory = false; 15370 app.thread.scheduleLowMemory(); 15371 } else { 15372 app.thread.processInBackground(); 15373 } 15374 } 15375 } catch (Exception e) { 15376 // whatever. 15377 } 15378 } 15379 15380 /** 15381 * Returns true if things are idle enough to perform GCs. 15382 */ 15383 private final boolean canGcNowLocked() { 15384 boolean processingBroadcasts = false; 15385 for (BroadcastQueue q : mBroadcastQueues) { 15386 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15387 processingBroadcasts = true; 15388 } 15389 } 15390 return !processingBroadcasts 15391 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15392 } 15393 15394 /** 15395 * Perform GCs on all processes that are waiting for it, but only 15396 * if things are idle. 15397 */ 15398 final void performAppGcsLocked() { 15399 final int N = mProcessesToGc.size(); 15400 if (N <= 0) { 15401 return; 15402 } 15403 if (canGcNowLocked()) { 15404 while (mProcessesToGc.size() > 0) { 15405 ProcessRecord proc = mProcessesToGc.remove(0); 15406 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15407 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15408 <= SystemClock.uptimeMillis()) { 15409 // To avoid spamming the system, we will GC processes one 15410 // at a time, waiting a few seconds between each. 15411 performAppGcLocked(proc); 15412 scheduleAppGcsLocked(); 15413 return; 15414 } else { 15415 // It hasn't been long enough since we last GCed this 15416 // process... put it in the list to wait for its time. 15417 addProcessToGcListLocked(proc); 15418 break; 15419 } 15420 } 15421 } 15422 15423 scheduleAppGcsLocked(); 15424 } 15425 } 15426 15427 /** 15428 * If all looks good, perform GCs on all processes waiting for them. 15429 */ 15430 final void performAppGcsIfAppropriateLocked() { 15431 if (canGcNowLocked()) { 15432 performAppGcsLocked(); 15433 return; 15434 } 15435 // Still not idle, wait some more. 15436 scheduleAppGcsLocked(); 15437 } 15438 15439 /** 15440 * Schedule the execution of all pending app GCs. 15441 */ 15442 final void scheduleAppGcsLocked() { 15443 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15444 15445 if (mProcessesToGc.size() > 0) { 15446 // Schedule a GC for the time to the next process. 15447 ProcessRecord proc = mProcessesToGc.get(0); 15448 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15449 15450 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15451 long now = SystemClock.uptimeMillis(); 15452 if (when < (now+GC_TIMEOUT)) { 15453 when = now + GC_TIMEOUT; 15454 } 15455 mHandler.sendMessageAtTime(msg, when); 15456 } 15457 } 15458 15459 /** 15460 * Add a process to the array of processes waiting to be GCed. Keeps the 15461 * list in sorted order by the last GC time. The process can't already be 15462 * on the list. 15463 */ 15464 final void addProcessToGcListLocked(ProcessRecord proc) { 15465 boolean added = false; 15466 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15467 if (mProcessesToGc.get(i).lastRequestedGc < 15468 proc.lastRequestedGc) { 15469 added = true; 15470 mProcessesToGc.add(i+1, proc); 15471 break; 15472 } 15473 } 15474 if (!added) { 15475 mProcessesToGc.add(0, proc); 15476 } 15477 } 15478 15479 /** 15480 * Set up to ask a process to GC itself. This will either do it 15481 * immediately, or put it on the list of processes to gc the next 15482 * time things are idle. 15483 */ 15484 final void scheduleAppGcLocked(ProcessRecord app) { 15485 long now = SystemClock.uptimeMillis(); 15486 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15487 return; 15488 } 15489 if (!mProcessesToGc.contains(app)) { 15490 addProcessToGcListLocked(app); 15491 scheduleAppGcsLocked(); 15492 } 15493 } 15494 15495 final void checkExcessivePowerUsageLocked(boolean doKills) { 15496 updateCpuStatsNow(); 15497 15498 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15499 boolean doWakeKills = doKills; 15500 boolean doCpuKills = doKills; 15501 if (mLastPowerCheckRealtime == 0) { 15502 doWakeKills = false; 15503 } 15504 if (mLastPowerCheckUptime == 0) { 15505 doCpuKills = false; 15506 } 15507 if (stats.isScreenOn()) { 15508 doWakeKills = false; 15509 } 15510 final long curRealtime = SystemClock.elapsedRealtime(); 15511 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15512 final long curUptime = SystemClock.uptimeMillis(); 15513 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15514 mLastPowerCheckRealtime = curRealtime; 15515 mLastPowerCheckUptime = curUptime; 15516 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15517 doWakeKills = false; 15518 } 15519 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15520 doCpuKills = false; 15521 } 15522 int i = mLruProcesses.size(); 15523 while (i > 0) { 15524 i--; 15525 ProcessRecord app = mLruProcesses.get(i); 15526 if (!app.keeping) { 15527 long wtime; 15528 synchronized (stats) { 15529 wtime = stats.getProcessWakeTime(app.info.uid, 15530 app.pid, curRealtime); 15531 } 15532 long wtimeUsed = wtime - app.lastWakeTime; 15533 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15534 if (DEBUG_POWER) { 15535 StringBuilder sb = new StringBuilder(128); 15536 sb.append("Wake for "); 15537 app.toShortString(sb); 15538 sb.append(": over "); 15539 TimeUtils.formatDuration(realtimeSince, sb); 15540 sb.append(" used "); 15541 TimeUtils.formatDuration(wtimeUsed, sb); 15542 sb.append(" ("); 15543 sb.append((wtimeUsed*100)/realtimeSince); 15544 sb.append("%)"); 15545 Slog.i(TAG, sb.toString()); 15546 sb.setLength(0); 15547 sb.append("CPU for "); 15548 app.toShortString(sb); 15549 sb.append(": over "); 15550 TimeUtils.formatDuration(uptimeSince, sb); 15551 sb.append(" used "); 15552 TimeUtils.formatDuration(cputimeUsed, sb); 15553 sb.append(" ("); 15554 sb.append((cputimeUsed*100)/uptimeSince); 15555 sb.append("%)"); 15556 Slog.i(TAG, sb.toString()); 15557 } 15558 // If a process has held a wake lock for more 15559 // than 50% of the time during this period, 15560 // that sounds bad. Kill! 15561 if (doWakeKills && realtimeSince > 0 15562 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15563 synchronized (stats) { 15564 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15565 realtimeSince, wtimeUsed); 15566 } 15567 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15568 + " during " + realtimeSince); 15569 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15570 } else if (doCpuKills && uptimeSince > 0 15571 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15572 synchronized (stats) { 15573 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15574 uptimeSince, cputimeUsed); 15575 } 15576 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15577 + " during " + uptimeSince); 15578 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15579 } else { 15580 app.lastWakeTime = wtime; 15581 app.lastCpuTime = app.curCpuTime; 15582 } 15583 } 15584 } 15585 } 15586 15587 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15588 ProcessRecord TOP_APP, boolean doingAll, long now) { 15589 boolean success = true; 15590 15591 if (app.curRawAdj != app.setRawAdj) { 15592 if (wasKeeping && !app.keeping) { 15593 // This app is no longer something we want to keep. Note 15594 // its current wake lock time to later know to kill it if 15595 // it is not behaving well. 15596 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15597 synchronized (stats) { 15598 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15599 app.pid, SystemClock.elapsedRealtime()); 15600 } 15601 app.lastCpuTime = app.curCpuTime; 15602 } 15603 15604 app.setRawAdj = app.curRawAdj; 15605 } 15606 15607 int changes = 0; 15608 15609 if (app.curAdj != app.setAdj) { 15610 ProcessList.setOomAdj(app.pid, app.curAdj); 15611 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15612 TAG, "Set " + app.pid + " " + app.processName + 15613 " adj " + app.curAdj + ": " + app.adjType); 15614 app.setAdj = app.curAdj; 15615 } 15616 15617 if (app.setSchedGroup != app.curSchedGroup) { 15618 app.setSchedGroup = app.curSchedGroup; 15619 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15620 "Setting process group of " + app.processName 15621 + " to " + app.curSchedGroup); 15622 if (app.waitingToKill != null && 15623 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15624 killUnneededProcessLocked(app, app.waitingToKill); 15625 success = false; 15626 } else { 15627 if (true) { 15628 long oldId = Binder.clearCallingIdentity(); 15629 try { 15630 Process.setProcessGroup(app.pid, app.curSchedGroup); 15631 } catch (Exception e) { 15632 Slog.w(TAG, "Failed setting process group of " + app.pid 15633 + " to " + app.curSchedGroup); 15634 e.printStackTrace(); 15635 } finally { 15636 Binder.restoreCallingIdentity(oldId); 15637 } 15638 } else { 15639 if (app.thread != null) { 15640 try { 15641 app.thread.setSchedulingGroup(app.curSchedGroup); 15642 } catch (RemoteException e) { 15643 } 15644 } 15645 } 15646 Process.setSwappiness(app.pid, 15647 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15648 } 15649 } 15650 if (app.repForegroundActivities != app.foregroundActivities) { 15651 app.repForegroundActivities = app.foregroundActivities; 15652 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15653 } 15654 if (app.repProcState != app.curProcState) { 15655 app.repProcState = app.curProcState; 15656 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15657 if (app.thread != null) { 15658 try { 15659 if (false) { 15660 //RuntimeException h = new RuntimeException("here"); 15661 Slog.i(TAG, "Sending new process state " + app.repProcState 15662 + " to " + app /*, h*/); 15663 } 15664 app.thread.setProcessState(app.repProcState); 15665 } catch (RemoteException e) { 15666 } 15667 } 15668 } 15669 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15670 app.setProcState)) { 15671 app.lastStateTime = now; 15672 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15673 isSleeping(), now); 15674 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15675 + ProcessList.makeProcStateString(app.setProcState) + " to " 15676 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15677 + (app.nextPssTime-now) + ": " + app); 15678 } else { 15679 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15680 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15681 requestPssLocked(app, app.setProcState); 15682 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15683 isSleeping(), now); 15684 } else if (false && DEBUG_PSS) { 15685 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15686 } 15687 } 15688 if (app.setProcState != app.curProcState) { 15689 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15690 "Proc state change of " + app.processName 15691 + " to " + app.curProcState); 15692 app.setProcState = app.curProcState; 15693 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15694 app.notCachedSinceIdle = false; 15695 } 15696 if (!doingAll) { 15697 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15698 } else { 15699 app.procStateChanged = true; 15700 } 15701 } 15702 15703 if (changes != 0) { 15704 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15705 int i = mPendingProcessChanges.size()-1; 15706 ProcessChangeItem item = null; 15707 while (i >= 0) { 15708 item = mPendingProcessChanges.get(i); 15709 if (item.pid == app.pid) { 15710 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15711 break; 15712 } 15713 i--; 15714 } 15715 if (i < 0) { 15716 // No existing item in pending changes; need a new one. 15717 final int NA = mAvailProcessChanges.size(); 15718 if (NA > 0) { 15719 item = mAvailProcessChanges.remove(NA-1); 15720 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15721 } else { 15722 item = new ProcessChangeItem(); 15723 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15724 } 15725 item.changes = 0; 15726 item.pid = app.pid; 15727 item.uid = app.info.uid; 15728 if (mPendingProcessChanges.size() == 0) { 15729 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15730 "*** Enqueueing dispatch processes changed!"); 15731 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15732 } 15733 mPendingProcessChanges.add(item); 15734 } 15735 item.changes |= changes; 15736 item.processState = app.repProcState; 15737 item.foregroundActivities = app.repForegroundActivities; 15738 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15739 + Integer.toHexString(System.identityHashCode(item)) 15740 + " " + app.toShortString() + ": changes=" + item.changes 15741 + " procState=" + item.processState 15742 + " foreground=" + item.foregroundActivities 15743 + " type=" + app.adjType + " source=" + app.adjSource 15744 + " target=" + app.adjTarget); 15745 } 15746 15747 return success; 15748 } 15749 15750 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15751 if (proc.thread != null && proc.baseProcessTracker != null) { 15752 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15753 } 15754 } 15755 15756 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15757 ProcessRecord TOP_APP, boolean doingAll, long now) { 15758 if (app.thread == null) { 15759 return false; 15760 } 15761 15762 final boolean wasKeeping = app.keeping; 15763 15764 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15765 15766 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 15767 } 15768 15769 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15770 boolean oomAdj) { 15771 if (isForeground != proc.foregroundServices) { 15772 proc.foregroundServices = isForeground; 15773 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15774 proc.info.uid); 15775 if (isForeground) { 15776 if (curProcs == null) { 15777 curProcs = new ArrayList<ProcessRecord>(); 15778 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15779 } 15780 if (!curProcs.contains(proc)) { 15781 curProcs.add(proc); 15782 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15783 proc.info.packageName, proc.info.uid); 15784 } 15785 } else { 15786 if (curProcs != null) { 15787 if (curProcs.remove(proc)) { 15788 mBatteryStatsService.noteEvent( 15789 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15790 proc.info.packageName, proc.info.uid); 15791 if (curProcs.size() <= 0) { 15792 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15793 } 15794 } 15795 } 15796 } 15797 if (oomAdj) { 15798 updateOomAdjLocked(); 15799 } 15800 } 15801 } 15802 15803 private final ActivityRecord resumedAppLocked() { 15804 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15805 String pkg; 15806 int uid; 15807 if (act != null && !act.sleeping) { 15808 pkg = act.packageName; 15809 uid = act.info.applicationInfo.uid; 15810 } else { 15811 pkg = null; 15812 uid = -1; 15813 } 15814 // Has the UID or resumed package name changed? 15815 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15816 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15817 if (mCurResumedPackage != null) { 15818 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15819 mCurResumedPackage, mCurResumedUid); 15820 } 15821 mCurResumedPackage = pkg; 15822 mCurResumedUid = uid; 15823 if (mCurResumedPackage != null) { 15824 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15825 mCurResumedPackage, mCurResumedUid); 15826 } 15827 } 15828 return act; 15829 } 15830 15831 final boolean updateOomAdjLocked(ProcessRecord app) { 15832 final ActivityRecord TOP_ACT = resumedAppLocked(); 15833 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15834 final boolean wasCached = app.cached; 15835 15836 mAdjSeq++; 15837 15838 // This is the desired cached adjusment we want to tell it to use. 15839 // If our app is currently cached, we know it, and that is it. Otherwise, 15840 // we don't know it yet, and it needs to now be cached we will then 15841 // need to do a complete oom adj. 15842 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15843 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15844 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 15845 SystemClock.uptimeMillis()); 15846 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15847 // Changed to/from cached state, so apps after it in the LRU 15848 // list may also be changed. 15849 updateOomAdjLocked(); 15850 } 15851 return success; 15852 } 15853 15854 final void updateOomAdjLocked() { 15855 final ActivityRecord TOP_ACT = resumedAppLocked(); 15856 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15857 final long now = SystemClock.uptimeMillis(); 15858 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15859 final int N = mLruProcesses.size(); 15860 15861 if (false) { 15862 RuntimeException e = new RuntimeException(); 15863 e.fillInStackTrace(); 15864 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15865 } 15866 15867 mAdjSeq++; 15868 mNewNumServiceProcs = 0; 15869 mNewNumAServiceProcs = 0; 15870 15871 final int emptyProcessLimit; 15872 final int cachedProcessLimit; 15873 if (mProcessLimit <= 0) { 15874 emptyProcessLimit = cachedProcessLimit = 0; 15875 } else if (mProcessLimit == 1) { 15876 emptyProcessLimit = 1; 15877 cachedProcessLimit = 0; 15878 } else { 15879 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15880 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15881 } 15882 15883 // Let's determine how many processes we have running vs. 15884 // how many slots we have for background processes; we may want 15885 // to put multiple processes in a slot of there are enough of 15886 // them. 15887 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15888 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15889 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15890 if (numEmptyProcs > cachedProcessLimit) { 15891 // If there are more empty processes than our limit on cached 15892 // processes, then use the cached process limit for the factor. 15893 // This ensures that the really old empty processes get pushed 15894 // down to the bottom, so if we are running low on memory we will 15895 // have a better chance at keeping around more cached processes 15896 // instead of a gazillion empty processes. 15897 numEmptyProcs = cachedProcessLimit; 15898 } 15899 int emptyFactor = numEmptyProcs/numSlots; 15900 if (emptyFactor < 1) emptyFactor = 1; 15901 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15902 if (cachedFactor < 1) cachedFactor = 1; 15903 int stepCached = 0; 15904 int stepEmpty = 0; 15905 int numCached = 0; 15906 int numEmpty = 0; 15907 int numTrimming = 0; 15908 15909 mNumNonCachedProcs = 0; 15910 mNumCachedHiddenProcs = 0; 15911 15912 // First update the OOM adjustment for each of the 15913 // application processes based on their current state. 15914 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15915 int nextCachedAdj = curCachedAdj+1; 15916 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15917 int nextEmptyAdj = curEmptyAdj+2; 15918 for (int i=N-1; i>=0; i--) { 15919 ProcessRecord app = mLruProcesses.get(i); 15920 if (!app.killedByAm && app.thread != null) { 15921 app.procStateChanged = false; 15922 final boolean wasKeeping = app.keeping; 15923 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15924 15925 // If we haven't yet assigned the final cached adj 15926 // to the process, do that now. 15927 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15928 switch (app.curProcState) { 15929 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15930 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15931 // This process is a cached process holding activities... 15932 // assign it the next cached value for that type, and then 15933 // step that cached level. 15934 app.curRawAdj = curCachedAdj; 15935 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15936 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15937 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15938 + ")"); 15939 if (curCachedAdj != nextCachedAdj) { 15940 stepCached++; 15941 if (stepCached >= cachedFactor) { 15942 stepCached = 0; 15943 curCachedAdj = nextCachedAdj; 15944 nextCachedAdj += 2; 15945 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15946 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15947 } 15948 } 15949 } 15950 break; 15951 default: 15952 // For everything else, assign next empty cached process 15953 // level and bump that up. Note that this means that 15954 // long-running services that have dropped down to the 15955 // cached level will be treated as empty (since their process 15956 // state is still as a service), which is what we want. 15957 app.curRawAdj = curEmptyAdj; 15958 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15959 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15960 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15961 + ")"); 15962 if (curEmptyAdj != nextEmptyAdj) { 15963 stepEmpty++; 15964 if (stepEmpty >= emptyFactor) { 15965 stepEmpty = 0; 15966 curEmptyAdj = nextEmptyAdj; 15967 nextEmptyAdj += 2; 15968 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15969 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15970 } 15971 } 15972 } 15973 break; 15974 } 15975 } 15976 15977 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 15978 15979 // Count the number of process types. 15980 switch (app.curProcState) { 15981 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15982 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15983 mNumCachedHiddenProcs++; 15984 numCached++; 15985 if (numCached > cachedProcessLimit) { 15986 killUnneededProcessLocked(app, "cached #" + numCached); 15987 } 15988 break; 15989 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15990 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15991 && app.lastActivityTime < oldTime) { 15992 killUnneededProcessLocked(app, "empty for " 15993 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15994 / 1000) + "s"); 15995 } else { 15996 numEmpty++; 15997 if (numEmpty > emptyProcessLimit) { 15998 killUnneededProcessLocked(app, "empty #" + numEmpty); 15999 } 16000 } 16001 break; 16002 default: 16003 mNumNonCachedProcs++; 16004 break; 16005 } 16006 16007 if (app.isolated && app.services.size() <= 0) { 16008 // If this is an isolated process, and there are no 16009 // services running in it, then the process is no longer 16010 // needed. We agressively kill these because we can by 16011 // definition not re-use the same process again, and it is 16012 // good to avoid having whatever code was running in them 16013 // left sitting around after no longer needed. 16014 killUnneededProcessLocked(app, "isolated not needed"); 16015 } 16016 16017 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16018 && !app.killedByAm) { 16019 numTrimming++; 16020 } 16021 } 16022 } 16023 16024 mNumServiceProcs = mNewNumServiceProcs; 16025 16026 // Now determine the memory trimming level of background processes. 16027 // Unfortunately we need to start at the back of the list to do this 16028 // properly. We only do this if the number of background apps we 16029 // are managing to keep around is less than half the maximum we desire; 16030 // if we are keeping a good number around, we'll let them use whatever 16031 // memory they want. 16032 final int numCachedAndEmpty = numCached + numEmpty; 16033 int memFactor; 16034 if (numCached <= ProcessList.TRIM_CACHED_APPS 16035 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16036 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16037 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16038 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16039 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16040 } else { 16041 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16042 } 16043 } else { 16044 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16045 } 16046 // We always allow the memory level to go up (better). We only allow it to go 16047 // down if we are in a state where that is allowed, *and* the total number of processes 16048 // has gone down since last time. 16049 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16050 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16051 + " last=" + mLastNumProcesses); 16052 if (memFactor > mLastMemoryLevel) { 16053 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16054 memFactor = mLastMemoryLevel; 16055 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16056 } 16057 } 16058 mLastMemoryLevel = memFactor; 16059 mLastNumProcesses = mLruProcesses.size(); 16060 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16061 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16062 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16063 if (mLowRamStartTime == 0) { 16064 mLowRamStartTime = now; 16065 } 16066 int step = 0; 16067 int fgTrimLevel; 16068 switch (memFactor) { 16069 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16070 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16071 break; 16072 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16073 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16074 break; 16075 default: 16076 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16077 break; 16078 } 16079 int factor = numTrimming/3; 16080 int minFactor = 2; 16081 if (mHomeProcess != null) minFactor++; 16082 if (mPreviousProcess != null) minFactor++; 16083 if (factor < minFactor) factor = minFactor; 16084 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16085 for (int i=N-1; i>=0; i--) { 16086 ProcessRecord app = mLruProcesses.get(i); 16087 if (allChanged || app.procStateChanged) { 16088 setProcessTrackerState(app, trackerMemFactor, now); 16089 app.procStateChanged = false; 16090 } 16091 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16092 && !app.killedByAm) { 16093 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16094 try { 16095 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16096 "Trimming memory of " + app.processName 16097 + " to " + curLevel); 16098 app.thread.scheduleTrimMemory(curLevel); 16099 } catch (RemoteException e) { 16100 } 16101 if (false) { 16102 // For now we won't do this; our memory trimming seems 16103 // to be good enough at this point that destroying 16104 // activities causes more harm than good. 16105 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16106 && app != mHomeProcess && app != mPreviousProcess) { 16107 // Need to do this on its own message because the stack may not 16108 // be in a consistent state at this point. 16109 // For these apps we will also finish their activities 16110 // to help them free memory. 16111 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16112 } 16113 } 16114 } 16115 app.trimMemoryLevel = curLevel; 16116 step++; 16117 if (step >= factor) { 16118 step = 0; 16119 switch (curLevel) { 16120 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16121 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16122 break; 16123 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16124 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16125 break; 16126 } 16127 } 16128 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16129 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16130 && app.thread != null) { 16131 try { 16132 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16133 "Trimming memory of heavy-weight " + app.processName 16134 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16135 app.thread.scheduleTrimMemory( 16136 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16137 } catch (RemoteException e) { 16138 } 16139 } 16140 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16141 } else { 16142 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16143 || app.systemNoUi) && app.pendingUiClean) { 16144 // If this application is now in the background and it 16145 // had done UI, then give it the special trim level to 16146 // have it free UI resources. 16147 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16148 if (app.trimMemoryLevel < level && app.thread != null) { 16149 try { 16150 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16151 "Trimming memory of bg-ui " + app.processName 16152 + " to " + level); 16153 app.thread.scheduleTrimMemory(level); 16154 } catch (RemoteException e) { 16155 } 16156 } 16157 app.pendingUiClean = false; 16158 } 16159 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16160 try { 16161 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16162 "Trimming memory of fg " + app.processName 16163 + " to " + fgTrimLevel); 16164 app.thread.scheduleTrimMemory(fgTrimLevel); 16165 } catch (RemoteException e) { 16166 } 16167 } 16168 app.trimMemoryLevel = fgTrimLevel; 16169 } 16170 } 16171 } else { 16172 if (mLowRamStartTime != 0) { 16173 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16174 mLowRamStartTime = 0; 16175 } 16176 for (int i=N-1; i>=0; i--) { 16177 ProcessRecord app = mLruProcesses.get(i); 16178 if (allChanged || app.procStateChanged) { 16179 setProcessTrackerState(app, trackerMemFactor, now); 16180 app.procStateChanged = false; 16181 } 16182 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16183 || app.systemNoUi) && app.pendingUiClean) { 16184 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16185 && app.thread != null) { 16186 try { 16187 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16188 "Trimming memory of ui hidden " + app.processName 16189 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16190 app.thread.scheduleTrimMemory( 16191 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16192 } catch (RemoteException e) { 16193 } 16194 } 16195 app.pendingUiClean = false; 16196 } 16197 app.trimMemoryLevel = 0; 16198 } 16199 } 16200 16201 if (mAlwaysFinishActivities) { 16202 // Need to do this on its own message because the stack may not 16203 // be in a consistent state at this point. 16204 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16205 } 16206 16207 if (allChanged) { 16208 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16209 } 16210 16211 if (mProcessStats.shouldWriteNowLocked(now)) { 16212 mHandler.post(new Runnable() { 16213 @Override public void run() { 16214 synchronized (ActivityManagerService.this) { 16215 mProcessStats.writeStateAsyncLocked(); 16216 } 16217 } 16218 }); 16219 } 16220 16221 if (DEBUG_OOM_ADJ) { 16222 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16223 } 16224 } 16225 16226 final void trimApplications() { 16227 synchronized (this) { 16228 int i; 16229 16230 // First remove any unused application processes whose package 16231 // has been removed. 16232 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16233 final ProcessRecord app = mRemovedProcesses.get(i); 16234 if (app.activities.size() == 0 16235 && app.curReceiver == null && app.services.size() == 0) { 16236 Slog.i( 16237 TAG, "Exiting empty application process " 16238 + app.processName + " (" 16239 + (app.thread != null ? app.thread.asBinder() : null) 16240 + ")\n"); 16241 if (app.pid > 0 && app.pid != MY_PID) { 16242 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16243 app.processName, app.setAdj, "empty"); 16244 app.killedByAm = true; 16245 Process.killProcessQuiet(app.pid); 16246 } else { 16247 try { 16248 app.thread.scheduleExit(); 16249 } catch (Exception e) { 16250 // Ignore exceptions. 16251 } 16252 } 16253 cleanUpApplicationRecordLocked(app, false, true, -1); 16254 mRemovedProcesses.remove(i); 16255 16256 if (app.persistent) { 16257 if (app.persistent) { 16258 addAppLocked(app.info, false); 16259 } 16260 } 16261 } 16262 } 16263 16264 // Now update the oom adj for all processes. 16265 updateOomAdjLocked(); 16266 } 16267 } 16268 16269 /** This method sends the specified signal to each of the persistent apps */ 16270 public void signalPersistentProcesses(int sig) throws RemoteException { 16271 if (sig != Process.SIGNAL_USR1) { 16272 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16273 } 16274 16275 synchronized (this) { 16276 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16277 != PackageManager.PERMISSION_GRANTED) { 16278 throw new SecurityException("Requires permission " 16279 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16280 } 16281 16282 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16283 ProcessRecord r = mLruProcesses.get(i); 16284 if (r.thread != null && r.persistent) { 16285 Process.sendSignal(r.pid, sig); 16286 } 16287 } 16288 } 16289 } 16290 16291 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16292 if (proc == null || proc == mProfileProc) { 16293 proc = mProfileProc; 16294 path = mProfileFile; 16295 profileType = mProfileType; 16296 clearProfilerLocked(); 16297 } 16298 if (proc == null) { 16299 return; 16300 } 16301 try { 16302 proc.thread.profilerControl(false, path, null, profileType); 16303 } catch (RemoteException e) { 16304 throw new IllegalStateException("Process disappeared"); 16305 } 16306 } 16307 16308 private void clearProfilerLocked() { 16309 if (mProfileFd != null) { 16310 try { 16311 mProfileFd.close(); 16312 } catch (IOException e) { 16313 } 16314 } 16315 mProfileApp = null; 16316 mProfileProc = null; 16317 mProfileFile = null; 16318 mProfileType = 0; 16319 mAutoStopProfiler = false; 16320 } 16321 16322 public boolean profileControl(String process, int userId, boolean start, 16323 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16324 16325 try { 16326 synchronized (this) { 16327 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16328 // its own permission. 16329 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16330 != PackageManager.PERMISSION_GRANTED) { 16331 throw new SecurityException("Requires permission " 16332 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16333 } 16334 16335 if (start && fd == null) { 16336 throw new IllegalArgumentException("null fd"); 16337 } 16338 16339 ProcessRecord proc = null; 16340 if (process != null) { 16341 proc = findProcessLocked(process, userId, "profileControl"); 16342 } 16343 16344 if (start && (proc == null || proc.thread == null)) { 16345 throw new IllegalArgumentException("Unknown process: " + process); 16346 } 16347 16348 if (start) { 16349 stopProfilerLocked(null, null, 0); 16350 setProfileApp(proc.info, proc.processName, path, fd, false); 16351 mProfileProc = proc; 16352 mProfileType = profileType; 16353 try { 16354 fd = fd.dup(); 16355 } catch (IOException e) { 16356 fd = null; 16357 } 16358 proc.thread.profilerControl(start, path, fd, profileType); 16359 fd = null; 16360 mProfileFd = null; 16361 } else { 16362 stopProfilerLocked(proc, path, profileType); 16363 if (fd != null) { 16364 try { 16365 fd.close(); 16366 } catch (IOException e) { 16367 } 16368 } 16369 } 16370 16371 return true; 16372 } 16373 } catch (RemoteException e) { 16374 throw new IllegalStateException("Process disappeared"); 16375 } finally { 16376 if (fd != null) { 16377 try { 16378 fd.close(); 16379 } catch (IOException e) { 16380 } 16381 } 16382 } 16383 } 16384 16385 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16386 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16387 userId, true, true, callName, null); 16388 ProcessRecord proc = null; 16389 try { 16390 int pid = Integer.parseInt(process); 16391 synchronized (mPidsSelfLocked) { 16392 proc = mPidsSelfLocked.get(pid); 16393 } 16394 } catch (NumberFormatException e) { 16395 } 16396 16397 if (proc == null) { 16398 ArrayMap<String, SparseArray<ProcessRecord>> all 16399 = mProcessNames.getMap(); 16400 SparseArray<ProcessRecord> procs = all.get(process); 16401 if (procs != null && procs.size() > 0) { 16402 proc = procs.valueAt(0); 16403 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16404 for (int i=1; i<procs.size(); i++) { 16405 ProcessRecord thisProc = procs.valueAt(i); 16406 if (thisProc.userId == userId) { 16407 proc = thisProc; 16408 break; 16409 } 16410 } 16411 } 16412 } 16413 } 16414 16415 return proc; 16416 } 16417 16418 public boolean dumpHeap(String process, int userId, boolean managed, 16419 String path, ParcelFileDescriptor fd) throws RemoteException { 16420 16421 try { 16422 synchronized (this) { 16423 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16424 // its own permission (same as profileControl). 16425 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16426 != PackageManager.PERMISSION_GRANTED) { 16427 throw new SecurityException("Requires permission " 16428 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16429 } 16430 16431 if (fd == null) { 16432 throw new IllegalArgumentException("null fd"); 16433 } 16434 16435 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16436 if (proc == null || proc.thread == null) { 16437 throw new IllegalArgumentException("Unknown process: " + process); 16438 } 16439 16440 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16441 if (!isDebuggable) { 16442 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16443 throw new SecurityException("Process not debuggable: " + proc); 16444 } 16445 } 16446 16447 proc.thread.dumpHeap(managed, path, fd); 16448 fd = null; 16449 return true; 16450 } 16451 } catch (RemoteException e) { 16452 throw new IllegalStateException("Process disappeared"); 16453 } finally { 16454 if (fd != null) { 16455 try { 16456 fd.close(); 16457 } catch (IOException e) { 16458 } 16459 } 16460 } 16461 } 16462 16463 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16464 public void monitor() { 16465 synchronized (this) { } 16466 } 16467 16468 void onCoreSettingsChange(Bundle settings) { 16469 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16470 ProcessRecord processRecord = mLruProcesses.get(i); 16471 try { 16472 if (processRecord.thread != null) { 16473 processRecord.thread.setCoreSettings(settings); 16474 } 16475 } catch (RemoteException re) { 16476 /* ignore */ 16477 } 16478 } 16479 } 16480 16481 // Multi-user methods 16482 16483 /** 16484 * Start user, if its not already running, but don't bring it to foreground. 16485 */ 16486 @Override 16487 public boolean startUserInBackground(final int userId) { 16488 return startUser(userId, /* foreground */ false); 16489 } 16490 16491 /** 16492 * Refreshes the list of users related to the current user when either a 16493 * user switch happens or when a new related user is started in the 16494 * background. 16495 */ 16496 private void updateCurrentProfileIdsLocked() { 16497 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16498 mCurrentUserId, false /* enabledOnly */); 16499 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16500 for (int i = 0; i < currentProfileIds.length; i++) { 16501 currentProfileIds[i] = profiles.get(i).id; 16502 } 16503 mCurrentProfileIds = currentProfileIds; 16504 } 16505 16506 private Set getProfileIdsLocked(int userId) { 16507 Set userIds = new HashSet<Integer>(); 16508 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16509 userId, false /* enabledOnly */); 16510 for (UserInfo user : profiles) { 16511 userIds.add(Integer.valueOf(user.id)); 16512 } 16513 return userIds; 16514 } 16515 16516 @Override 16517 public boolean switchUser(final int userId) { 16518 return startUser(userId, /* foregound */ true); 16519 } 16520 16521 private boolean startUser(final int userId, boolean foreground) { 16522 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16523 != PackageManager.PERMISSION_GRANTED) { 16524 String msg = "Permission Denial: switchUser() from pid=" 16525 + Binder.getCallingPid() 16526 + ", uid=" + Binder.getCallingUid() 16527 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16528 Slog.w(TAG, msg); 16529 throw new SecurityException(msg); 16530 } 16531 16532 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16533 16534 final long ident = Binder.clearCallingIdentity(); 16535 try { 16536 synchronized (this) { 16537 final int oldUserId = mCurrentUserId; 16538 if (oldUserId == userId) { 16539 return true; 16540 } 16541 16542 mStackSupervisor.setLockTaskModeLocked(null); 16543 16544 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16545 if (userInfo == null) { 16546 Slog.w(TAG, "No user info for user #" + userId); 16547 return false; 16548 } 16549 16550 if (foreground) { 16551 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16552 R.anim.screen_user_enter); 16553 } 16554 16555 boolean needStart = false; 16556 16557 // If the user we are switching to is not currently started, then 16558 // we need to start it now. 16559 if (mStartedUsers.get(userId) == null) { 16560 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16561 updateStartedUserArrayLocked(); 16562 needStart = true; 16563 } 16564 16565 final Integer userIdInt = Integer.valueOf(userId); 16566 mUserLru.remove(userIdInt); 16567 mUserLru.add(userIdInt); 16568 16569 if (foreground) { 16570 mCurrentUserId = userId; 16571 updateCurrentProfileIdsLocked(); 16572 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16573 // Once the internal notion of the active user has switched, we lock the device 16574 // with the option to show the user switcher on the keyguard. 16575 mWindowManager.lockNow(null); 16576 } else { 16577 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16578 updateCurrentProfileIdsLocked(); 16579 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16580 mUserLru.remove(currentUserIdInt); 16581 mUserLru.add(currentUserIdInt); 16582 } 16583 16584 final UserStartedState uss = mStartedUsers.get(userId); 16585 16586 // Make sure user is in the started state. If it is currently 16587 // stopping, we need to knock that off. 16588 if (uss.mState == UserStartedState.STATE_STOPPING) { 16589 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16590 // so we can just fairly silently bring the user back from 16591 // the almost-dead. 16592 uss.mState = UserStartedState.STATE_RUNNING; 16593 updateStartedUserArrayLocked(); 16594 needStart = true; 16595 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16596 // This means ACTION_SHUTDOWN has been sent, so we will 16597 // need to treat this as a new boot of the user. 16598 uss.mState = UserStartedState.STATE_BOOTING; 16599 updateStartedUserArrayLocked(); 16600 needStart = true; 16601 } 16602 16603 if (uss.mState == UserStartedState.STATE_BOOTING) { 16604 // Booting up a new user, need to tell system services about it. 16605 // Note that this is on the same handler as scheduling of broadcasts, 16606 // which is important because it needs to go first. 16607 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16608 } 16609 16610 if (foreground) { 16611 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16612 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16613 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16614 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16615 oldUserId, userId, uss)); 16616 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16617 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16618 } 16619 16620 if (needStart) { 16621 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16622 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16623 | Intent.FLAG_RECEIVER_FOREGROUND); 16624 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16625 broadcastIntentLocked(null, null, intent, 16626 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16627 false, false, MY_PID, Process.SYSTEM_UID, userId); 16628 } 16629 16630 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16631 if (userId != UserHandle.USER_OWNER) { 16632 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16633 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16634 broadcastIntentLocked(null, null, intent, null, 16635 new IIntentReceiver.Stub() { 16636 public void performReceive(Intent intent, int resultCode, 16637 String data, Bundle extras, boolean ordered, 16638 boolean sticky, int sendingUser) { 16639 userInitialized(uss, userId); 16640 } 16641 }, 0, null, null, null, AppOpsManager.OP_NONE, 16642 true, false, MY_PID, Process.SYSTEM_UID, 16643 userId); 16644 uss.initializing = true; 16645 } else { 16646 getUserManagerLocked().makeInitialized(userInfo.id); 16647 } 16648 } 16649 16650 if (foreground) { 16651 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16652 if (homeInFront) { 16653 startHomeActivityLocked(userId); 16654 } else { 16655 mStackSupervisor.resumeTopActivitiesLocked(); 16656 } 16657 EventLogTags.writeAmSwitchUser(userId); 16658 getUserManagerLocked().userForeground(userId); 16659 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16660 } else { 16661 mStackSupervisor.startBackgroundUserLocked(userId, uss); 16662 } 16663 16664 if (needStart) { 16665 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16666 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16667 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16668 broadcastIntentLocked(null, null, intent, 16669 null, new IIntentReceiver.Stub() { 16670 @Override 16671 public void performReceive(Intent intent, int resultCode, String data, 16672 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16673 throws RemoteException { 16674 } 16675 }, 0, null, null, 16676 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16677 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16678 } 16679 } 16680 } finally { 16681 Binder.restoreCallingIdentity(ident); 16682 } 16683 16684 return true; 16685 } 16686 16687 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16688 long ident = Binder.clearCallingIdentity(); 16689 try { 16690 Intent intent; 16691 if (oldUserId >= 0) { 16692 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16693 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16694 | Intent.FLAG_RECEIVER_FOREGROUND); 16695 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16696 broadcastIntentLocked(null, null, intent, 16697 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16698 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16699 } 16700 if (newUserId >= 0) { 16701 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16702 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16703 | Intent.FLAG_RECEIVER_FOREGROUND); 16704 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16705 broadcastIntentLocked(null, null, intent, 16706 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16707 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16708 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16709 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16710 | Intent.FLAG_RECEIVER_FOREGROUND); 16711 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16712 broadcastIntentLocked(null, null, intent, 16713 null, null, 0, null, null, 16714 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16715 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16716 } 16717 } finally { 16718 Binder.restoreCallingIdentity(ident); 16719 } 16720 } 16721 16722 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16723 final int newUserId) { 16724 final int N = mUserSwitchObservers.beginBroadcast(); 16725 if (N > 0) { 16726 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16727 int mCount = 0; 16728 @Override 16729 public void sendResult(Bundle data) throws RemoteException { 16730 synchronized (ActivityManagerService.this) { 16731 if (mCurUserSwitchCallback == this) { 16732 mCount++; 16733 if (mCount == N) { 16734 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16735 } 16736 } 16737 } 16738 } 16739 }; 16740 synchronized (this) { 16741 uss.switching = true; 16742 mCurUserSwitchCallback = callback; 16743 } 16744 for (int i=0; i<N; i++) { 16745 try { 16746 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16747 newUserId, callback); 16748 } catch (RemoteException e) { 16749 } 16750 } 16751 } else { 16752 synchronized (this) { 16753 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16754 } 16755 } 16756 mUserSwitchObservers.finishBroadcast(); 16757 } 16758 16759 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16760 synchronized (this) { 16761 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16762 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16763 } 16764 } 16765 16766 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16767 mCurUserSwitchCallback = null; 16768 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16769 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16770 oldUserId, newUserId, uss)); 16771 } 16772 16773 void userInitialized(UserStartedState uss, int newUserId) { 16774 completeSwitchAndInitalize(uss, newUserId, true, false); 16775 } 16776 16777 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16778 completeSwitchAndInitalize(uss, newUserId, false, true); 16779 } 16780 16781 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16782 boolean clearInitializing, boolean clearSwitching) { 16783 boolean unfrozen = false; 16784 synchronized (this) { 16785 if (clearInitializing) { 16786 uss.initializing = false; 16787 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16788 } 16789 if (clearSwitching) { 16790 uss.switching = false; 16791 } 16792 if (!uss.switching && !uss.initializing) { 16793 mWindowManager.stopFreezingScreen(); 16794 unfrozen = true; 16795 } 16796 } 16797 if (unfrozen) { 16798 final int N = mUserSwitchObservers.beginBroadcast(); 16799 for (int i=0; i<N; i++) { 16800 try { 16801 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16802 } catch (RemoteException e) { 16803 } 16804 } 16805 mUserSwitchObservers.finishBroadcast(); 16806 } 16807 } 16808 16809 void scheduleStartProfilesLocked() { 16810 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16811 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16812 DateUtils.SECOND_IN_MILLIS); 16813 } 16814 } 16815 16816 void startProfilesLocked() { 16817 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16818 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16819 mCurrentUserId, false /* enabledOnly */); 16820 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16821 for (UserInfo user : profiles) { 16822 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16823 && user.id != mCurrentUserId) { 16824 toStart.add(user); 16825 } 16826 } 16827 final int n = toStart.size(); 16828 int i = 0; 16829 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16830 startUserInBackground(toStart.get(i).id); 16831 } 16832 if (i < n) { 16833 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16834 } 16835 } 16836 16837 void finishUserBoot(UserStartedState uss) { 16838 synchronized (this) { 16839 if (uss.mState == UserStartedState.STATE_BOOTING 16840 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16841 uss.mState = UserStartedState.STATE_RUNNING; 16842 final int userId = uss.mHandle.getIdentifier(); 16843 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16844 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16845 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16846 broadcastIntentLocked(null, null, intent, 16847 null, null, 0, null, null, 16848 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16849 true, false, MY_PID, Process.SYSTEM_UID, userId); 16850 } 16851 } 16852 } 16853 16854 void finishUserSwitch(UserStartedState uss) { 16855 synchronized (this) { 16856 finishUserBoot(uss); 16857 16858 startProfilesLocked(); 16859 16860 int num = mUserLru.size(); 16861 int i = 0; 16862 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16863 Integer oldUserId = mUserLru.get(i); 16864 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16865 if (oldUss == null) { 16866 // Shouldn't happen, but be sane if it does. 16867 mUserLru.remove(i); 16868 num--; 16869 continue; 16870 } 16871 if (oldUss.mState == UserStartedState.STATE_STOPPING 16872 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16873 // This user is already stopping, doesn't count. 16874 num--; 16875 i++; 16876 continue; 16877 } 16878 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16879 // Owner and current can't be stopped, but count as running. 16880 i++; 16881 continue; 16882 } 16883 // This is a user to be stopped. 16884 stopUserLocked(oldUserId, null); 16885 num--; 16886 i++; 16887 } 16888 } 16889 } 16890 16891 @Override 16892 public int stopUser(final int userId, final IStopUserCallback callback) { 16893 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16894 != PackageManager.PERMISSION_GRANTED) { 16895 String msg = "Permission Denial: switchUser() from pid=" 16896 + Binder.getCallingPid() 16897 + ", uid=" + Binder.getCallingUid() 16898 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16899 Slog.w(TAG, msg); 16900 throw new SecurityException(msg); 16901 } 16902 if (userId <= 0) { 16903 throw new IllegalArgumentException("Can't stop primary user " + userId); 16904 } 16905 synchronized (this) { 16906 return stopUserLocked(userId, callback); 16907 } 16908 } 16909 16910 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16911 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16912 if (mCurrentUserId == userId) { 16913 return ActivityManager.USER_OP_IS_CURRENT; 16914 } 16915 16916 final UserStartedState uss = mStartedUsers.get(userId); 16917 if (uss == null) { 16918 // User is not started, nothing to do... but we do need to 16919 // callback if requested. 16920 if (callback != null) { 16921 mHandler.post(new Runnable() { 16922 @Override 16923 public void run() { 16924 try { 16925 callback.userStopped(userId); 16926 } catch (RemoteException e) { 16927 } 16928 } 16929 }); 16930 } 16931 return ActivityManager.USER_OP_SUCCESS; 16932 } 16933 16934 if (callback != null) { 16935 uss.mStopCallbacks.add(callback); 16936 } 16937 16938 if (uss.mState != UserStartedState.STATE_STOPPING 16939 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16940 uss.mState = UserStartedState.STATE_STOPPING; 16941 updateStartedUserArrayLocked(); 16942 16943 long ident = Binder.clearCallingIdentity(); 16944 try { 16945 // We are going to broadcast ACTION_USER_STOPPING and then 16946 // once that is done send a final ACTION_SHUTDOWN and then 16947 // stop the user. 16948 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16949 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16950 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16951 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16952 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16953 // This is the result receiver for the final shutdown broadcast. 16954 final IIntentReceiver shutdownReceiver = 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 finishUserStop(uss); 16959 } 16960 }; 16961 // This is the result receiver for the initial stopping broadcast. 16962 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16963 @Override 16964 public void performReceive(Intent intent, int resultCode, String data, 16965 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16966 // On to the next. 16967 synchronized (ActivityManagerService.this) { 16968 if (uss.mState != UserStartedState.STATE_STOPPING) { 16969 // Whoops, we are being started back up. Abort, abort! 16970 return; 16971 } 16972 uss.mState = UserStartedState.STATE_SHUTDOWN; 16973 } 16974 mSystemServiceManager.stopUser(userId); 16975 broadcastIntentLocked(null, null, shutdownIntent, 16976 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16977 true, false, MY_PID, Process.SYSTEM_UID, userId); 16978 } 16979 }; 16980 // Kick things off. 16981 broadcastIntentLocked(null, null, stoppingIntent, 16982 null, stoppingReceiver, 0, null, null, 16983 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16984 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16985 } finally { 16986 Binder.restoreCallingIdentity(ident); 16987 } 16988 } 16989 16990 return ActivityManager.USER_OP_SUCCESS; 16991 } 16992 16993 void finishUserStop(UserStartedState uss) { 16994 final int userId = uss.mHandle.getIdentifier(); 16995 boolean stopped; 16996 ArrayList<IStopUserCallback> callbacks; 16997 synchronized (this) { 16998 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16999 if (mStartedUsers.get(userId) != uss) { 17000 stopped = false; 17001 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 17002 stopped = false; 17003 } else { 17004 stopped = true; 17005 // User can no longer run. 17006 mStartedUsers.remove(userId); 17007 mUserLru.remove(Integer.valueOf(userId)); 17008 updateStartedUserArrayLocked(); 17009 17010 // Clean up all state and processes associated with the user. 17011 // Kill all the processes for the user. 17012 forceStopUserLocked(userId, "finish user"); 17013 } 17014 } 17015 17016 for (int i=0; i<callbacks.size(); i++) { 17017 try { 17018 if (stopped) callbacks.get(i).userStopped(userId); 17019 else callbacks.get(i).userStopAborted(userId); 17020 } catch (RemoteException e) { 17021 } 17022 } 17023 17024 if (stopped) { 17025 mSystemServiceManager.cleanupUser(userId); 17026 synchronized (this) { 17027 mStackSupervisor.removeUserLocked(userId); 17028 } 17029 } 17030 } 17031 17032 @Override 17033 public UserInfo getCurrentUser() { 17034 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17035 != PackageManager.PERMISSION_GRANTED) && ( 17036 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17037 != PackageManager.PERMISSION_GRANTED)) { 17038 String msg = "Permission Denial: getCurrentUser() from pid=" 17039 + Binder.getCallingPid() 17040 + ", uid=" + Binder.getCallingUid() 17041 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17042 Slog.w(TAG, msg); 17043 throw new SecurityException(msg); 17044 } 17045 synchronized (this) { 17046 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17047 } 17048 } 17049 17050 int getCurrentUserIdLocked() { 17051 return mCurrentUserId; 17052 } 17053 17054 @Override 17055 public boolean isUserRunning(int userId, boolean orStopped) { 17056 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17057 != PackageManager.PERMISSION_GRANTED) { 17058 String msg = "Permission Denial: isUserRunning() from pid=" 17059 + Binder.getCallingPid() 17060 + ", uid=" + Binder.getCallingUid() 17061 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17062 Slog.w(TAG, msg); 17063 throw new SecurityException(msg); 17064 } 17065 synchronized (this) { 17066 return isUserRunningLocked(userId, orStopped); 17067 } 17068 } 17069 17070 boolean isUserRunningLocked(int userId, boolean orStopped) { 17071 UserStartedState state = mStartedUsers.get(userId); 17072 if (state == null) { 17073 return false; 17074 } 17075 if (orStopped) { 17076 return true; 17077 } 17078 return state.mState != UserStartedState.STATE_STOPPING 17079 && state.mState != UserStartedState.STATE_SHUTDOWN; 17080 } 17081 17082 @Override 17083 public int[] getRunningUserIds() { 17084 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17085 != PackageManager.PERMISSION_GRANTED) { 17086 String msg = "Permission Denial: isUserRunning() from pid=" 17087 + Binder.getCallingPid() 17088 + ", uid=" + Binder.getCallingUid() 17089 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17090 Slog.w(TAG, msg); 17091 throw new SecurityException(msg); 17092 } 17093 synchronized (this) { 17094 return mStartedUserArray; 17095 } 17096 } 17097 17098 private void updateStartedUserArrayLocked() { 17099 int num = 0; 17100 for (int i=0; i<mStartedUsers.size(); i++) { 17101 UserStartedState uss = mStartedUsers.valueAt(i); 17102 // This list does not include stopping users. 17103 if (uss.mState != UserStartedState.STATE_STOPPING 17104 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17105 num++; 17106 } 17107 } 17108 mStartedUserArray = new int[num]; 17109 num = 0; 17110 for (int i=0; i<mStartedUsers.size(); i++) { 17111 UserStartedState uss = mStartedUsers.valueAt(i); 17112 if (uss.mState != UserStartedState.STATE_STOPPING 17113 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17114 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17115 num++; 17116 } 17117 } 17118 } 17119 17120 @Override 17121 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17122 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17123 != PackageManager.PERMISSION_GRANTED) { 17124 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17125 + Binder.getCallingPid() 17126 + ", uid=" + Binder.getCallingUid() 17127 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 17128 Slog.w(TAG, msg); 17129 throw new SecurityException(msg); 17130 } 17131 17132 mUserSwitchObservers.register(observer); 17133 } 17134 17135 @Override 17136 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17137 mUserSwitchObservers.unregister(observer); 17138 } 17139 17140 private boolean userExists(int userId) { 17141 if (userId == 0) { 17142 return true; 17143 } 17144 UserManagerService ums = getUserManagerLocked(); 17145 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17146 } 17147 17148 int[] getUsersLocked() { 17149 UserManagerService ums = getUserManagerLocked(); 17150 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17151 } 17152 17153 UserManagerService getUserManagerLocked() { 17154 if (mUserManager == null) { 17155 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17156 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17157 } 17158 return mUserManager; 17159 } 17160 17161 private int applyUserId(int uid, int userId) { 17162 return UserHandle.getUid(userId, uid); 17163 } 17164 17165 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17166 if (info == null) return null; 17167 ApplicationInfo newInfo = new ApplicationInfo(info); 17168 newInfo.uid = applyUserId(info.uid, userId); 17169 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17170 + info.packageName; 17171 return newInfo; 17172 } 17173 17174 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17175 if (aInfo == null 17176 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17177 return aInfo; 17178 } 17179 17180 ActivityInfo info = new ActivityInfo(aInfo); 17181 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17182 return info; 17183 } 17184 17185 private final class LocalService extends ActivityManagerInternal { 17186 @Override 17187 public void goingToSleep() { 17188 ActivityManagerService.this.goingToSleep(); 17189 } 17190 17191 @Override 17192 public void wakingUp() { 17193 ActivityManagerService.this.wakingUp(); 17194 } 17195 } 17196 17197 /** 17198 * An implementation of IAppTask, that allows an app to manage its own tasks via 17199 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 17200 * only the process that calls getAppTasks() can call the AppTask methods. 17201 */ 17202 class AppTaskImpl extends IAppTask.Stub { 17203 private int mTaskId; 17204 private int mCallingUid; 17205 17206 public AppTaskImpl(int taskId, int callingUid) { 17207 mTaskId = taskId; 17208 mCallingUid = callingUid; 17209 } 17210 17211 @Override 17212 public void finishAndRemoveTask() { 17213 // Ensure that we are called from the same process that created this AppTask 17214 if (mCallingUid != Binder.getCallingUid()) { 17215 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17216 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17217 return; 17218 } 17219 17220 synchronized (ActivityManagerService.this) { 17221 long origId = Binder.clearCallingIdentity(); 17222 try { 17223 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17224 if (tr != null) { 17225 // Only kill the process if we are not a new document 17226 int flags = tr.getBaseIntent().getFlags(); 17227 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 17228 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 17229 removeTaskByIdLocked(mTaskId, 17230 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 17231 } 17232 } finally { 17233 Binder.restoreCallingIdentity(origId); 17234 } 17235 } 17236 } 17237 17238 @Override 17239 public ActivityManager.RecentTaskInfo getTaskInfo() { 17240 // Ensure that we are called from the same process that created this AppTask 17241 if (mCallingUid != Binder.getCallingUid()) { 17242 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17243 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17244 return null; 17245 } 17246 17247 synchronized (ActivityManagerService.this) { 17248 long origId = Binder.clearCallingIdentity(); 17249 try { 17250 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17251 if (tr != null) { 17252 return createRecentTaskInfoFromTaskRecord(tr); 17253 } 17254 } finally { 17255 Binder.restoreCallingIdentity(origId); 17256 } 17257 return null; 17258 } 17259 } 17260 } 17261} 17262