ActivityManagerService.java revision 233ceeebab7efe6ad4783371003c4cf29b896436
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.appwidget.AppWidgetManager; 36import android.graphics.Rect; 37import android.os.BatteryStats; 38import android.os.PersistableBundle; 39import android.service.voice.IVoiceInteractionSession; 40import android.util.ArrayMap; 41 42import com.android.internal.R; 43import com.android.internal.annotations.GuardedBy; 44import com.android.internal.app.IAppOpsService; 45import com.android.internal.app.IVoiceInteractor; 46import com.android.internal.app.ProcessMap; 47import com.android.internal.app.ProcessStats; 48import com.android.internal.content.PackageMonitor; 49import com.android.internal.os.BackgroundThread; 50import com.android.internal.os.BatteryStatsImpl; 51import com.android.internal.os.ProcessCpuTracker; 52import com.android.internal.os.TransferPipe; 53import com.android.internal.os.Zygote; 54import com.android.internal.util.FastPrintWriter; 55import com.android.internal.util.FastXmlSerializer; 56import com.android.internal.util.MemInfoReader; 57import com.android.internal.util.Preconditions; 58import com.android.server.AppOpsService; 59import com.android.server.AttributeCache; 60import com.android.server.IntentResolver; 61import com.android.server.LocalServices; 62import com.android.server.ServiceThread; 63import com.android.server.SystemService; 64import com.android.server.SystemServiceManager; 65import com.android.server.Watchdog; 66import com.android.server.am.ActivityStack.ActivityState; 67import com.android.server.firewall.IntentFirewall; 68import com.android.server.pm.UserManagerService; 69import com.android.server.wm.AppTransition; 70import com.android.server.wm.WindowManagerService; 71import com.google.android.collect.Lists; 72import com.google.android.collect.Maps; 73 74import libcore.io.IoUtils; 75 76import org.xmlpull.v1.XmlPullParser; 77import org.xmlpull.v1.XmlPullParserException; 78import org.xmlpull.v1.XmlSerializer; 79 80import android.app.Activity; 81import android.app.ActivityManager; 82import android.app.ActivityManager.RunningTaskInfo; 83import android.app.ActivityManager.StackInfo; 84import android.app.ActivityManagerInternal; 85import android.app.ActivityManagerNative; 86import android.app.ActivityOptions; 87import android.app.ActivityThread; 88import android.app.AlertDialog; 89import android.app.AppGlobals; 90import android.app.ApplicationErrorReport; 91import android.app.Dialog; 92import android.app.IActivityController; 93import android.app.IApplicationThread; 94import android.app.IInstrumentationWatcher; 95import android.app.INotificationManager; 96import android.app.IProcessObserver; 97import android.app.IServiceConnection; 98import android.app.IStopUserCallback; 99import android.app.IUiAutomationConnection; 100import android.app.IUserSwitchObserver; 101import android.app.Instrumentation; 102import android.app.Notification; 103import android.app.NotificationManager; 104import android.app.PendingIntent; 105import android.app.backup.IBackupManager; 106import android.content.ActivityNotFoundException; 107import android.content.BroadcastReceiver; 108import android.content.ClipData; 109import android.content.ComponentCallbacks2; 110import android.content.ComponentName; 111import android.content.ContentProvider; 112import android.content.ContentResolver; 113import android.content.Context; 114import android.content.DialogInterface; 115import android.content.IContentProvider; 116import android.content.IIntentReceiver; 117import android.content.IIntentSender; 118import android.content.Intent; 119import android.content.IntentFilter; 120import android.content.IntentSender; 121import android.content.pm.ActivityInfo; 122import android.content.pm.ApplicationInfo; 123import android.content.pm.ConfigurationInfo; 124import android.content.pm.IPackageDataObserver; 125import android.content.pm.IPackageManager; 126import android.content.pm.InstrumentationInfo; 127import android.content.pm.PackageInfo; 128import android.content.pm.PackageManager; 129import android.content.pm.ParceledListSlice; 130import android.content.pm.UserInfo; 131import android.content.pm.PackageManager.NameNotFoundException; 132import android.content.pm.PathPermission; 133import android.content.pm.ProviderInfo; 134import android.content.pm.ResolveInfo; 135import android.content.pm.ServiceInfo; 136import android.content.res.CompatibilityInfo; 137import android.content.res.Configuration; 138import android.graphics.Bitmap; 139import android.net.Proxy; 140import android.net.ProxyInfo; 141import android.net.Uri; 142import android.os.Binder; 143import android.os.Build; 144import android.os.Bundle; 145import android.os.Debug; 146import android.os.DropBoxManager; 147import android.os.Environment; 148import android.os.FactoryTest; 149import android.os.FileObserver; 150import android.os.FileUtils; 151import android.os.Handler; 152import android.os.IBinder; 153import android.os.IPermissionController; 154import android.os.IRemoteCallback; 155import android.os.IUserManager; 156import android.os.Looper; 157import android.os.Message; 158import android.os.Parcel; 159import android.os.ParcelFileDescriptor; 160import android.os.Process; 161import android.os.RemoteCallbackList; 162import android.os.RemoteException; 163import android.os.SELinux; 164import android.os.ServiceManager; 165import android.os.StrictMode; 166import android.os.SystemClock; 167import android.os.SystemProperties; 168import android.os.UpdateLock; 169import android.os.UserHandle; 170import android.provider.Settings; 171import android.text.format.DateUtils; 172import android.text.format.Time; 173import android.util.AtomicFile; 174import android.util.EventLog; 175import android.util.Log; 176import android.util.Pair; 177import android.util.PrintWriterPrinter; 178import android.util.Slog; 179import android.util.SparseArray; 180import android.util.TimeUtils; 181import android.util.Xml; 182import android.view.Gravity; 183import android.view.LayoutInflater; 184import android.view.View; 185import android.view.WindowManager; 186 187import java.io.BufferedInputStream; 188import java.io.BufferedOutputStream; 189import java.io.DataInputStream; 190import java.io.DataOutputStream; 191import java.io.File; 192import java.io.FileDescriptor; 193import java.io.FileInputStream; 194import java.io.FileNotFoundException; 195import java.io.FileOutputStream; 196import java.io.IOException; 197import java.io.InputStreamReader; 198import java.io.PrintWriter; 199import java.io.StringWriter; 200import java.lang.ref.WeakReference; 201import java.util.ArrayList; 202import java.util.Arrays; 203import java.util.Collections; 204import java.util.Comparator; 205import java.util.HashMap; 206import java.util.HashSet; 207import java.util.Iterator; 208import java.util.List; 209import java.util.Locale; 210import java.util.Map; 211import java.util.Set; 212import java.util.concurrent.atomic.AtomicBoolean; 213import java.util.concurrent.atomic.AtomicLong; 214 215public final class ActivityManagerService extends ActivityManagerNative 216 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 217 private static final String USER_DATA_DIR = "/data/user/"; 218 static final String TAG = "ActivityManager"; 219 static final String TAG_MU = "ActivityManagerServiceMU"; 220 static final boolean DEBUG = false; 221 static final boolean localLOGV = DEBUG; 222 static final boolean DEBUG_BACKUP = localLOGV || false; 223 static final boolean DEBUG_BROADCAST = localLOGV || false; 224 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 225 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 226 static final boolean DEBUG_CLEANUP = localLOGV || false; 227 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 228 static final boolean DEBUG_FOCUS = false; 229 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 230 static final boolean DEBUG_MU = localLOGV || false; 231 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 232 static final boolean DEBUG_LRU = localLOGV || false; 233 static final boolean DEBUG_PAUSE = localLOGV || false; 234 static final boolean DEBUG_POWER = localLOGV || false; 235 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 236 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 237 static final boolean DEBUG_PROCESSES = localLOGV || false; 238 static final boolean DEBUG_PROVIDER = localLOGV || false; 239 static final boolean DEBUG_RESULTS = localLOGV || false; 240 static final boolean DEBUG_SERVICE = localLOGV || false; 241 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 242 static final boolean DEBUG_STACK = localLOGV || false; 243 static final boolean DEBUG_SWITCH = localLOGV || false; 244 static final boolean DEBUG_TASKS = localLOGV || false; 245 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 246 static final boolean DEBUG_TRANSITION = localLOGV || false; 247 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 248 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 249 static final boolean DEBUG_VISBILITY = localLOGV || false; 250 static final boolean DEBUG_PSS = localLOGV || false; 251 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 252 static final boolean VALIDATE_TOKENS = false; 253 static final boolean SHOW_ACTIVITY_START_TIME = true; 254 255 // Control over CPU and battery monitoring. 256 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 257 static final boolean MONITOR_CPU_USAGE = true; 258 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 259 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 260 static final boolean MONITOR_THREAD_CPU_USAGE = false; 261 262 // The flags that are set for all calls we make to the package manager. 263 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 264 265 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 266 267 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 268 269 // Maximum number of recent tasks that we can remember. 270 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 271 272 // Amount of time after a call to stopAppSwitches() during which we will 273 // prevent further untrusted switches from happening. 274 static final long APP_SWITCH_DELAY_TIME = 5*1000; 275 276 // How long we wait for a launched process to attach to the activity manager 277 // before we decide it's never going to come up for real. 278 static final int PROC_START_TIMEOUT = 10*1000; 279 280 // How long we wait for a launched process to attach to the activity manager 281 // before we decide it's never going to come up for real, when the process was 282 // started with a wrapper for instrumentation (such as Valgrind) because it 283 // could take much longer than usual. 284 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 285 286 // How long to wait after going idle before forcing apps to GC. 287 static final int GC_TIMEOUT = 5*1000; 288 289 // The minimum amount of time between successive GC requests for a process. 290 static final int GC_MIN_INTERVAL = 60*1000; 291 292 // The minimum amount of time between successive PSS requests for a process. 293 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 294 295 // The minimum amount of time between successive PSS requests for a process 296 // when the request is due to the memory state being lowered. 297 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 298 299 // The rate at which we check for apps using excessive power -- 15 mins. 300 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 301 302 // The minimum sample duration we will allow before deciding we have 303 // enough data on wake locks to start killing things. 304 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 305 306 // The minimum sample duration we will allow before deciding we have 307 // enough data on CPU usage to start killing things. 308 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 309 310 // How long we allow a receiver to run before giving up on it. 311 static final int BROADCAST_FG_TIMEOUT = 10*1000; 312 static final int BROADCAST_BG_TIMEOUT = 60*1000; 313 314 // How long we wait until we timeout on key dispatching. 315 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 316 317 // How long we wait until we timeout on key dispatching during instrumentation. 318 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 319 320 // Amount of time we wait for observers to handle a user switch before 321 // giving up on them and unfreezing the screen. 322 static final int USER_SWITCH_TIMEOUT = 2*1000; 323 324 // Maximum number of users we allow to be running at a time. 325 static final int MAX_RUNNING_USERS = 3; 326 327 // How long to wait in getAssistContextExtras for the activity and foreground services 328 // to respond with the result. 329 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 330 331 // Maximum number of persisted Uri grants a package is allowed 332 static final int MAX_PERSISTED_URI_GRANTS = 128; 333 334 static final int MY_PID = Process.myPid(); 335 336 static final String[] EMPTY_STRING_ARRAY = new String[0]; 337 338 // How many bytes to write into the dropbox log before truncating 339 static final int DROPBOX_MAX_SIZE = 256 * 1024; 340 341 /** All system services */ 342 SystemServiceManager mSystemServiceManager; 343 344 /** Run all ActivityStacks through this */ 345 ActivityStackSupervisor mStackSupervisor; 346 347 public IntentFirewall mIntentFirewall; 348 349 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 350 // default actuion automatically. Important for devices without direct input 351 // devices. 352 private boolean mShowDialogs = true; 353 354 /** 355 * Description of a request to start a new activity, which has been held 356 * due to app switches being disabled. 357 */ 358 static class PendingActivityLaunch { 359 final ActivityRecord r; 360 final ActivityRecord sourceRecord; 361 final int startFlags; 362 final ActivityStack stack; 363 364 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 365 int _startFlags, ActivityStack _stack) { 366 r = _r; 367 sourceRecord = _sourceRecord; 368 startFlags = _startFlags; 369 stack = _stack; 370 } 371 } 372 373 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 374 = new ArrayList<PendingActivityLaunch>(); 375 376 BroadcastQueue mFgBroadcastQueue; 377 BroadcastQueue mBgBroadcastQueue; 378 // Convenient for easy iteration over the queues. Foreground is first 379 // so that dispatch of foreground broadcasts gets precedence. 380 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 381 382 BroadcastQueue broadcastQueueForIntent(Intent intent) { 383 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 384 if (DEBUG_BACKGROUND_BROADCAST) { 385 Slog.i(TAG, "Broadcast intent " + intent + " on " 386 + (isFg ? "foreground" : "background") 387 + " queue"); 388 } 389 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 390 } 391 392 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 393 for (BroadcastQueue queue : mBroadcastQueues) { 394 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 395 if (r != null) { 396 return r; 397 } 398 } 399 return null; 400 } 401 402 /** 403 * Activity we have told the window manager to have key focus. 404 */ 405 ActivityRecord mFocusedActivity = null; 406 407 /** 408 * List of intents that were used to start the most recent tasks. 409 */ 410 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 411 412 public class PendingAssistExtras extends Binder implements Runnable { 413 public final ActivityRecord activity; 414 public boolean haveResult = false; 415 public Bundle result = null; 416 public PendingAssistExtras(ActivityRecord _activity) { 417 activity = _activity; 418 } 419 @Override 420 public void run() { 421 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 422 synchronized (this) { 423 haveResult = true; 424 notifyAll(); 425 } 426 } 427 } 428 429 final ArrayList<PendingAssistExtras> mPendingAssistExtras 430 = new ArrayList<PendingAssistExtras>(); 431 432 /** 433 * Process management. 434 */ 435 final ProcessList mProcessList = new ProcessList(); 436 437 /** 438 * All of the applications we currently have running organized by name. 439 * The keys are strings of the application package name (as 440 * returned by the package manager), and the keys are ApplicationRecord 441 * objects. 442 */ 443 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 444 445 /** 446 * Tracking long-term execution of processes to look for abuse and other 447 * bad app behavior. 448 */ 449 final ProcessStatsService mProcessStats; 450 451 /** 452 * The currently running isolated processes. 453 */ 454 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 455 456 /** 457 * Counter for assigning isolated process uids, to avoid frequently reusing the 458 * same ones. 459 */ 460 int mNextIsolatedProcessUid = 0; 461 462 /** 463 * The currently running heavy-weight process, if any. 464 */ 465 ProcessRecord mHeavyWeightProcess = null; 466 467 /** 468 * The last time that various processes have crashed. 469 */ 470 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 471 472 /** 473 * Information about a process that is currently marked as bad. 474 */ 475 static final class BadProcessInfo { 476 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 477 this.time = time; 478 this.shortMsg = shortMsg; 479 this.longMsg = longMsg; 480 this.stack = stack; 481 } 482 483 final long time; 484 final String shortMsg; 485 final String longMsg; 486 final String stack; 487 } 488 489 /** 490 * Set of applications that we consider to be bad, and will reject 491 * incoming broadcasts from (which the user has no control over). 492 * Processes are added to this set when they have crashed twice within 493 * a minimum amount of time; they are removed from it when they are 494 * later restarted (hopefully due to some user action). The value is the 495 * time it was added to the list. 496 */ 497 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 498 499 /** 500 * All of the processes we currently have running organized by pid. 501 * The keys are the pid running the application. 502 * 503 * <p>NOTE: This object is protected by its own lock, NOT the global 504 * activity manager lock! 505 */ 506 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 507 508 /** 509 * All of the processes that have been forced to be foreground. The key 510 * is the pid of the caller who requested it (we hold a death 511 * link on it). 512 */ 513 abstract class ForegroundToken implements IBinder.DeathRecipient { 514 int pid; 515 IBinder token; 516 } 517 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 518 519 /** 520 * List of records for processes that someone had tried to start before the 521 * system was ready. We don't start them at that point, but ensure they 522 * are started by the time booting is complete. 523 */ 524 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 525 526 /** 527 * List of persistent applications that are in the process 528 * of being started. 529 */ 530 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 531 532 /** 533 * Processes that are being forcibly torn down. 534 */ 535 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 536 537 /** 538 * List of running applications, sorted by recent usage. 539 * The first entry in the list is the least recently used. 540 */ 541 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 542 543 /** 544 * Where in mLruProcesses that the processes hosting activities start. 545 */ 546 int mLruProcessActivityStart = 0; 547 548 /** 549 * Where in mLruProcesses that the processes hosting services start. 550 * This is after (lower index) than mLruProcessesActivityStart. 551 */ 552 int mLruProcessServiceStart = 0; 553 554 /** 555 * List of processes that should gc as soon as things are idle. 556 */ 557 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 558 559 /** 560 * Processes we want to collect PSS data from. 561 */ 562 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 563 564 /** 565 * Last time we requested PSS data of all processes. 566 */ 567 long mLastFullPssTime = SystemClock.uptimeMillis(); 568 569 /** 570 * This is the process holding what we currently consider to be 571 * the "home" activity. 572 */ 573 ProcessRecord mHomeProcess; 574 575 /** 576 * This is the process holding the activity the user last visited that 577 * is in a different process from the one they are currently in. 578 */ 579 ProcessRecord mPreviousProcess; 580 581 /** 582 * The time at which the previous process was last visible. 583 */ 584 long mPreviousProcessVisibleTime; 585 586 /** 587 * Which uses have been started, so are allowed to run code. 588 */ 589 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 590 591 /** 592 * LRU list of history of current users. Most recently current is at the end. 593 */ 594 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 595 596 /** 597 * Constant array of the users that are currently started. 598 */ 599 int[] mStartedUserArray = new int[] { 0 }; 600 601 /** 602 * Registered observers of the user switching mechanics. 603 */ 604 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 605 = new RemoteCallbackList<IUserSwitchObserver>(); 606 607 /** 608 * Currently active user switch. 609 */ 610 Object mCurUserSwitchCallback; 611 612 /** 613 * Packages that the user has asked to have run in screen size 614 * compatibility mode instead of filling the screen. 615 */ 616 final CompatModePackages mCompatModePackages; 617 618 /** 619 * Set of IntentSenderRecord objects that are currently active. 620 */ 621 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 622 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 623 624 /** 625 * Fingerprints (hashCode()) of stack traces that we've 626 * already logged DropBox entries for. Guarded by itself. If 627 * something (rogue user app) forces this over 628 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 629 */ 630 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 631 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 632 633 /** 634 * Strict Mode background batched logging state. 635 * 636 * The string buffer is guarded by itself, and its lock is also 637 * used to determine if another batched write is already 638 * in-flight. 639 */ 640 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 641 642 /** 643 * Keeps track of all IIntentReceivers that have been registered for 644 * broadcasts. Hash keys are the receiver IBinder, hash value is 645 * a ReceiverList. 646 */ 647 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 648 new HashMap<IBinder, ReceiverList>(); 649 650 /** 651 * Resolver for broadcast intents to registered receivers. 652 * Holds BroadcastFilter (subclass of IntentFilter). 653 */ 654 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 655 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 656 @Override 657 protected boolean allowFilterResult( 658 BroadcastFilter filter, List<BroadcastFilter> dest) { 659 IBinder target = filter.receiverList.receiver.asBinder(); 660 for (int i=dest.size()-1; i>=0; i--) { 661 if (dest.get(i).receiverList.receiver.asBinder() == target) { 662 return false; 663 } 664 } 665 return true; 666 } 667 668 @Override 669 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 670 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 671 || userId == filter.owningUserId) { 672 return super.newResult(filter, match, userId); 673 } 674 return null; 675 } 676 677 @Override 678 protected BroadcastFilter[] newArray(int size) { 679 return new BroadcastFilter[size]; 680 } 681 682 @Override 683 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 684 return packageName.equals(filter.packageName); 685 } 686 }; 687 688 /** 689 * State of all active sticky broadcasts per user. Keys are the action of the 690 * sticky Intent, values are an ArrayList of all broadcasted intents with 691 * that action (which should usually be one). The SparseArray is keyed 692 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 693 * for stickies that are sent to all users. 694 */ 695 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 696 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 697 698 final ActiveServices mServices; 699 700 /** 701 * Backup/restore process management 702 */ 703 String mBackupAppName = null; 704 BackupRecord mBackupTarget = null; 705 706 final ProviderMap mProviderMap; 707 708 /** 709 * List of content providers who have clients waiting for them. The 710 * application is currently being launched and the provider will be 711 * removed from this list once it is published. 712 */ 713 final ArrayList<ContentProviderRecord> mLaunchingProviders 714 = new ArrayList<ContentProviderRecord>(); 715 716 /** 717 * File storing persisted {@link #mGrantedUriPermissions}. 718 */ 719 private final AtomicFile mGrantFile; 720 721 /** XML constants used in {@link #mGrantFile} */ 722 private static final String TAG_URI_GRANTS = "uri-grants"; 723 private static final String TAG_URI_GRANT = "uri-grant"; 724 private static final String ATTR_USER_HANDLE = "userHandle"; 725 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 726 private static final String ATTR_TARGET_PKG = "targetPkg"; 727 private static final String ATTR_URI = "uri"; 728 private static final String ATTR_MODE_FLAGS = "modeFlags"; 729 private static final String ATTR_CREATED_TIME = "createdTime"; 730 private static final String ATTR_PREFIX = "prefix"; 731 732 /** 733 * Global set of specific {@link Uri} permissions that have been granted. 734 * This optimized lookup structure maps from {@link UriPermission#targetUid} 735 * to {@link UriPermission#uri} to {@link UriPermission}. 736 */ 737 @GuardedBy("this") 738 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 739 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 740 741 public static class GrantUri { 742 public final Uri uri; 743 public final boolean prefix; 744 745 public GrantUri(Uri uri, boolean prefix) { 746 this.uri = uri; 747 this.prefix = prefix; 748 } 749 750 @Override 751 public int hashCode() { 752 return toString().hashCode(); 753 } 754 755 @Override 756 public boolean equals(Object o) { 757 if (o instanceof GrantUri) { 758 GrantUri other = (GrantUri) o; 759 return uri.equals(other.uri) && prefix == other.prefix; 760 } 761 return false; 762 } 763 764 @Override 765 public String toString() { 766 if (prefix) { 767 return uri.toString() + " [prefix]"; 768 } else { 769 return uri.toString(); 770 } 771 } 772 } 773 774 CoreSettingsObserver mCoreSettingsObserver; 775 776 /** 777 * Thread-local storage used to carry caller permissions over through 778 * indirect content-provider access. 779 */ 780 private class Identity { 781 public int pid; 782 public int uid; 783 784 Identity(int _pid, int _uid) { 785 pid = _pid; 786 uid = _uid; 787 } 788 } 789 790 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 791 792 /** 793 * All information we have collected about the runtime performance of 794 * any user id that can impact battery performance. 795 */ 796 final BatteryStatsService mBatteryStatsService; 797 798 /** 799 * Information about component usage 800 */ 801 final UsageStatsService mUsageStatsService; 802 803 /** 804 * Information about and control over application operations 805 */ 806 final AppOpsService mAppOpsService; 807 808 /** 809 * Current configuration information. HistoryRecord objects are given 810 * a reference to this object to indicate which configuration they are 811 * currently running in, so this object must be kept immutable. 812 */ 813 Configuration mConfiguration = new Configuration(); 814 815 /** 816 * Current sequencing integer of the configuration, for skipping old 817 * configurations. 818 */ 819 int mConfigurationSeq = 0; 820 821 /** 822 * Hardware-reported OpenGLES version. 823 */ 824 final int GL_ES_VERSION; 825 826 /** 827 * List of initialization arguments to pass to all processes when binding applications to them. 828 * For example, references to the commonly used services. 829 */ 830 HashMap<String, IBinder> mAppBindArgs; 831 832 /** 833 * Temporary to avoid allocations. Protected by main lock. 834 */ 835 final StringBuilder mStringBuilder = new StringBuilder(256); 836 837 /** 838 * Used to control how we initialize the service. 839 */ 840 ComponentName mTopComponent; 841 String mTopAction = Intent.ACTION_MAIN; 842 String mTopData; 843 boolean mProcessesReady = false; 844 boolean mSystemReady = false; 845 boolean mBooting = false; 846 boolean mWaitingUpdate = false; 847 boolean mDidUpdate = false; 848 boolean mOnBattery = false; 849 boolean mLaunchWarningShown = false; 850 851 Context mContext; 852 853 int mFactoryTest; 854 855 boolean mCheckedForSetup; 856 857 /** 858 * The time at which we will allow normal application switches again, 859 * after a call to {@link #stopAppSwitches()}. 860 */ 861 long mAppSwitchesAllowedTime; 862 863 /** 864 * This is set to true after the first switch after mAppSwitchesAllowedTime 865 * is set; any switches after that will clear the time. 866 */ 867 boolean mDidAppSwitch; 868 869 /** 870 * Last time (in realtime) at which we checked for power usage. 871 */ 872 long mLastPowerCheckRealtime; 873 874 /** 875 * Last time (in uptime) at which we checked for power usage. 876 */ 877 long mLastPowerCheckUptime; 878 879 /** 880 * Set while we are wanting to sleep, to prevent any 881 * activities from being started/resumed. 882 */ 883 private boolean mSleeping = false; 884 885 /** 886 * Set while we are running a voice interaction. This overrides 887 * sleeping while it is active. 888 */ 889 private boolean mRunningVoice = false; 890 891 /** 892 * State of external calls telling us if the device is asleep. 893 */ 894 private boolean mWentToSleep = false; 895 896 /** 897 * State of external call telling us if the lock screen is shown. 898 */ 899 private boolean mLockScreenShown = false; 900 901 /** 902 * Set if we are shutting down the system, similar to sleeping. 903 */ 904 boolean mShuttingDown = false; 905 906 /** 907 * Current sequence id for oom_adj computation traversal. 908 */ 909 int mAdjSeq = 0; 910 911 /** 912 * Current sequence id for process LRU updating. 913 */ 914 int mLruSeq = 0; 915 916 /** 917 * Keep track of the non-cached/empty process we last found, to help 918 * determine how to distribute cached/empty processes next time. 919 */ 920 int mNumNonCachedProcs = 0; 921 922 /** 923 * Keep track of the number of cached hidden procs, to balance oom adj 924 * distribution between those and empty procs. 925 */ 926 int mNumCachedHiddenProcs = 0; 927 928 /** 929 * Keep track of the number of service processes we last found, to 930 * determine on the next iteration which should be B services. 931 */ 932 int mNumServiceProcs = 0; 933 int mNewNumAServiceProcs = 0; 934 int mNewNumServiceProcs = 0; 935 936 /** 937 * Allow the current computed overall memory level of the system to go down? 938 * This is set to false when we are killing processes for reasons other than 939 * memory management, so that the now smaller process list will not be taken as 940 * an indication that memory is tighter. 941 */ 942 boolean mAllowLowerMemLevel = false; 943 944 /** 945 * The last computed memory level, for holding when we are in a state that 946 * processes are going away for other reasons. 947 */ 948 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 949 950 /** 951 * The last total number of process we have, to determine if changes actually look 952 * like a shrinking number of process due to lower RAM. 953 */ 954 int mLastNumProcesses; 955 956 /** 957 * The uptime of the last time we performed idle maintenance. 958 */ 959 long mLastIdleTime = SystemClock.uptimeMillis(); 960 961 /** 962 * Total time spent with RAM that has been added in the past since the last idle time. 963 */ 964 long mLowRamTimeSinceLastIdle = 0; 965 966 /** 967 * If RAM is currently low, when that horrible situation started. 968 */ 969 long mLowRamStartTime = 0; 970 971 /** 972 * For reporting to battery stats the current top application. 973 */ 974 private String mCurResumedPackage = null; 975 private int mCurResumedUid = -1; 976 977 /** 978 * For reporting to battery stats the apps currently running foreground 979 * service. The ProcessMap is package/uid tuples; each of these contain 980 * an array of the currently foreground processes. 981 */ 982 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 983 = new ProcessMap<ArrayList<ProcessRecord>>(); 984 985 /** 986 * This is set if we had to do a delayed dexopt of an app before launching 987 * it, to increase the ANR timeouts in that case. 988 */ 989 boolean mDidDexOpt; 990 991 /** 992 * Set if the systemServer made a call to enterSafeMode. 993 */ 994 boolean mSafeMode; 995 996 String mDebugApp = null; 997 boolean mWaitForDebugger = false; 998 boolean mDebugTransient = false; 999 String mOrigDebugApp = null; 1000 boolean mOrigWaitForDebugger = false; 1001 boolean mAlwaysFinishActivities = false; 1002 IActivityController mController = null; 1003 String mProfileApp = null; 1004 ProcessRecord mProfileProc = null; 1005 String mProfileFile; 1006 ParcelFileDescriptor mProfileFd; 1007 int mProfileType = 0; 1008 boolean mAutoStopProfiler = false; 1009 String mOpenGlTraceApp = null; 1010 1011 static class ProcessChangeItem { 1012 static final int CHANGE_ACTIVITIES = 1<<0; 1013 static final int CHANGE_PROCESS_STATE = 1<<1; 1014 int changes; 1015 int uid; 1016 int pid; 1017 int processState; 1018 boolean foregroundActivities; 1019 } 1020 1021 final RemoteCallbackList<IProcessObserver> mProcessObservers 1022 = new RemoteCallbackList<IProcessObserver>(); 1023 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1024 1025 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1026 = new ArrayList<ProcessChangeItem>(); 1027 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1028 = new ArrayList<ProcessChangeItem>(); 1029 1030 /** 1031 * Runtime CPU use collection thread. This object's lock is used to 1032 * protect all related state. 1033 */ 1034 final Thread mProcessCpuThread; 1035 1036 /** 1037 * Used to collect process stats when showing not responding dialog. 1038 * Protected by mProcessCpuThread. 1039 */ 1040 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1041 MONITOR_THREAD_CPU_USAGE); 1042 final AtomicLong mLastCpuTime = new AtomicLong(0); 1043 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1044 1045 long mLastWriteTime = 0; 1046 1047 /** 1048 * Used to retain an update lock when the foreground activity is in 1049 * immersive mode. 1050 */ 1051 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1052 1053 /** 1054 * Set to true after the system has finished booting. 1055 */ 1056 boolean mBooted = false; 1057 1058 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1059 int mProcessLimitOverride = -1; 1060 1061 WindowManagerService mWindowManager; 1062 1063 final ActivityThread mSystemThread; 1064 1065 int mCurrentUserId = 0; 1066 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1067 private UserManagerService mUserManager; 1068 1069 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1070 final ProcessRecord mApp; 1071 final int mPid; 1072 final IApplicationThread mAppThread; 1073 1074 AppDeathRecipient(ProcessRecord app, int pid, 1075 IApplicationThread thread) { 1076 if (localLOGV) Slog.v( 1077 TAG, "New death recipient " + this 1078 + " for thread " + thread.asBinder()); 1079 mApp = app; 1080 mPid = pid; 1081 mAppThread = thread; 1082 } 1083 1084 @Override 1085 public void binderDied() { 1086 if (localLOGV) Slog.v( 1087 TAG, "Death received in " + this 1088 + " for thread " + mAppThread.asBinder()); 1089 synchronized(ActivityManagerService.this) { 1090 appDiedLocked(mApp, mPid, mAppThread); 1091 } 1092 } 1093 } 1094 1095 static final int SHOW_ERROR_MSG = 1; 1096 static final int SHOW_NOT_RESPONDING_MSG = 2; 1097 static final int SHOW_FACTORY_ERROR_MSG = 3; 1098 static final int UPDATE_CONFIGURATION_MSG = 4; 1099 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1100 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1101 static final int SERVICE_TIMEOUT_MSG = 12; 1102 static final int UPDATE_TIME_ZONE = 13; 1103 static final int SHOW_UID_ERROR_MSG = 14; 1104 static final int IM_FEELING_LUCKY_MSG = 15; 1105 static final int PROC_START_TIMEOUT_MSG = 20; 1106 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1107 static final int KILL_APPLICATION_MSG = 22; 1108 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1109 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1110 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1111 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1112 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1113 static final int CLEAR_DNS_CACHE_MSG = 28; 1114 static final int UPDATE_HTTP_PROXY_MSG = 29; 1115 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1116 static final int DISPATCH_PROCESSES_CHANGED = 31; 1117 static final int DISPATCH_PROCESS_DIED = 32; 1118 static final int REPORT_MEM_USAGE_MSG = 33; 1119 static final int REPORT_USER_SWITCH_MSG = 34; 1120 static final int CONTINUE_USER_SWITCH_MSG = 35; 1121 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1122 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1123 static final int PERSIST_URI_GRANTS_MSG = 38; 1124 static final int REQUEST_ALL_PSS_MSG = 39; 1125 static final int START_PROFILES_MSG = 40; 1126 static final int UPDATE_TIME = 41; 1127 static final int SYSTEM_USER_START_MSG = 42; 1128 static final int SYSTEM_USER_CURRENT_MSG = 43; 1129 1130 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1131 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1132 static final int FIRST_COMPAT_MODE_MSG = 300; 1133 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1134 1135 AlertDialog mUidAlert; 1136 CompatModeDialog mCompatModeDialog; 1137 long mLastMemUsageReportTime = 0; 1138 1139 /** 1140 * Flag whether the current user is a "monkey", i.e. whether 1141 * the UI is driven by a UI automation tool. 1142 */ 1143 private boolean mUserIsMonkey; 1144 1145 final ServiceThread mHandlerThread; 1146 final MainHandler mHandler; 1147 1148 final class MainHandler extends Handler { 1149 public MainHandler(Looper looper) { 1150 super(looper, null, true); 1151 } 1152 1153 @Override 1154 public void handleMessage(Message msg) { 1155 switch (msg.what) { 1156 case SHOW_ERROR_MSG: { 1157 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1158 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1159 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1160 synchronized (ActivityManagerService.this) { 1161 ProcessRecord proc = (ProcessRecord)data.get("app"); 1162 AppErrorResult res = (AppErrorResult) data.get("result"); 1163 if (proc != null && proc.crashDialog != null) { 1164 Slog.e(TAG, "App already has crash dialog: " + proc); 1165 if (res != null) { 1166 res.set(0); 1167 } 1168 return; 1169 } 1170 if (!showBackground && UserHandle.getAppId(proc.uid) 1171 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1172 && proc.pid != MY_PID) { 1173 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1174 if (res != null) { 1175 res.set(0); 1176 } 1177 return; 1178 } 1179 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1180 Dialog d = new AppErrorDialog(mContext, 1181 ActivityManagerService.this, res, proc); 1182 d.show(); 1183 proc.crashDialog = d; 1184 } else { 1185 // The device is asleep, so just pretend that the user 1186 // saw a crash dialog and hit "force quit". 1187 if (res != null) { 1188 res.set(0); 1189 } 1190 } 1191 } 1192 1193 ensureBootCompleted(); 1194 } break; 1195 case SHOW_NOT_RESPONDING_MSG: { 1196 synchronized (ActivityManagerService.this) { 1197 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1198 ProcessRecord proc = (ProcessRecord)data.get("app"); 1199 if (proc != null && proc.anrDialog != null) { 1200 Slog.e(TAG, "App already has anr dialog: " + proc); 1201 return; 1202 } 1203 1204 Intent intent = new Intent("android.intent.action.ANR"); 1205 if (!mProcessesReady) { 1206 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1207 | Intent.FLAG_RECEIVER_FOREGROUND); 1208 } 1209 broadcastIntentLocked(null, null, intent, 1210 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1211 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1212 1213 if (mShowDialogs) { 1214 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1215 mContext, proc, (ActivityRecord)data.get("activity"), 1216 msg.arg1 != 0); 1217 d.show(); 1218 proc.anrDialog = d; 1219 } else { 1220 // Just kill the app if there is no dialog to be shown. 1221 killAppAtUsersRequest(proc, null); 1222 } 1223 } 1224 1225 ensureBootCompleted(); 1226 } break; 1227 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1228 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1229 synchronized (ActivityManagerService.this) { 1230 ProcessRecord proc = (ProcessRecord) data.get("app"); 1231 if (proc == null) { 1232 Slog.e(TAG, "App not found when showing strict mode dialog."); 1233 break; 1234 } 1235 if (proc.crashDialog != null) { 1236 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1237 return; 1238 } 1239 AppErrorResult res = (AppErrorResult) data.get("result"); 1240 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1241 Dialog d = new StrictModeViolationDialog(mContext, 1242 ActivityManagerService.this, res, proc); 1243 d.show(); 1244 proc.crashDialog = d; 1245 } else { 1246 // The device is asleep, so just pretend that the user 1247 // saw a crash dialog and hit "force quit". 1248 res.set(0); 1249 } 1250 } 1251 ensureBootCompleted(); 1252 } break; 1253 case SHOW_FACTORY_ERROR_MSG: { 1254 Dialog d = new FactoryErrorDialog( 1255 mContext, msg.getData().getCharSequence("msg")); 1256 d.show(); 1257 ensureBootCompleted(); 1258 } break; 1259 case UPDATE_CONFIGURATION_MSG: { 1260 final ContentResolver resolver = mContext.getContentResolver(); 1261 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1262 } break; 1263 case GC_BACKGROUND_PROCESSES_MSG: { 1264 synchronized (ActivityManagerService.this) { 1265 performAppGcsIfAppropriateLocked(); 1266 } 1267 } break; 1268 case WAIT_FOR_DEBUGGER_MSG: { 1269 synchronized (ActivityManagerService.this) { 1270 ProcessRecord app = (ProcessRecord)msg.obj; 1271 if (msg.arg1 != 0) { 1272 if (!app.waitedForDebugger) { 1273 Dialog d = new AppWaitingForDebuggerDialog( 1274 ActivityManagerService.this, 1275 mContext, app); 1276 app.waitDialog = d; 1277 app.waitedForDebugger = true; 1278 d.show(); 1279 } 1280 } else { 1281 if (app.waitDialog != null) { 1282 app.waitDialog.dismiss(); 1283 app.waitDialog = null; 1284 } 1285 } 1286 } 1287 } break; 1288 case SERVICE_TIMEOUT_MSG: { 1289 if (mDidDexOpt) { 1290 mDidDexOpt = false; 1291 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1292 nmsg.obj = msg.obj; 1293 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1294 return; 1295 } 1296 mServices.serviceTimeout((ProcessRecord)msg.obj); 1297 } break; 1298 case UPDATE_TIME_ZONE: { 1299 synchronized (ActivityManagerService.this) { 1300 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1301 ProcessRecord r = mLruProcesses.get(i); 1302 if (r.thread != null) { 1303 try { 1304 r.thread.updateTimeZone(); 1305 } catch (RemoteException ex) { 1306 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1307 } 1308 } 1309 } 1310 } 1311 } break; 1312 case CLEAR_DNS_CACHE_MSG: { 1313 synchronized (ActivityManagerService.this) { 1314 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1315 ProcessRecord r = mLruProcesses.get(i); 1316 if (r.thread != null) { 1317 try { 1318 r.thread.clearDnsCache(); 1319 } catch (RemoteException ex) { 1320 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1321 } 1322 } 1323 } 1324 } 1325 } break; 1326 case UPDATE_HTTP_PROXY_MSG: { 1327 ProxyInfo proxy = (ProxyInfo)msg.obj; 1328 String host = ""; 1329 String port = ""; 1330 String exclList = ""; 1331 String pacFileUrl = ""; 1332 if (proxy != null) { 1333 host = proxy.getHost(); 1334 port = Integer.toString(proxy.getPort()); 1335 exclList = proxy.getExclusionListAsString(); 1336 if (proxy.getPacFileUrl() != null) { 1337 pacFileUrl = proxy.getPacFileUrl().toString(); 1338 } 1339 } 1340 synchronized (ActivityManagerService.this) { 1341 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1342 ProcessRecord r = mLruProcesses.get(i); 1343 if (r.thread != null) { 1344 try { 1345 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1346 } catch (RemoteException ex) { 1347 Slog.w(TAG, "Failed to update http proxy for: " + 1348 r.info.processName); 1349 } 1350 } 1351 } 1352 } 1353 } break; 1354 case SHOW_UID_ERROR_MSG: { 1355 String title = "System UIDs Inconsistent"; 1356 String text = "UIDs on the system are inconsistent, you need to wipe your" 1357 + " data partition or your device will be unstable."; 1358 Log.e(TAG, title + ": " + text); 1359 if (mShowDialogs) { 1360 // XXX This is a temporary dialog, no need to localize. 1361 AlertDialog d = new BaseErrorDialog(mContext); 1362 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1363 d.setCancelable(false); 1364 d.setTitle(title); 1365 d.setMessage(text); 1366 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1367 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1368 mUidAlert = d; 1369 d.show(); 1370 } 1371 } break; 1372 case IM_FEELING_LUCKY_MSG: { 1373 if (mUidAlert != null) { 1374 mUidAlert.dismiss(); 1375 mUidAlert = null; 1376 } 1377 } break; 1378 case PROC_START_TIMEOUT_MSG: { 1379 if (mDidDexOpt) { 1380 mDidDexOpt = false; 1381 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1382 nmsg.obj = msg.obj; 1383 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1384 return; 1385 } 1386 ProcessRecord app = (ProcessRecord)msg.obj; 1387 synchronized (ActivityManagerService.this) { 1388 processStartTimedOutLocked(app); 1389 } 1390 } break; 1391 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1392 synchronized (ActivityManagerService.this) { 1393 doPendingActivityLaunchesLocked(true); 1394 } 1395 } break; 1396 case KILL_APPLICATION_MSG: { 1397 synchronized (ActivityManagerService.this) { 1398 int appid = msg.arg1; 1399 boolean restart = (msg.arg2 == 1); 1400 Bundle bundle = (Bundle)msg.obj; 1401 String pkg = bundle.getString("pkg"); 1402 String reason = bundle.getString("reason"); 1403 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1404 false, UserHandle.USER_ALL, reason); 1405 } 1406 } break; 1407 case FINALIZE_PENDING_INTENT_MSG: { 1408 ((PendingIntentRecord)msg.obj).completeFinalize(); 1409 } break; 1410 case POST_HEAVY_NOTIFICATION_MSG: { 1411 INotificationManager inm = NotificationManager.getService(); 1412 if (inm == null) { 1413 return; 1414 } 1415 1416 ActivityRecord root = (ActivityRecord)msg.obj; 1417 ProcessRecord process = root.app; 1418 if (process == null) { 1419 return; 1420 } 1421 1422 try { 1423 Context context = mContext.createPackageContext(process.info.packageName, 0); 1424 String text = mContext.getString(R.string.heavy_weight_notification, 1425 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1426 Notification notification = new Notification(); 1427 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1428 notification.when = 0; 1429 notification.flags = Notification.FLAG_ONGOING_EVENT; 1430 notification.tickerText = text; 1431 notification.defaults = 0; // please be quiet 1432 notification.sound = null; 1433 notification.vibrate = null; 1434 notification.setLatestEventInfo(context, text, 1435 mContext.getText(R.string.heavy_weight_notification_detail), 1436 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1437 PendingIntent.FLAG_CANCEL_CURRENT, null, 1438 new UserHandle(root.userId))); 1439 1440 try { 1441 int[] outId = new int[1]; 1442 inm.enqueueNotificationWithTag("android", "android", null, 1443 R.string.heavy_weight_notification, 1444 notification, outId, root.userId); 1445 } catch (RuntimeException e) { 1446 Slog.w(ActivityManagerService.TAG, 1447 "Error showing notification for heavy-weight app", e); 1448 } catch (RemoteException e) { 1449 } 1450 } catch (NameNotFoundException e) { 1451 Slog.w(TAG, "Unable to create context for heavy notification", e); 1452 } 1453 } break; 1454 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1455 INotificationManager inm = NotificationManager.getService(); 1456 if (inm == null) { 1457 return; 1458 } 1459 try { 1460 inm.cancelNotificationWithTag("android", null, 1461 R.string.heavy_weight_notification, msg.arg1); 1462 } catch (RuntimeException e) { 1463 Slog.w(ActivityManagerService.TAG, 1464 "Error canceling notification for service", e); 1465 } catch (RemoteException e) { 1466 } 1467 } break; 1468 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1469 synchronized (ActivityManagerService.this) { 1470 checkExcessivePowerUsageLocked(true); 1471 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1472 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1473 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1474 } 1475 } break; 1476 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1477 synchronized (ActivityManagerService.this) { 1478 ActivityRecord ar = (ActivityRecord)msg.obj; 1479 if (mCompatModeDialog != null) { 1480 if (mCompatModeDialog.mAppInfo.packageName.equals( 1481 ar.info.applicationInfo.packageName)) { 1482 return; 1483 } 1484 mCompatModeDialog.dismiss(); 1485 mCompatModeDialog = null; 1486 } 1487 if (ar != null && false) { 1488 if (mCompatModePackages.getPackageAskCompatModeLocked( 1489 ar.packageName)) { 1490 int mode = mCompatModePackages.computeCompatModeLocked( 1491 ar.info.applicationInfo); 1492 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1493 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1494 mCompatModeDialog = new CompatModeDialog( 1495 ActivityManagerService.this, mContext, 1496 ar.info.applicationInfo); 1497 mCompatModeDialog.show(); 1498 } 1499 } 1500 } 1501 } 1502 break; 1503 } 1504 case DISPATCH_PROCESSES_CHANGED: { 1505 dispatchProcessesChanged(); 1506 break; 1507 } 1508 case DISPATCH_PROCESS_DIED: { 1509 final int pid = msg.arg1; 1510 final int uid = msg.arg2; 1511 dispatchProcessDied(pid, uid); 1512 break; 1513 } 1514 case REPORT_MEM_USAGE_MSG: { 1515 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1516 Thread thread = new Thread() { 1517 @Override public void run() { 1518 final SparseArray<ProcessMemInfo> infoMap 1519 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1520 for (int i=0, N=memInfos.size(); i<N; i++) { 1521 ProcessMemInfo mi = memInfos.get(i); 1522 infoMap.put(mi.pid, mi); 1523 } 1524 updateCpuStatsNow(); 1525 synchronized (mProcessCpuThread) { 1526 final int N = mProcessCpuTracker.countStats(); 1527 for (int i=0; i<N; i++) { 1528 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1529 if (st.vsize > 0) { 1530 long pss = Debug.getPss(st.pid, null); 1531 if (pss > 0) { 1532 if (infoMap.indexOfKey(st.pid) < 0) { 1533 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1534 ProcessList.NATIVE_ADJ, -1, "native", null); 1535 mi.pss = pss; 1536 memInfos.add(mi); 1537 } 1538 } 1539 } 1540 } 1541 } 1542 1543 long totalPss = 0; 1544 for (int i=0, N=memInfos.size(); i<N; i++) { 1545 ProcessMemInfo mi = memInfos.get(i); 1546 if (mi.pss == 0) { 1547 mi.pss = Debug.getPss(mi.pid, null); 1548 } 1549 totalPss += mi.pss; 1550 } 1551 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1552 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1553 if (lhs.oomAdj != rhs.oomAdj) { 1554 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1555 } 1556 if (lhs.pss != rhs.pss) { 1557 return lhs.pss < rhs.pss ? 1 : -1; 1558 } 1559 return 0; 1560 } 1561 }); 1562 1563 StringBuilder tag = new StringBuilder(128); 1564 StringBuilder stack = new StringBuilder(128); 1565 tag.append("Low on memory -- "); 1566 appendMemBucket(tag, totalPss, "total", false); 1567 appendMemBucket(stack, totalPss, "total", true); 1568 1569 StringBuilder logBuilder = new StringBuilder(1024); 1570 logBuilder.append("Low on memory:\n"); 1571 1572 boolean firstLine = true; 1573 int lastOomAdj = Integer.MIN_VALUE; 1574 for (int i=0, N=memInfos.size(); i<N; i++) { 1575 ProcessMemInfo mi = memInfos.get(i); 1576 1577 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1578 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1579 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1580 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1581 if (lastOomAdj != mi.oomAdj) { 1582 lastOomAdj = mi.oomAdj; 1583 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1584 tag.append(" / "); 1585 } 1586 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1587 if (firstLine) { 1588 stack.append(":"); 1589 firstLine = false; 1590 } 1591 stack.append("\n\t at "); 1592 } else { 1593 stack.append("$"); 1594 } 1595 } else { 1596 tag.append(" "); 1597 stack.append("$"); 1598 } 1599 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1600 appendMemBucket(tag, mi.pss, mi.name, false); 1601 } 1602 appendMemBucket(stack, mi.pss, mi.name, true); 1603 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1604 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1605 stack.append("("); 1606 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1607 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1608 stack.append(DUMP_MEM_OOM_LABEL[k]); 1609 stack.append(":"); 1610 stack.append(DUMP_MEM_OOM_ADJ[k]); 1611 } 1612 } 1613 stack.append(")"); 1614 } 1615 } 1616 1617 logBuilder.append(" "); 1618 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1619 logBuilder.append(' '); 1620 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1621 logBuilder.append(' '); 1622 ProcessList.appendRamKb(logBuilder, mi.pss); 1623 logBuilder.append(" kB: "); 1624 logBuilder.append(mi.name); 1625 logBuilder.append(" ("); 1626 logBuilder.append(mi.pid); 1627 logBuilder.append(") "); 1628 logBuilder.append(mi.adjType); 1629 logBuilder.append('\n'); 1630 if (mi.adjReason != null) { 1631 logBuilder.append(" "); 1632 logBuilder.append(mi.adjReason); 1633 logBuilder.append('\n'); 1634 } 1635 } 1636 1637 logBuilder.append(" "); 1638 ProcessList.appendRamKb(logBuilder, totalPss); 1639 logBuilder.append(" kB: TOTAL\n"); 1640 1641 long[] infos = new long[Debug.MEMINFO_COUNT]; 1642 Debug.getMemInfo(infos); 1643 logBuilder.append(" MemInfo: "); 1644 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1645 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1646 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1647 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1648 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1649 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1650 logBuilder.append(" ZRAM: "); 1651 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1652 logBuilder.append(" kB RAM, "); 1653 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1654 logBuilder.append(" kB swap total, "); 1655 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1656 logBuilder.append(" kB swap free\n"); 1657 } 1658 Slog.i(TAG, logBuilder.toString()); 1659 1660 StringBuilder dropBuilder = new StringBuilder(1024); 1661 /* 1662 StringWriter oomSw = new StringWriter(); 1663 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1664 StringWriter catSw = new StringWriter(); 1665 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1666 String[] emptyArgs = new String[] { }; 1667 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1668 oomPw.flush(); 1669 String oomString = oomSw.toString(); 1670 */ 1671 dropBuilder.append(stack); 1672 dropBuilder.append('\n'); 1673 dropBuilder.append('\n'); 1674 dropBuilder.append(logBuilder); 1675 dropBuilder.append('\n'); 1676 /* 1677 dropBuilder.append(oomString); 1678 dropBuilder.append('\n'); 1679 */ 1680 StringWriter catSw = new StringWriter(); 1681 synchronized (ActivityManagerService.this) { 1682 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1683 String[] emptyArgs = new String[] { }; 1684 catPw.println(); 1685 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1686 catPw.println(); 1687 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1688 false, false, null); 1689 catPw.println(); 1690 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1691 catPw.flush(); 1692 } 1693 dropBuilder.append(catSw.toString()); 1694 addErrorToDropBox("lowmem", null, "system_server", null, 1695 null, tag.toString(), dropBuilder.toString(), null, null); 1696 //Slog.i(TAG, "Sent to dropbox:"); 1697 //Slog.i(TAG, dropBuilder.toString()); 1698 synchronized (ActivityManagerService.this) { 1699 long now = SystemClock.uptimeMillis(); 1700 if (mLastMemUsageReportTime < now) { 1701 mLastMemUsageReportTime = now; 1702 } 1703 } 1704 } 1705 }; 1706 thread.start(); 1707 break; 1708 } 1709 case REPORT_USER_SWITCH_MSG: { 1710 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1711 break; 1712 } 1713 case CONTINUE_USER_SWITCH_MSG: { 1714 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1715 break; 1716 } 1717 case USER_SWITCH_TIMEOUT_MSG: { 1718 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1719 break; 1720 } 1721 case IMMERSIVE_MODE_LOCK_MSG: { 1722 final boolean nextState = (msg.arg1 != 0); 1723 if (mUpdateLock.isHeld() != nextState) { 1724 if (DEBUG_IMMERSIVE) { 1725 final ActivityRecord r = (ActivityRecord) msg.obj; 1726 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1727 } 1728 if (nextState) { 1729 mUpdateLock.acquire(); 1730 } else { 1731 mUpdateLock.release(); 1732 } 1733 } 1734 break; 1735 } 1736 case PERSIST_URI_GRANTS_MSG: { 1737 writeGrantedUriPermissions(); 1738 break; 1739 } 1740 case REQUEST_ALL_PSS_MSG: { 1741 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1742 break; 1743 } 1744 case START_PROFILES_MSG: { 1745 synchronized (ActivityManagerService.this) { 1746 startProfilesLocked(); 1747 } 1748 break; 1749 } 1750 case UPDATE_TIME: { 1751 synchronized (ActivityManagerService.this) { 1752 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1753 ProcessRecord r = mLruProcesses.get(i); 1754 if (r.thread != null) { 1755 try { 1756 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1757 } catch (RemoteException ex) { 1758 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1759 } 1760 } 1761 } 1762 } 1763 break; 1764 } 1765 case SYSTEM_USER_START_MSG: { 1766 mSystemServiceManager.startUser(msg.arg1); 1767 break; 1768 } 1769 case SYSTEM_USER_CURRENT_MSG: { 1770 mSystemServiceManager.switchUser(msg.arg1); 1771 break; 1772 } 1773 } 1774 } 1775 }; 1776 1777 static final int COLLECT_PSS_BG_MSG = 1; 1778 1779 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1780 @Override 1781 public void handleMessage(Message msg) { 1782 switch (msg.what) { 1783 case COLLECT_PSS_BG_MSG: { 1784 int i=0, num=0; 1785 long start = SystemClock.uptimeMillis(); 1786 long[] tmp = new long[1]; 1787 do { 1788 ProcessRecord proc; 1789 int procState; 1790 int pid; 1791 synchronized (ActivityManagerService.this) { 1792 if (i >= mPendingPssProcesses.size()) { 1793 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1794 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1795 mPendingPssProcesses.clear(); 1796 return; 1797 } 1798 proc = mPendingPssProcesses.get(i); 1799 procState = proc.pssProcState; 1800 if (proc.thread != null && procState == proc.setProcState) { 1801 pid = proc.pid; 1802 } else { 1803 proc = null; 1804 pid = 0; 1805 } 1806 i++; 1807 } 1808 if (proc != null) { 1809 long pss = Debug.getPss(pid, tmp); 1810 synchronized (ActivityManagerService.this) { 1811 if (proc.thread != null && proc.setProcState == procState 1812 && proc.pid == pid) { 1813 num++; 1814 proc.lastPssTime = SystemClock.uptimeMillis(); 1815 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1816 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1817 + ": " + pss + " lastPss=" + proc.lastPss 1818 + " state=" + ProcessList.makeProcStateString(procState)); 1819 if (proc.initialIdlePss == 0) { 1820 proc.initialIdlePss = pss; 1821 } 1822 proc.lastPss = pss; 1823 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1824 proc.lastCachedPss = pss; 1825 } 1826 } 1827 } 1828 } 1829 } while (true); 1830 } 1831 } 1832 } 1833 }; 1834 1835 /** 1836 * Monitor for package changes and update our internal state. 1837 */ 1838 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1839 @Override 1840 public void onPackageRemoved(String packageName, int uid) { 1841 // Remove all tasks with activities in the specified package from the list of recent tasks 1842 synchronized (ActivityManagerService.this) { 1843 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1844 TaskRecord tr = mRecentTasks.get(i); 1845 ComponentName cn = tr.intent.getComponent(); 1846 if (cn != null && cn.getPackageName().equals(packageName)) { 1847 // If the package name matches, remove the task and kill the process 1848 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1849 } 1850 } 1851 } 1852 } 1853 1854 @Override 1855 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1856 onPackageModified(packageName); 1857 return true; 1858 } 1859 1860 @Override 1861 public void onPackageModified(String packageName) { 1862 final PackageManager pm = mContext.getPackageManager(); 1863 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1864 new ArrayList<Pair<Intent, Integer>>(); 1865 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1866 // Copy the list of recent tasks so that we don't hold onto the lock on 1867 // ActivityManagerService for long periods while checking if components exist. 1868 synchronized (ActivityManagerService.this) { 1869 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1870 TaskRecord tr = mRecentTasks.get(i); 1871 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1872 } 1873 } 1874 // Check the recent tasks and filter out all tasks with components that no longer exist. 1875 Intent tmpI = new Intent(); 1876 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1877 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1878 ComponentName cn = p.first.getComponent(); 1879 if (cn != null && cn.getPackageName().equals(packageName)) { 1880 try { 1881 // Add the task to the list to remove if the component no longer exists 1882 tmpI.setComponent(cn); 1883 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1884 tasksToRemove.add(p.second); 1885 } 1886 } catch (Exception e) {} 1887 } 1888 } 1889 // Prune all the tasks with removed components from the list of recent tasks 1890 synchronized (ActivityManagerService.this) { 1891 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1892 // Remove the task but don't kill the process (since other components in that 1893 // package may still be running and in the background) 1894 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1895 } 1896 } 1897 } 1898 1899 @Override 1900 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1901 // Force stop the specified packages 1902 if (packages != null) { 1903 for (String pkg : packages) { 1904 synchronized (ActivityManagerService.this) { 1905 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1906 "finished booting")) { 1907 return true; 1908 } 1909 } 1910 } 1911 } 1912 return false; 1913 } 1914 }; 1915 1916 public void setSystemProcess() { 1917 try { 1918 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1919 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1920 ServiceManager.addService("meminfo", new MemBinder(this)); 1921 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1922 ServiceManager.addService("dbinfo", new DbBinder(this)); 1923 if (MONITOR_CPU_USAGE) { 1924 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1925 } 1926 ServiceManager.addService("permission", new PermissionController(this)); 1927 1928 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1929 "android", STOCK_PM_FLAGS); 1930 mSystemThread.installSystemApplicationInfo(info); 1931 1932 synchronized (this) { 1933 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1934 app.persistent = true; 1935 app.pid = MY_PID; 1936 app.maxAdj = ProcessList.SYSTEM_ADJ; 1937 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1938 mProcessNames.put(app.processName, app.uid, app); 1939 synchronized (mPidsSelfLocked) { 1940 mPidsSelfLocked.put(app.pid, app); 1941 } 1942 updateLruProcessLocked(app, false, null); 1943 updateOomAdjLocked(); 1944 } 1945 } catch (PackageManager.NameNotFoundException e) { 1946 throw new RuntimeException( 1947 "Unable to find android system package", e); 1948 } 1949 } 1950 1951 public void setWindowManager(WindowManagerService wm) { 1952 mWindowManager = wm; 1953 mStackSupervisor.setWindowManager(wm); 1954 } 1955 1956 public void startObservingNativeCrashes() { 1957 final NativeCrashListener ncl = new NativeCrashListener(this); 1958 ncl.start(); 1959 } 1960 1961 public IAppOpsService getAppOpsService() { 1962 return mAppOpsService; 1963 } 1964 1965 static class MemBinder extends Binder { 1966 ActivityManagerService mActivityManagerService; 1967 MemBinder(ActivityManagerService activityManagerService) { 1968 mActivityManagerService = activityManagerService; 1969 } 1970 1971 @Override 1972 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1973 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1974 != PackageManager.PERMISSION_GRANTED) { 1975 pw.println("Permission Denial: can't dump meminfo from from pid=" 1976 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1977 + " without permission " + android.Manifest.permission.DUMP); 1978 return; 1979 } 1980 1981 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1982 } 1983 } 1984 1985 static class GraphicsBinder extends Binder { 1986 ActivityManagerService mActivityManagerService; 1987 GraphicsBinder(ActivityManagerService activityManagerService) { 1988 mActivityManagerService = activityManagerService; 1989 } 1990 1991 @Override 1992 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1993 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1994 != PackageManager.PERMISSION_GRANTED) { 1995 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1996 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1997 + " without permission " + android.Manifest.permission.DUMP); 1998 return; 1999 } 2000 2001 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2002 } 2003 } 2004 2005 static class DbBinder extends Binder { 2006 ActivityManagerService mActivityManagerService; 2007 DbBinder(ActivityManagerService activityManagerService) { 2008 mActivityManagerService = activityManagerService; 2009 } 2010 2011 @Override 2012 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2013 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2014 != PackageManager.PERMISSION_GRANTED) { 2015 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2016 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2017 + " without permission " + android.Manifest.permission.DUMP); 2018 return; 2019 } 2020 2021 mActivityManagerService.dumpDbInfo(fd, pw, args); 2022 } 2023 } 2024 2025 static class CpuBinder extends Binder { 2026 ActivityManagerService mActivityManagerService; 2027 CpuBinder(ActivityManagerService activityManagerService) { 2028 mActivityManagerService = activityManagerService; 2029 } 2030 2031 @Override 2032 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2033 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2034 != PackageManager.PERMISSION_GRANTED) { 2035 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2036 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2037 + " without permission " + android.Manifest.permission.DUMP); 2038 return; 2039 } 2040 2041 synchronized (mActivityManagerService.mProcessCpuThread) { 2042 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2043 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2044 SystemClock.uptimeMillis())); 2045 } 2046 } 2047 } 2048 2049 public static final class Lifecycle extends SystemService { 2050 private final ActivityManagerService mService; 2051 2052 public Lifecycle(Context context) { 2053 super(context); 2054 mService = new ActivityManagerService(context); 2055 } 2056 2057 @Override 2058 public void onStart() { 2059 mService.start(); 2060 } 2061 2062 public ActivityManagerService getService() { 2063 return mService; 2064 } 2065 } 2066 2067 // Note: This method is invoked on the main thread but may need to attach various 2068 // handlers to other threads. So take care to be explicit about the looper. 2069 public ActivityManagerService(Context systemContext) { 2070 mContext = systemContext; 2071 mFactoryTest = FactoryTest.getMode(); 2072 mSystemThread = ActivityThread.currentActivityThread(); 2073 2074 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2075 2076 mHandlerThread = new ServiceThread(TAG, 2077 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2078 mHandlerThread.start(); 2079 mHandler = new MainHandler(mHandlerThread.getLooper()); 2080 2081 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2082 "foreground", BROADCAST_FG_TIMEOUT, false); 2083 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2084 "background", BROADCAST_BG_TIMEOUT, true); 2085 mBroadcastQueues[0] = mFgBroadcastQueue; 2086 mBroadcastQueues[1] = mBgBroadcastQueue; 2087 2088 mServices = new ActiveServices(this); 2089 mProviderMap = new ProviderMap(this); 2090 2091 // TODO: Move creation of battery stats service outside of activity manager service. 2092 File dataDir = Environment.getDataDirectory(); 2093 File systemDir = new File(dataDir, "system"); 2094 systemDir.mkdirs(); 2095 mBatteryStatsService = new BatteryStatsService(new File( 2096 systemDir, "batterystats.bin").toString(), mHandler); 2097 mBatteryStatsService.getActiveStatistics().readLocked(); 2098 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2099 mOnBattery = DEBUG_POWER ? true 2100 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2101 mBatteryStatsService.getActiveStatistics().setCallback(this); 2102 2103 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2104 2105 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2106 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2107 2108 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2109 2110 // User 0 is the first and only user that runs at boot. 2111 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2112 mUserLru.add(Integer.valueOf(0)); 2113 updateStartedUserArrayLocked(); 2114 2115 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2116 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2117 2118 mConfiguration.setToDefaults(); 2119 mConfiguration.setLocale(Locale.getDefault()); 2120 2121 mConfigurationSeq = mConfiguration.seq = 1; 2122 mProcessCpuTracker.init(); 2123 2124 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2125 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2126 mStackSupervisor = new ActivityStackSupervisor(this); 2127 2128 mProcessCpuThread = new Thread("CpuTracker") { 2129 @Override 2130 public void run() { 2131 while (true) { 2132 try { 2133 try { 2134 synchronized(this) { 2135 final long now = SystemClock.uptimeMillis(); 2136 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2137 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2138 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2139 // + ", write delay=" + nextWriteDelay); 2140 if (nextWriteDelay < nextCpuDelay) { 2141 nextCpuDelay = nextWriteDelay; 2142 } 2143 if (nextCpuDelay > 0) { 2144 mProcessCpuMutexFree.set(true); 2145 this.wait(nextCpuDelay); 2146 } 2147 } 2148 } catch (InterruptedException e) { 2149 } 2150 updateCpuStatsNow(); 2151 } catch (Exception e) { 2152 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2153 } 2154 } 2155 } 2156 }; 2157 2158 Watchdog.getInstance().addMonitor(this); 2159 Watchdog.getInstance().addThread(mHandler); 2160 } 2161 2162 public void setSystemServiceManager(SystemServiceManager mgr) { 2163 mSystemServiceManager = mgr; 2164 } 2165 2166 private void start() { 2167 mProcessCpuThread.start(); 2168 2169 mBatteryStatsService.publish(mContext); 2170 mUsageStatsService.publish(mContext); 2171 mAppOpsService.publish(mContext); 2172 2173 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2174 } 2175 2176 @Override 2177 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2178 throws RemoteException { 2179 if (code == SYSPROPS_TRANSACTION) { 2180 // We need to tell all apps about the system property change. 2181 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2182 synchronized(this) { 2183 final int NP = mProcessNames.getMap().size(); 2184 for (int ip=0; ip<NP; ip++) { 2185 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2186 final int NA = apps.size(); 2187 for (int ia=0; ia<NA; ia++) { 2188 ProcessRecord app = apps.valueAt(ia); 2189 if (app.thread != null) { 2190 procs.add(app.thread.asBinder()); 2191 } 2192 } 2193 } 2194 } 2195 2196 int N = procs.size(); 2197 for (int i=0; i<N; i++) { 2198 Parcel data2 = Parcel.obtain(); 2199 try { 2200 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2201 } catch (RemoteException e) { 2202 } 2203 data2.recycle(); 2204 } 2205 } 2206 try { 2207 return super.onTransact(code, data, reply, flags); 2208 } catch (RuntimeException e) { 2209 // The activity manager only throws security exceptions, so let's 2210 // log all others. 2211 if (!(e instanceof SecurityException)) { 2212 Slog.wtf(TAG, "Activity Manager Crash", e); 2213 } 2214 throw e; 2215 } 2216 } 2217 2218 void updateCpuStats() { 2219 final long now = SystemClock.uptimeMillis(); 2220 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2221 return; 2222 } 2223 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2224 synchronized (mProcessCpuThread) { 2225 mProcessCpuThread.notify(); 2226 } 2227 } 2228 } 2229 2230 void updateCpuStatsNow() { 2231 synchronized (mProcessCpuThread) { 2232 mProcessCpuMutexFree.set(false); 2233 final long now = SystemClock.uptimeMillis(); 2234 boolean haveNewCpuStats = false; 2235 2236 if (MONITOR_CPU_USAGE && 2237 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2238 mLastCpuTime.set(now); 2239 haveNewCpuStats = true; 2240 mProcessCpuTracker.update(); 2241 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2242 //Slog.i(TAG, "Total CPU usage: " 2243 // + mProcessCpu.getTotalCpuPercent() + "%"); 2244 2245 // Slog the cpu usage if the property is set. 2246 if ("true".equals(SystemProperties.get("events.cpu"))) { 2247 int user = mProcessCpuTracker.getLastUserTime(); 2248 int system = mProcessCpuTracker.getLastSystemTime(); 2249 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2250 int irq = mProcessCpuTracker.getLastIrqTime(); 2251 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2252 int idle = mProcessCpuTracker.getLastIdleTime(); 2253 2254 int total = user + system + iowait + irq + softIrq + idle; 2255 if (total == 0) total = 1; 2256 2257 EventLog.writeEvent(EventLogTags.CPU, 2258 ((user+system+iowait+irq+softIrq) * 100) / total, 2259 (user * 100) / total, 2260 (system * 100) / total, 2261 (iowait * 100) / total, 2262 (irq * 100) / total, 2263 (softIrq * 100) / total); 2264 } 2265 } 2266 2267 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2268 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2269 synchronized(bstats) { 2270 synchronized(mPidsSelfLocked) { 2271 if (haveNewCpuStats) { 2272 if (mOnBattery) { 2273 int perc = bstats.startAddingCpuLocked(); 2274 int totalUTime = 0; 2275 int totalSTime = 0; 2276 final int N = mProcessCpuTracker.countStats(); 2277 for (int i=0; i<N; i++) { 2278 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2279 if (!st.working) { 2280 continue; 2281 } 2282 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2283 int otherUTime = (st.rel_utime*perc)/100; 2284 int otherSTime = (st.rel_stime*perc)/100; 2285 totalUTime += otherUTime; 2286 totalSTime += otherSTime; 2287 if (pr != null) { 2288 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2289 if (ps == null || !ps.isActive()) { 2290 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2291 pr.info.uid, pr.processName); 2292 } 2293 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2294 st.rel_stime-otherSTime); 2295 ps.addSpeedStepTimes(cpuSpeedTimes); 2296 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2297 } else { 2298 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2299 if (ps == null || !ps.isActive()) { 2300 st.batteryStats = ps = bstats.getProcessStatsLocked( 2301 bstats.mapUid(st.uid), st.name); 2302 } 2303 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2304 st.rel_stime-otherSTime); 2305 ps.addSpeedStepTimes(cpuSpeedTimes); 2306 } 2307 } 2308 bstats.finishAddingCpuLocked(perc, totalUTime, 2309 totalSTime, cpuSpeedTimes); 2310 } 2311 } 2312 } 2313 2314 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2315 mLastWriteTime = now; 2316 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2317 } 2318 } 2319 } 2320 } 2321 2322 @Override 2323 public void batteryNeedsCpuUpdate() { 2324 updateCpuStatsNow(); 2325 } 2326 2327 @Override 2328 public void batteryPowerChanged(boolean onBattery) { 2329 // When plugging in, update the CPU stats first before changing 2330 // the plug state. 2331 updateCpuStatsNow(); 2332 synchronized (this) { 2333 synchronized(mPidsSelfLocked) { 2334 mOnBattery = DEBUG_POWER ? true : onBattery; 2335 } 2336 } 2337 } 2338 2339 /** 2340 * Initialize the application bind args. These are passed to each 2341 * process when the bindApplication() IPC is sent to the process. They're 2342 * lazily setup to make sure the services are running when they're asked for. 2343 */ 2344 private HashMap<String, IBinder> getCommonServicesLocked() { 2345 if (mAppBindArgs == null) { 2346 mAppBindArgs = new HashMap<String, IBinder>(); 2347 2348 // Setup the application init args 2349 mAppBindArgs.put("package", ServiceManager.getService("package")); 2350 mAppBindArgs.put("window", ServiceManager.getService("window")); 2351 mAppBindArgs.put(Context.ALARM_SERVICE, 2352 ServiceManager.getService(Context.ALARM_SERVICE)); 2353 } 2354 return mAppBindArgs; 2355 } 2356 2357 final void setFocusedActivityLocked(ActivityRecord r) { 2358 if (mFocusedActivity != r) { 2359 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2360 mFocusedActivity = r; 2361 if (r.task != null && r.task.voiceInteractor != null) { 2362 startRunningVoiceLocked(); 2363 } else { 2364 finishRunningVoiceLocked(); 2365 } 2366 mStackSupervisor.setFocusedStack(r); 2367 if (r != null) { 2368 mWindowManager.setFocusedApp(r.appToken, true); 2369 } 2370 applyUpdateLockStateLocked(r); 2371 } 2372 } 2373 2374 final void clearFocusedActivity(ActivityRecord r) { 2375 if (mFocusedActivity == r) { 2376 mFocusedActivity = null; 2377 } 2378 } 2379 2380 @Override 2381 public void setFocusedStack(int stackId) { 2382 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2383 synchronized (ActivityManagerService.this) { 2384 ActivityStack stack = mStackSupervisor.getStack(stackId); 2385 if (stack != null) { 2386 ActivityRecord r = stack.topRunningActivityLocked(null); 2387 if (r != null) { 2388 setFocusedActivityLocked(r); 2389 } 2390 } 2391 } 2392 } 2393 2394 @Override 2395 public void notifyActivityDrawn(IBinder token) { 2396 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2397 synchronized (this) { 2398 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2399 if (r != null) { 2400 r.task.stack.notifyActivityDrawnLocked(r); 2401 } 2402 } 2403 } 2404 2405 final void applyUpdateLockStateLocked(ActivityRecord r) { 2406 // Modifications to the UpdateLock state are done on our handler, outside 2407 // the activity manager's locks. The new state is determined based on the 2408 // state *now* of the relevant activity record. The object is passed to 2409 // the handler solely for logging detail, not to be consulted/modified. 2410 final boolean nextState = r != null && r.immersive; 2411 mHandler.sendMessage( 2412 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2413 } 2414 2415 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2416 Message msg = Message.obtain(); 2417 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2418 msg.obj = r.task.askedCompatMode ? null : r; 2419 mHandler.sendMessage(msg); 2420 } 2421 2422 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2423 String what, Object obj, ProcessRecord srcApp) { 2424 app.lastActivityTime = now; 2425 2426 if (app.activities.size() > 0) { 2427 // Don't want to touch dependent processes that are hosting activities. 2428 return index; 2429 } 2430 2431 int lrui = mLruProcesses.lastIndexOf(app); 2432 if (lrui < 0) { 2433 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2434 + what + " " + obj + " from " + srcApp); 2435 return index; 2436 } 2437 2438 if (lrui >= index) { 2439 // Don't want to cause this to move dependent processes *back* in the 2440 // list as if they were less frequently used. 2441 return index; 2442 } 2443 2444 if (lrui >= mLruProcessActivityStart) { 2445 // Don't want to touch dependent processes that are hosting activities. 2446 return index; 2447 } 2448 2449 mLruProcesses.remove(lrui); 2450 if (index > 0) { 2451 index--; 2452 } 2453 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2454 + " in LRU list: " + app); 2455 mLruProcesses.add(index, app); 2456 return index; 2457 } 2458 2459 final void removeLruProcessLocked(ProcessRecord app) { 2460 int lrui = mLruProcesses.lastIndexOf(app); 2461 if (lrui >= 0) { 2462 if (lrui <= mLruProcessActivityStart) { 2463 mLruProcessActivityStart--; 2464 } 2465 if (lrui <= mLruProcessServiceStart) { 2466 mLruProcessServiceStart--; 2467 } 2468 mLruProcesses.remove(lrui); 2469 } 2470 } 2471 2472 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2473 ProcessRecord client) { 2474 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2475 || app.treatLikeActivity; 2476 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2477 if (!activityChange && hasActivity) { 2478 // The process has activities, so we are only allowing activity-based adjustments 2479 // to move it. It should be kept in the front of the list with other 2480 // processes that have activities, and we don't want those to change their 2481 // order except due to activity operations. 2482 return; 2483 } 2484 2485 mLruSeq++; 2486 final long now = SystemClock.uptimeMillis(); 2487 app.lastActivityTime = now; 2488 2489 // First a quick reject: if the app is already at the position we will 2490 // put it, then there is nothing to do. 2491 if (hasActivity) { 2492 final int N = mLruProcesses.size(); 2493 if (N > 0 && mLruProcesses.get(N-1) == app) { 2494 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2495 return; 2496 } 2497 } else { 2498 if (mLruProcessServiceStart > 0 2499 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2500 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2501 return; 2502 } 2503 } 2504 2505 int lrui = mLruProcesses.lastIndexOf(app); 2506 2507 if (app.persistent && lrui >= 0) { 2508 // We don't care about the position of persistent processes, as long as 2509 // they are in the list. 2510 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2511 return; 2512 } 2513 2514 /* In progress: compute new position first, so we can avoid doing work 2515 if the process is not actually going to move. Not yet working. 2516 int addIndex; 2517 int nextIndex; 2518 boolean inActivity = false, inService = false; 2519 if (hasActivity) { 2520 // Process has activities, put it at the very tipsy-top. 2521 addIndex = mLruProcesses.size(); 2522 nextIndex = mLruProcessServiceStart; 2523 inActivity = true; 2524 } else if (hasService) { 2525 // Process has services, put it at the top of the service list. 2526 addIndex = mLruProcessActivityStart; 2527 nextIndex = mLruProcessServiceStart; 2528 inActivity = true; 2529 inService = true; 2530 } else { 2531 // Process not otherwise of interest, it goes to the top of the non-service area. 2532 addIndex = mLruProcessServiceStart; 2533 if (client != null) { 2534 int clientIndex = mLruProcesses.lastIndexOf(client); 2535 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2536 + app); 2537 if (clientIndex >= 0 && addIndex > clientIndex) { 2538 addIndex = clientIndex; 2539 } 2540 } 2541 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2542 } 2543 2544 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2545 + mLruProcessActivityStart + "): " + app); 2546 */ 2547 2548 if (lrui >= 0) { 2549 if (lrui < mLruProcessActivityStart) { 2550 mLruProcessActivityStart--; 2551 } 2552 if (lrui < mLruProcessServiceStart) { 2553 mLruProcessServiceStart--; 2554 } 2555 /* 2556 if (addIndex > lrui) { 2557 addIndex--; 2558 } 2559 if (nextIndex > lrui) { 2560 nextIndex--; 2561 } 2562 */ 2563 mLruProcesses.remove(lrui); 2564 } 2565 2566 /* 2567 mLruProcesses.add(addIndex, app); 2568 if (inActivity) { 2569 mLruProcessActivityStart++; 2570 } 2571 if (inService) { 2572 mLruProcessActivityStart++; 2573 } 2574 */ 2575 2576 int nextIndex; 2577 if (hasActivity) { 2578 final int N = mLruProcesses.size(); 2579 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2580 // Process doesn't have activities, but has clients with 2581 // activities... move it up, but one below the top (the top 2582 // should always have a real activity). 2583 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2584 mLruProcesses.add(N-1, app); 2585 // To keep it from spamming the LRU list (by making a bunch of clients), 2586 // we will push down any other entries owned by the app. 2587 final int uid = app.info.uid; 2588 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2589 ProcessRecord subProc = mLruProcesses.get(i); 2590 if (subProc.info.uid == uid) { 2591 // We want to push this one down the list. If the process after 2592 // it is for the same uid, however, don't do so, because we don't 2593 // want them internally to be re-ordered. 2594 if (mLruProcesses.get(i-1).info.uid != uid) { 2595 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2596 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2597 ProcessRecord tmp = mLruProcesses.get(i); 2598 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2599 mLruProcesses.set(i-1, tmp); 2600 i--; 2601 } 2602 } else { 2603 // A gap, we can stop here. 2604 break; 2605 } 2606 } 2607 } else { 2608 // Process has activities, put it at the very tipsy-top. 2609 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2610 mLruProcesses.add(app); 2611 } 2612 nextIndex = mLruProcessServiceStart; 2613 } else if (hasService) { 2614 // Process has services, put it at the top of the service list. 2615 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2616 mLruProcesses.add(mLruProcessActivityStart, app); 2617 nextIndex = mLruProcessServiceStart; 2618 mLruProcessActivityStart++; 2619 } else { 2620 // Process not otherwise of interest, it goes to the top of the non-service area. 2621 int index = mLruProcessServiceStart; 2622 if (client != null) { 2623 // If there is a client, don't allow the process to be moved up higher 2624 // in the list than that client. 2625 int clientIndex = mLruProcesses.lastIndexOf(client); 2626 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2627 + " when updating " + app); 2628 if (clientIndex <= lrui) { 2629 // Don't allow the client index restriction to push it down farther in the 2630 // list than it already is. 2631 clientIndex = lrui; 2632 } 2633 if (clientIndex >= 0 && index > clientIndex) { 2634 index = clientIndex; 2635 } 2636 } 2637 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2638 mLruProcesses.add(index, app); 2639 nextIndex = index-1; 2640 mLruProcessActivityStart++; 2641 mLruProcessServiceStart++; 2642 } 2643 2644 // If the app is currently using a content provider or service, 2645 // bump those processes as well. 2646 for (int j=app.connections.size()-1; j>=0; j--) { 2647 ConnectionRecord cr = app.connections.valueAt(j); 2648 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2649 && cr.binding.service.app != null 2650 && cr.binding.service.app.lruSeq != mLruSeq 2651 && !cr.binding.service.app.persistent) { 2652 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2653 "service connection", cr, app); 2654 } 2655 } 2656 for (int j=app.conProviders.size()-1; j>=0; j--) { 2657 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2658 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2659 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2660 "provider reference", cpr, app); 2661 } 2662 } 2663 } 2664 2665 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2666 if (uid == Process.SYSTEM_UID) { 2667 // The system gets to run in any process. If there are multiple 2668 // processes with the same uid, just pick the first (this 2669 // should never happen). 2670 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2671 if (procs == null) return null; 2672 final int N = procs.size(); 2673 for (int i = 0; i < N; i++) { 2674 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2675 } 2676 } 2677 ProcessRecord proc = mProcessNames.get(processName, uid); 2678 if (false && proc != null && !keepIfLarge 2679 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2680 && proc.lastCachedPss >= 4000) { 2681 // Turn this condition on to cause killing to happen regularly, for testing. 2682 if (proc.baseProcessTracker != null) { 2683 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2684 } 2685 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2686 + "k from cached"); 2687 } else if (proc != null && !keepIfLarge 2688 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2689 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2690 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2691 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2692 if (proc.baseProcessTracker != null) { 2693 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2694 } 2695 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2696 + "k from cached"); 2697 } 2698 } 2699 return proc; 2700 } 2701 2702 void ensurePackageDexOpt(String packageName) { 2703 IPackageManager pm = AppGlobals.getPackageManager(); 2704 try { 2705 if (pm.performDexOpt(packageName)) { 2706 mDidDexOpt = true; 2707 } 2708 } catch (RemoteException e) { 2709 } 2710 } 2711 2712 boolean isNextTransitionForward() { 2713 int transit = mWindowManager.getPendingAppTransition(); 2714 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2715 || transit == AppTransition.TRANSIT_TASK_OPEN 2716 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2717 } 2718 2719 final ProcessRecord startProcessLocked(String processName, 2720 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2721 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2722 boolean isolated, boolean keepIfLarge) { 2723 ProcessRecord app; 2724 if (!isolated) { 2725 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2726 } else { 2727 // If this is an isolated process, it can't re-use an existing process. 2728 app = null; 2729 } 2730 // We don't have to do anything more if: 2731 // (1) There is an existing application record; and 2732 // (2) The caller doesn't think it is dead, OR there is no thread 2733 // object attached to it so we know it couldn't have crashed; and 2734 // (3) There is a pid assigned to it, so it is either starting or 2735 // already running. 2736 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2737 + " app=" + app + " knownToBeDead=" + knownToBeDead 2738 + " thread=" + (app != null ? app.thread : null) 2739 + " pid=" + (app != null ? app.pid : -1)); 2740 if (app != null && app.pid > 0) { 2741 if (!knownToBeDead || app.thread == null) { 2742 // We already have the app running, or are waiting for it to 2743 // come up (we have a pid but not yet its thread), so keep it. 2744 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2745 // If this is a new package in the process, add the package to the list 2746 app.addPackage(info.packageName, mProcessStats); 2747 return app; 2748 } 2749 2750 // An application record is attached to a previous process, 2751 // clean it up now. 2752 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2753 handleAppDiedLocked(app, true, true); 2754 } 2755 2756 String hostingNameStr = hostingName != null 2757 ? hostingName.flattenToShortString() : null; 2758 2759 if (!isolated) { 2760 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2761 // If we are in the background, then check to see if this process 2762 // is bad. If so, we will just silently fail. 2763 if (mBadProcesses.get(info.processName, info.uid) != null) { 2764 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2765 + "/" + info.processName); 2766 return null; 2767 } 2768 } else { 2769 // When the user is explicitly starting a process, then clear its 2770 // crash count so that we won't make it bad until they see at 2771 // least one crash dialog again, and make the process good again 2772 // if it had been bad. 2773 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2774 + "/" + info.processName); 2775 mProcessCrashTimes.remove(info.processName, info.uid); 2776 if (mBadProcesses.get(info.processName, info.uid) != null) { 2777 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2778 UserHandle.getUserId(info.uid), info.uid, 2779 info.processName); 2780 mBadProcesses.remove(info.processName, info.uid); 2781 if (app != null) { 2782 app.bad = false; 2783 } 2784 } 2785 } 2786 } 2787 2788 if (app == null) { 2789 app = newProcessRecordLocked(info, processName, isolated); 2790 if (app == null) { 2791 Slog.w(TAG, "Failed making new process record for " 2792 + processName + "/" + info.uid + " isolated=" + isolated); 2793 return null; 2794 } 2795 mProcessNames.put(processName, app.uid, app); 2796 if (isolated) { 2797 mIsolatedProcesses.put(app.uid, app); 2798 } 2799 } else { 2800 // If this is a new package in the process, add the package to the list 2801 app.addPackage(info.packageName, mProcessStats); 2802 } 2803 2804 // If the system is not ready yet, then hold off on starting this 2805 // process until it is. 2806 if (!mProcessesReady 2807 && !isAllowedWhileBooting(info) 2808 && !allowWhileBooting) { 2809 if (!mProcessesOnHold.contains(app)) { 2810 mProcessesOnHold.add(app); 2811 } 2812 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2813 return app; 2814 } 2815 2816 startProcessLocked(app, hostingType, hostingNameStr); 2817 return (app.pid != 0) ? app : null; 2818 } 2819 2820 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2821 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2822 } 2823 2824 private final void startProcessLocked(ProcessRecord app, 2825 String hostingType, String hostingNameStr) { 2826 if (app.pid > 0 && app.pid != MY_PID) { 2827 synchronized (mPidsSelfLocked) { 2828 mPidsSelfLocked.remove(app.pid); 2829 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2830 } 2831 app.setPid(0); 2832 } 2833 2834 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2835 "startProcessLocked removing on hold: " + app); 2836 mProcessesOnHold.remove(app); 2837 2838 updateCpuStats(); 2839 2840 try { 2841 int uid = app.uid; 2842 2843 int[] gids = null; 2844 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2845 if (!app.isolated) { 2846 int[] permGids = null; 2847 try { 2848 final PackageManager pm = mContext.getPackageManager(); 2849 permGids = pm.getPackageGids(app.info.packageName); 2850 2851 if (Environment.isExternalStorageEmulated()) { 2852 if (pm.checkPermission( 2853 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2854 app.info.packageName) == PERMISSION_GRANTED) { 2855 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2856 } else { 2857 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2858 } 2859 } 2860 } catch (PackageManager.NameNotFoundException e) { 2861 Slog.w(TAG, "Unable to retrieve gids", e); 2862 } 2863 2864 /* 2865 * Add shared application GID so applications can share some 2866 * resources like shared libraries 2867 */ 2868 if (permGids == null) { 2869 gids = new int[1]; 2870 } else { 2871 gids = new int[permGids.length + 1]; 2872 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2873 } 2874 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2875 } 2876 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2877 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2878 && mTopComponent != null 2879 && app.processName.equals(mTopComponent.getPackageName())) { 2880 uid = 0; 2881 } 2882 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2883 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2884 uid = 0; 2885 } 2886 } 2887 int debugFlags = 0; 2888 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2889 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2890 // Also turn on CheckJNI for debuggable apps. It's quite 2891 // awkward to turn on otherwise. 2892 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2893 } 2894 // Run the app in safe mode if its manifest requests so or the 2895 // system is booted in safe mode. 2896 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2897 mSafeMode == true) { 2898 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2899 } 2900 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2901 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2902 } 2903 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2904 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2905 } 2906 if ("1".equals(SystemProperties.get("debug.assert"))) { 2907 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2908 } 2909 2910 String requiredAbi = app.info.requiredCpuAbi; 2911 if (requiredAbi == null) { 2912 requiredAbi = Build.SUPPORTED_ABIS[0]; 2913 } 2914 2915 // Start the process. It will either succeed and return a result containing 2916 // the PID of the new process, or else throw a RuntimeException. 2917 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2918 app.processName, uid, uid, gids, debugFlags, mountExternal, 2919 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2920 2921 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2922 synchronized (bs) { 2923 if (bs.isOnBattery()) { 2924 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2925 } 2926 } 2927 2928 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2929 UserHandle.getUserId(uid), startResult.pid, uid, 2930 app.processName, hostingType, 2931 hostingNameStr != null ? hostingNameStr : ""); 2932 2933 if (app.persistent) { 2934 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2935 } 2936 2937 StringBuilder buf = mStringBuilder; 2938 buf.setLength(0); 2939 buf.append("Start proc "); 2940 buf.append(app.processName); 2941 buf.append(" for "); 2942 buf.append(hostingType); 2943 if (hostingNameStr != null) { 2944 buf.append(" "); 2945 buf.append(hostingNameStr); 2946 } 2947 buf.append(": pid="); 2948 buf.append(startResult.pid); 2949 buf.append(" uid="); 2950 buf.append(uid); 2951 buf.append(" gids={"); 2952 if (gids != null) { 2953 for (int gi=0; gi<gids.length; gi++) { 2954 if (gi != 0) buf.append(", "); 2955 buf.append(gids[gi]); 2956 2957 } 2958 } 2959 buf.append("}"); 2960 Slog.i(TAG, buf.toString()); 2961 app.setPid(startResult.pid); 2962 app.usingWrapper = startResult.usingWrapper; 2963 app.removed = false; 2964 synchronized (mPidsSelfLocked) { 2965 this.mPidsSelfLocked.put(startResult.pid, app); 2966 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2967 msg.obj = app; 2968 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2969 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2970 } 2971 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2972 app.processName, app.info.uid); 2973 if (app.isolated) { 2974 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2975 } 2976 } catch (RuntimeException e) { 2977 // XXX do better error recovery. 2978 app.setPid(0); 2979 Slog.e(TAG, "Failure starting process " + app.processName, e); 2980 } 2981 } 2982 2983 void updateUsageStats(ActivityRecord component, boolean resumed) { 2984 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2985 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2986 if (resumed) { 2987 mUsageStatsService.noteResumeComponent(component.realActivity); 2988 synchronized (stats) { 2989 stats.noteActivityResumedLocked(component.app.uid); 2990 } 2991 } else { 2992 mUsageStatsService.notePauseComponent(component.realActivity); 2993 synchronized (stats) { 2994 stats.noteActivityPausedLocked(component.app.uid); 2995 } 2996 } 2997 } 2998 2999 Intent getHomeIntent() { 3000 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3001 intent.setComponent(mTopComponent); 3002 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3003 intent.addCategory(Intent.CATEGORY_HOME); 3004 } 3005 return intent; 3006 } 3007 3008 boolean startHomeActivityLocked(int userId) { 3009 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3010 && mTopAction == null) { 3011 // We are running in factory test mode, but unable to find 3012 // the factory test app, so just sit around displaying the 3013 // error message and don't try to start anything. 3014 return false; 3015 } 3016 Intent intent = getHomeIntent(); 3017 ActivityInfo aInfo = 3018 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3019 if (aInfo != null) { 3020 intent.setComponent(new ComponentName( 3021 aInfo.applicationInfo.packageName, aInfo.name)); 3022 // Don't do this if the home app is currently being 3023 // instrumented. 3024 aInfo = new ActivityInfo(aInfo); 3025 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3026 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3027 aInfo.applicationInfo.uid, true); 3028 if (app == null || app.instrumentationClass == null) { 3029 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3030 mStackSupervisor.startHomeActivity(intent, aInfo); 3031 } 3032 } 3033 3034 return true; 3035 } 3036 3037 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3038 ActivityInfo ai = null; 3039 ComponentName comp = intent.getComponent(); 3040 try { 3041 if (comp != null) { 3042 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3043 } else { 3044 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3045 intent, 3046 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3047 flags, userId); 3048 3049 if (info != null) { 3050 ai = info.activityInfo; 3051 } 3052 } 3053 } catch (RemoteException e) { 3054 // ignore 3055 } 3056 3057 return ai; 3058 } 3059 3060 /** 3061 * Starts the "new version setup screen" if appropriate. 3062 */ 3063 void startSetupActivityLocked() { 3064 // Only do this once per boot. 3065 if (mCheckedForSetup) { 3066 return; 3067 } 3068 3069 // We will show this screen if the current one is a different 3070 // version than the last one shown, and we are not running in 3071 // low-level factory test mode. 3072 final ContentResolver resolver = mContext.getContentResolver(); 3073 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3074 Settings.Global.getInt(resolver, 3075 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3076 mCheckedForSetup = true; 3077 3078 // See if we should be showing the platform update setup UI. 3079 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3080 List<ResolveInfo> ris = mContext.getPackageManager() 3081 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3082 3083 // We don't allow third party apps to replace this. 3084 ResolveInfo ri = null; 3085 for (int i=0; ris != null && i<ris.size(); i++) { 3086 if ((ris.get(i).activityInfo.applicationInfo.flags 3087 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3088 ri = ris.get(i); 3089 break; 3090 } 3091 } 3092 3093 if (ri != null) { 3094 String vers = ri.activityInfo.metaData != null 3095 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3096 : null; 3097 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3098 vers = ri.activityInfo.applicationInfo.metaData.getString( 3099 Intent.METADATA_SETUP_VERSION); 3100 } 3101 String lastVers = Settings.Secure.getString( 3102 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3103 if (vers != null && !vers.equals(lastVers)) { 3104 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3105 intent.setComponent(new ComponentName( 3106 ri.activityInfo.packageName, ri.activityInfo.name)); 3107 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3108 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3109 } 3110 } 3111 } 3112 } 3113 3114 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3115 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3116 } 3117 3118 void enforceNotIsolatedCaller(String caller) { 3119 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3120 throw new SecurityException("Isolated process not allowed to call " + caller); 3121 } 3122 } 3123 3124 @Override 3125 public int getFrontActivityScreenCompatMode() { 3126 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3127 synchronized (this) { 3128 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3129 } 3130 } 3131 3132 @Override 3133 public void setFrontActivityScreenCompatMode(int mode) { 3134 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3135 "setFrontActivityScreenCompatMode"); 3136 synchronized (this) { 3137 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3138 } 3139 } 3140 3141 @Override 3142 public int getPackageScreenCompatMode(String packageName) { 3143 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3144 synchronized (this) { 3145 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3146 } 3147 } 3148 3149 @Override 3150 public void setPackageScreenCompatMode(String packageName, int mode) { 3151 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3152 "setPackageScreenCompatMode"); 3153 synchronized (this) { 3154 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3155 } 3156 } 3157 3158 @Override 3159 public boolean getPackageAskScreenCompat(String packageName) { 3160 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3161 synchronized (this) { 3162 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3163 } 3164 } 3165 3166 @Override 3167 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3168 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3169 "setPackageAskScreenCompat"); 3170 synchronized (this) { 3171 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3172 } 3173 } 3174 3175 private void dispatchProcessesChanged() { 3176 int N; 3177 synchronized (this) { 3178 N = mPendingProcessChanges.size(); 3179 if (mActiveProcessChanges.length < N) { 3180 mActiveProcessChanges = new ProcessChangeItem[N]; 3181 } 3182 mPendingProcessChanges.toArray(mActiveProcessChanges); 3183 mAvailProcessChanges.addAll(mPendingProcessChanges); 3184 mPendingProcessChanges.clear(); 3185 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3186 } 3187 3188 int i = mProcessObservers.beginBroadcast(); 3189 while (i > 0) { 3190 i--; 3191 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3192 if (observer != null) { 3193 try { 3194 for (int j=0; j<N; j++) { 3195 ProcessChangeItem item = mActiveProcessChanges[j]; 3196 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3197 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3198 + item.pid + " uid=" + item.uid + ": " 3199 + item.foregroundActivities); 3200 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3201 item.foregroundActivities); 3202 } 3203 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3204 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3205 + item.pid + " uid=" + item.uid + ": " + item.processState); 3206 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3207 } 3208 } 3209 } catch (RemoteException e) { 3210 } 3211 } 3212 } 3213 mProcessObservers.finishBroadcast(); 3214 } 3215 3216 private void dispatchProcessDied(int pid, int uid) { 3217 int i = mProcessObservers.beginBroadcast(); 3218 while (i > 0) { 3219 i--; 3220 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3221 if (observer != null) { 3222 try { 3223 observer.onProcessDied(pid, uid); 3224 } catch (RemoteException e) { 3225 } 3226 } 3227 } 3228 mProcessObservers.finishBroadcast(); 3229 } 3230 3231 final void doPendingActivityLaunchesLocked(boolean doResume) { 3232 final int N = mPendingActivityLaunches.size(); 3233 if (N <= 0) { 3234 return; 3235 } 3236 for (int i=0; i<N; i++) { 3237 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3238 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3239 doResume && i == (N-1), null); 3240 } 3241 mPendingActivityLaunches.clear(); 3242 } 3243 3244 @Override 3245 public final int startActivity(IApplicationThread caller, String callingPackage, 3246 Intent intent, String resolvedType, IBinder resultTo, 3247 String resultWho, int requestCode, int startFlags, 3248 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3249 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3250 resultWho, requestCode, 3251 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3252 } 3253 3254 @Override 3255 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3256 Intent intent, String resolvedType, IBinder resultTo, 3257 String resultWho, int requestCode, int startFlags, 3258 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3259 enforceNotIsolatedCaller("startActivity"); 3260 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3261 false, true, "startActivity", null); 3262 // TODO: Switch to user app stacks here. 3263 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3264 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3265 null, null, options, userId, null); 3266 } 3267 3268 @Override 3269 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3270 Intent intent, String resolvedType, IBinder resultTo, 3271 String resultWho, int requestCode, int startFlags, String profileFile, 3272 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3273 enforceNotIsolatedCaller("startActivityAndWait"); 3274 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3275 false, true, "startActivityAndWait", null); 3276 WaitResult res = new WaitResult(); 3277 // TODO: Switch to user app stacks here. 3278 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3279 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3280 res, null, options, UserHandle.getCallingUserId(), null); 3281 return res; 3282 } 3283 3284 @Override 3285 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3286 Intent intent, String resolvedType, IBinder resultTo, 3287 String resultWho, int requestCode, int startFlags, Configuration config, 3288 Bundle options, int userId) { 3289 enforceNotIsolatedCaller("startActivityWithConfig"); 3290 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3291 false, true, "startActivityWithConfig", null); 3292 // TODO: Switch to user app stacks here. 3293 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3294 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3295 null, null, null, config, options, userId, null); 3296 return ret; 3297 } 3298 3299 @Override 3300 public int startActivityIntentSender(IApplicationThread caller, 3301 IntentSender intent, Intent fillInIntent, String resolvedType, 3302 IBinder resultTo, String resultWho, int requestCode, 3303 int flagsMask, int flagsValues, Bundle options) { 3304 enforceNotIsolatedCaller("startActivityIntentSender"); 3305 // Refuse possible leaked file descriptors 3306 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3307 throw new IllegalArgumentException("File descriptors passed in Intent"); 3308 } 3309 3310 IIntentSender sender = intent.getTarget(); 3311 if (!(sender instanceof PendingIntentRecord)) { 3312 throw new IllegalArgumentException("Bad PendingIntent object"); 3313 } 3314 3315 PendingIntentRecord pir = (PendingIntentRecord)sender; 3316 3317 synchronized (this) { 3318 // If this is coming from the currently resumed activity, it is 3319 // effectively saying that app switches are allowed at this point. 3320 final ActivityStack stack = getFocusedStack(); 3321 if (stack.mResumedActivity != null && 3322 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3323 mAppSwitchesAllowedTime = 0; 3324 } 3325 } 3326 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3327 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3328 return ret; 3329 } 3330 3331 @Override 3332 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3333 Intent intent, String resolvedType, IVoiceInteractionSession session, 3334 IVoiceInteractor interactor, int startFlags, String profileFile, 3335 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3336 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3337 != PackageManager.PERMISSION_GRANTED) { 3338 String msg = "Permission Denial: startVoiceActivity() from pid=" 3339 + Binder.getCallingPid() 3340 + ", uid=" + Binder.getCallingUid() 3341 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3342 Slog.w(TAG, msg); 3343 throw new SecurityException(msg); 3344 } 3345 if (session == null || interactor == null) { 3346 throw new NullPointerException("null session or interactor"); 3347 } 3348 userId = handleIncomingUser(callingPid, callingUid, userId, 3349 false, true, "startVoiceActivity", null); 3350 // TODO: Switch to user app stacks here. 3351 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3352 resolvedType, session, interactor, null, null, 0, startFlags, 3353 profileFile, profileFd, null, null, options, userId, null); 3354 } 3355 3356 @Override 3357 public boolean startNextMatchingActivity(IBinder callingActivity, 3358 Intent intent, Bundle options) { 3359 // Refuse possible leaked file descriptors 3360 if (intent != null && intent.hasFileDescriptors() == true) { 3361 throw new IllegalArgumentException("File descriptors passed in Intent"); 3362 } 3363 3364 synchronized (this) { 3365 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3366 if (r == null) { 3367 ActivityOptions.abort(options); 3368 return false; 3369 } 3370 if (r.app == null || r.app.thread == null) { 3371 // The caller is not running... d'oh! 3372 ActivityOptions.abort(options); 3373 return false; 3374 } 3375 intent = new Intent(intent); 3376 // The caller is not allowed to change the data. 3377 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3378 // And we are resetting to find the next component... 3379 intent.setComponent(null); 3380 3381 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3382 3383 ActivityInfo aInfo = null; 3384 try { 3385 List<ResolveInfo> resolves = 3386 AppGlobals.getPackageManager().queryIntentActivities( 3387 intent, r.resolvedType, 3388 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3389 UserHandle.getCallingUserId()); 3390 3391 // Look for the original activity in the list... 3392 final int N = resolves != null ? resolves.size() : 0; 3393 for (int i=0; i<N; i++) { 3394 ResolveInfo rInfo = resolves.get(i); 3395 if (rInfo.activityInfo.packageName.equals(r.packageName) 3396 && rInfo.activityInfo.name.equals(r.info.name)) { 3397 // We found the current one... the next matching is 3398 // after it. 3399 i++; 3400 if (i<N) { 3401 aInfo = resolves.get(i).activityInfo; 3402 } 3403 if (debug) { 3404 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3405 + "/" + r.info.name); 3406 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3407 + "/" + aInfo.name); 3408 } 3409 break; 3410 } 3411 } 3412 } catch (RemoteException e) { 3413 } 3414 3415 if (aInfo == null) { 3416 // Nobody who is next! 3417 ActivityOptions.abort(options); 3418 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3419 return false; 3420 } 3421 3422 intent.setComponent(new ComponentName( 3423 aInfo.applicationInfo.packageName, aInfo.name)); 3424 intent.setFlags(intent.getFlags()&~( 3425 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3426 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3427 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3428 Intent.FLAG_ACTIVITY_NEW_TASK)); 3429 3430 // Okay now we need to start the new activity, replacing the 3431 // currently running activity. This is a little tricky because 3432 // we want to start the new one as if the current one is finished, 3433 // but not finish the current one first so that there is no flicker. 3434 // And thus... 3435 final boolean wasFinishing = r.finishing; 3436 r.finishing = true; 3437 3438 // Propagate reply information over to the new activity. 3439 final ActivityRecord resultTo = r.resultTo; 3440 final String resultWho = r.resultWho; 3441 final int requestCode = r.requestCode; 3442 r.resultTo = null; 3443 if (resultTo != null) { 3444 resultTo.removeResultsLocked(r, resultWho, requestCode); 3445 } 3446 3447 final long origId = Binder.clearCallingIdentity(); 3448 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3449 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3450 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3451 options, false, null, null); 3452 Binder.restoreCallingIdentity(origId); 3453 3454 r.finishing = wasFinishing; 3455 if (res != ActivityManager.START_SUCCESS) { 3456 return false; 3457 } 3458 return true; 3459 } 3460 } 3461 3462 final int startActivityInPackage(int uid, String callingPackage, 3463 Intent intent, String resolvedType, IBinder resultTo, 3464 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3465 IActivityContainer container) { 3466 3467 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3468 false, true, "startActivityInPackage", null); 3469 3470 // TODO: Switch to user app stacks here. 3471 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3472 null, null, resultTo, resultWho, requestCode, startFlags, 3473 null, null, null, null, options, userId, container); 3474 return ret; 3475 } 3476 3477 @Override 3478 public final int startActivities(IApplicationThread caller, String callingPackage, 3479 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3480 int userId) { 3481 enforceNotIsolatedCaller("startActivities"); 3482 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3483 false, true, "startActivity", null); 3484 // TODO: Switch to user app stacks here. 3485 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3486 resolvedTypes, resultTo, options, userId); 3487 return ret; 3488 } 3489 3490 final int startActivitiesInPackage(int uid, String callingPackage, 3491 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3492 Bundle options, int userId) { 3493 3494 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3495 false, true, "startActivityInPackage", null); 3496 // TODO: Switch to user app stacks here. 3497 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3498 resultTo, options, userId); 3499 return ret; 3500 } 3501 3502 final void addRecentTaskLocked(TaskRecord task) { 3503 int N = mRecentTasks.size(); 3504 // Quick case: check if the top-most recent task is the same. 3505 if (N > 0 && mRecentTasks.get(0) == task) { 3506 return; 3507 } 3508 // Another quick case: never add voice sessions. 3509 if (task.voiceSession != null) { 3510 return; 3511 } 3512 // Remove any existing entries that are the same kind of task. 3513 final Intent intent = task.intent; 3514 final boolean document = intent != null && intent.isDocument(); 3515 for (int i=0; i<N; i++) { 3516 TaskRecord tr = mRecentTasks.get(i); 3517 if (task != tr) { 3518 if (task.userId != tr.userId) { 3519 continue; 3520 } 3521 final Intent trIntent = tr.intent; 3522 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3523 (intent == null || !intent.filterEquals(trIntent))) { 3524 continue; 3525 } 3526 if (document || trIntent != null && trIntent.isDocument()) { 3527 // Document tasks do not match other tasks. 3528 continue; 3529 } 3530 } 3531 3532 // Either task and tr are the same or, their affinities match or their intents match 3533 // and neither of them is a document. 3534 tr.disposeThumbnail(); 3535 mRecentTasks.remove(i); 3536 i--; 3537 N--; 3538 if (task.intent == null) { 3539 // If the new recent task we are adding is not fully 3540 // specified, then replace it with the existing recent task. 3541 task = tr; 3542 } 3543 } 3544 if (N >= MAX_RECENT_TASKS) { 3545 mRecentTasks.remove(N-1).disposeThumbnail(); 3546 } 3547 mRecentTasks.add(0, task); 3548 } 3549 3550 @Override 3551 public void reportActivityFullyDrawn(IBinder token) { 3552 synchronized (this) { 3553 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3554 if (r == null) { 3555 return; 3556 } 3557 r.reportFullyDrawnLocked(); 3558 } 3559 } 3560 3561 @Override 3562 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3563 synchronized (this) { 3564 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3565 if (r == null) { 3566 return; 3567 } 3568 final long origId = Binder.clearCallingIdentity(); 3569 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3570 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3571 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3572 if (config != null) { 3573 r.frozenBeforeDestroy = true; 3574 if (!updateConfigurationLocked(config, r, false, false)) { 3575 mStackSupervisor.resumeTopActivitiesLocked(); 3576 } 3577 } 3578 Binder.restoreCallingIdentity(origId); 3579 } 3580 } 3581 3582 @Override 3583 public int getRequestedOrientation(IBinder token) { 3584 synchronized (this) { 3585 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3586 if (r == null) { 3587 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3588 } 3589 return mWindowManager.getAppOrientation(r.appToken); 3590 } 3591 } 3592 3593 /** 3594 * This is the internal entry point for handling Activity.finish(). 3595 * 3596 * @param token The Binder token referencing the Activity we want to finish. 3597 * @param resultCode Result code, if any, from this Activity. 3598 * @param resultData Result data (Intent), if any, from this Activity. 3599 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3600 * the root Activity in the task. 3601 * 3602 * @return Returns true if the activity successfully finished, or false if it is still running. 3603 */ 3604 @Override 3605 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3606 boolean finishTask) { 3607 // Refuse possible leaked file descriptors 3608 if (resultData != null && resultData.hasFileDescriptors() == true) { 3609 throw new IllegalArgumentException("File descriptors passed in Intent"); 3610 } 3611 3612 synchronized(this) { 3613 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3614 if (r == null) { 3615 return true; 3616 } 3617 // Keep track of the root activity of the task before we finish it 3618 TaskRecord tr = r.task; 3619 ActivityRecord rootR = tr.getRootActivity(); 3620 if (mController != null) { 3621 // Find the first activity that is not finishing. 3622 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3623 if (next != null) { 3624 // ask watcher if this is allowed 3625 boolean resumeOK = true; 3626 try { 3627 resumeOK = mController.activityResuming(next.packageName); 3628 } catch (RemoteException e) { 3629 mController = null; 3630 Watchdog.getInstance().setActivityController(null); 3631 } 3632 3633 if (!resumeOK) { 3634 return false; 3635 } 3636 } 3637 } 3638 final long origId = Binder.clearCallingIdentity(); 3639 try { 3640 boolean res; 3641 if (finishTask && r == rootR) { 3642 // If requested, remove the task that is associated to this activity only if it 3643 // was the root activity in the task. The result code and data is ignored because 3644 // we don't support returning them across task boundaries. 3645 res = removeTaskByIdLocked(tr.taskId, 0); 3646 } else { 3647 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3648 resultData, "app-request", true); 3649 } 3650 return res; 3651 } finally { 3652 Binder.restoreCallingIdentity(origId); 3653 } 3654 } 3655 } 3656 3657 @Override 3658 public final void finishHeavyWeightApp() { 3659 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3660 != PackageManager.PERMISSION_GRANTED) { 3661 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3662 + Binder.getCallingPid() 3663 + ", uid=" + Binder.getCallingUid() 3664 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3665 Slog.w(TAG, msg); 3666 throw new SecurityException(msg); 3667 } 3668 3669 synchronized(this) { 3670 if (mHeavyWeightProcess == null) { 3671 return; 3672 } 3673 3674 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3675 mHeavyWeightProcess.activities); 3676 for (int i=0; i<activities.size(); i++) { 3677 ActivityRecord r = activities.get(i); 3678 if (!r.finishing) { 3679 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3680 null, "finish-heavy", true); 3681 } 3682 } 3683 3684 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3685 mHeavyWeightProcess.userId, 0)); 3686 mHeavyWeightProcess = null; 3687 } 3688 } 3689 3690 @Override 3691 public void crashApplication(int uid, int initialPid, String packageName, 3692 String message) { 3693 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3694 != PackageManager.PERMISSION_GRANTED) { 3695 String msg = "Permission Denial: crashApplication() from pid=" 3696 + Binder.getCallingPid() 3697 + ", uid=" + Binder.getCallingUid() 3698 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3699 Slog.w(TAG, msg); 3700 throw new SecurityException(msg); 3701 } 3702 3703 synchronized(this) { 3704 ProcessRecord proc = null; 3705 3706 // Figure out which process to kill. We don't trust that initialPid 3707 // still has any relation to current pids, so must scan through the 3708 // list. 3709 synchronized (mPidsSelfLocked) { 3710 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3711 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3712 if (p.uid != uid) { 3713 continue; 3714 } 3715 if (p.pid == initialPid) { 3716 proc = p; 3717 break; 3718 } 3719 if (p.pkgList.containsKey(packageName)) { 3720 proc = p; 3721 } 3722 } 3723 } 3724 3725 if (proc == null) { 3726 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3727 + " initialPid=" + initialPid 3728 + " packageName=" + packageName); 3729 return; 3730 } 3731 3732 if (proc.thread != null) { 3733 if (proc.pid == Process.myPid()) { 3734 Log.w(TAG, "crashApplication: trying to crash self!"); 3735 return; 3736 } 3737 long ident = Binder.clearCallingIdentity(); 3738 try { 3739 proc.thread.scheduleCrash(message); 3740 } catch (RemoteException e) { 3741 } 3742 Binder.restoreCallingIdentity(ident); 3743 } 3744 } 3745 } 3746 3747 @Override 3748 public final void finishSubActivity(IBinder token, String resultWho, 3749 int requestCode) { 3750 synchronized(this) { 3751 final long origId = Binder.clearCallingIdentity(); 3752 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3753 if (r != null) { 3754 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3755 } 3756 Binder.restoreCallingIdentity(origId); 3757 } 3758 } 3759 3760 @Override 3761 public boolean finishActivityAffinity(IBinder token) { 3762 synchronized(this) { 3763 final long origId = Binder.clearCallingIdentity(); 3764 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3765 boolean res = false; 3766 if (r != null) { 3767 res = r.task.stack.finishActivityAffinityLocked(r); 3768 } 3769 Binder.restoreCallingIdentity(origId); 3770 return res; 3771 } 3772 } 3773 3774 @Override 3775 public boolean willActivityBeVisible(IBinder token) { 3776 synchronized(this) { 3777 ActivityStack stack = ActivityRecord.getStackLocked(token); 3778 if (stack != null) { 3779 return stack.willActivityBeVisibleLocked(token); 3780 } 3781 return false; 3782 } 3783 } 3784 3785 @Override 3786 public void overridePendingTransition(IBinder token, String packageName, 3787 int enterAnim, int exitAnim) { 3788 synchronized(this) { 3789 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3790 if (self == null) { 3791 return; 3792 } 3793 3794 final long origId = Binder.clearCallingIdentity(); 3795 3796 if (self.state == ActivityState.RESUMED 3797 || self.state == ActivityState.PAUSING) { 3798 mWindowManager.overridePendingAppTransition(packageName, 3799 enterAnim, exitAnim, null); 3800 } 3801 3802 Binder.restoreCallingIdentity(origId); 3803 } 3804 } 3805 3806 /** 3807 * Main function for removing an existing process from the activity manager 3808 * as a result of that process going away. Clears out all connections 3809 * to the process. 3810 */ 3811 private final void handleAppDiedLocked(ProcessRecord app, 3812 boolean restarting, boolean allowRestart) { 3813 int pid = app.pid; 3814 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3815 if (!restarting) { 3816 removeLruProcessLocked(app); 3817 if (pid > 0) { 3818 ProcessList.remove(pid); 3819 } 3820 } 3821 3822 if (mProfileProc == app) { 3823 clearProfilerLocked(); 3824 } 3825 3826 // Remove this application's activities from active lists. 3827 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3828 3829 app.activities.clear(); 3830 3831 if (app.instrumentationClass != null) { 3832 Slog.w(TAG, "Crash of app " + app.processName 3833 + " running instrumentation " + app.instrumentationClass); 3834 Bundle info = new Bundle(); 3835 info.putString("shortMsg", "Process crashed."); 3836 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3837 } 3838 3839 if (!restarting) { 3840 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3841 // If there was nothing to resume, and we are not already 3842 // restarting this process, but there is a visible activity that 3843 // is hosted by the process... then make sure all visible 3844 // activities are running, taking care of restarting this 3845 // process. 3846 if (hasVisibleActivities) { 3847 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3848 } 3849 } 3850 } 3851 } 3852 3853 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3854 IBinder threadBinder = thread.asBinder(); 3855 // Find the application record. 3856 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3857 ProcessRecord rec = mLruProcesses.get(i); 3858 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3859 return i; 3860 } 3861 } 3862 return -1; 3863 } 3864 3865 final ProcessRecord getRecordForAppLocked( 3866 IApplicationThread thread) { 3867 if (thread == null) { 3868 return null; 3869 } 3870 3871 int appIndex = getLRURecordIndexForAppLocked(thread); 3872 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3873 } 3874 3875 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3876 // If there are no longer any background processes running, 3877 // and the app that died was not running instrumentation, 3878 // then tell everyone we are now low on memory. 3879 boolean haveBg = false; 3880 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3881 ProcessRecord rec = mLruProcesses.get(i); 3882 if (rec.thread != null 3883 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3884 haveBg = true; 3885 break; 3886 } 3887 } 3888 3889 if (!haveBg) { 3890 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3891 if (doReport) { 3892 long now = SystemClock.uptimeMillis(); 3893 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3894 doReport = false; 3895 } else { 3896 mLastMemUsageReportTime = now; 3897 } 3898 } 3899 final ArrayList<ProcessMemInfo> memInfos 3900 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3901 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3902 long now = SystemClock.uptimeMillis(); 3903 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3904 ProcessRecord rec = mLruProcesses.get(i); 3905 if (rec == dyingProc || rec.thread == null) { 3906 continue; 3907 } 3908 if (doReport) { 3909 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3910 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3911 } 3912 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3913 // The low memory report is overriding any current 3914 // state for a GC request. Make sure to do 3915 // heavy/important/visible/foreground processes first. 3916 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3917 rec.lastRequestedGc = 0; 3918 } else { 3919 rec.lastRequestedGc = rec.lastLowMemory; 3920 } 3921 rec.reportLowMemory = true; 3922 rec.lastLowMemory = now; 3923 mProcessesToGc.remove(rec); 3924 addProcessToGcListLocked(rec); 3925 } 3926 } 3927 if (doReport) { 3928 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3929 mHandler.sendMessage(msg); 3930 } 3931 scheduleAppGcsLocked(); 3932 } 3933 } 3934 3935 final void appDiedLocked(ProcessRecord app, int pid, 3936 IApplicationThread thread) { 3937 3938 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3939 synchronized (stats) { 3940 stats.noteProcessDiedLocked(app.info.uid, pid); 3941 } 3942 3943 // Clean up already done if the process has been re-started. 3944 if (app.pid == pid && app.thread != null && 3945 app.thread.asBinder() == thread.asBinder()) { 3946 boolean doLowMem = app.instrumentationClass == null; 3947 boolean doOomAdj = doLowMem; 3948 if (!app.killedByAm) { 3949 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3950 + ") has died."); 3951 mAllowLowerMemLevel = true; 3952 } else { 3953 // Note that we always want to do oom adj to update our state with the 3954 // new number of procs. 3955 mAllowLowerMemLevel = false; 3956 doLowMem = false; 3957 } 3958 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3959 if (DEBUG_CLEANUP) Slog.v( 3960 TAG, "Dying app: " + app + ", pid: " + pid 3961 + ", thread: " + thread.asBinder()); 3962 handleAppDiedLocked(app, false, true); 3963 3964 if (doOomAdj) { 3965 updateOomAdjLocked(); 3966 } 3967 if (doLowMem) { 3968 doLowMemReportIfNeededLocked(app); 3969 } 3970 } else if (app.pid != pid) { 3971 // A new process has already been started. 3972 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3973 + ") has died and restarted (pid " + app.pid + ")."); 3974 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3975 } else if (DEBUG_PROCESSES) { 3976 Slog.d(TAG, "Received spurious death notification for thread " 3977 + thread.asBinder()); 3978 } 3979 } 3980 3981 /** 3982 * If a stack trace dump file is configured, dump process stack traces. 3983 * @param clearTraces causes the dump file to be erased prior to the new 3984 * traces being written, if true; when false, the new traces will be 3985 * appended to any existing file content. 3986 * @param firstPids of dalvik VM processes to dump stack traces for first 3987 * @param lastPids of dalvik VM processes to dump stack traces for last 3988 * @param nativeProcs optional list of native process names to dump stack crawls 3989 * @return file containing stack traces, or null if no dump file is configured 3990 */ 3991 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3992 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3993 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3994 if (tracesPath == null || tracesPath.length() == 0) { 3995 return null; 3996 } 3997 3998 File tracesFile = new File(tracesPath); 3999 try { 4000 File tracesDir = tracesFile.getParentFile(); 4001 if (!tracesDir.exists()) { 4002 tracesFile.mkdirs(); 4003 if (!SELinux.restorecon(tracesDir)) { 4004 return null; 4005 } 4006 } 4007 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4008 4009 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4010 tracesFile.createNewFile(); 4011 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4012 } catch (IOException e) { 4013 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4014 return null; 4015 } 4016 4017 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4018 return tracesFile; 4019 } 4020 4021 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4022 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4023 // Use a FileObserver to detect when traces finish writing. 4024 // The order of traces is considered important to maintain for legibility. 4025 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4026 @Override 4027 public synchronized void onEvent(int event, String path) { notify(); } 4028 }; 4029 4030 try { 4031 observer.startWatching(); 4032 4033 // First collect all of the stacks of the most important pids. 4034 if (firstPids != null) { 4035 try { 4036 int num = firstPids.size(); 4037 for (int i = 0; i < num; i++) { 4038 synchronized (observer) { 4039 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4040 observer.wait(200); // Wait for write-close, give up after 200msec 4041 } 4042 } 4043 } catch (InterruptedException e) { 4044 Log.wtf(TAG, e); 4045 } 4046 } 4047 4048 // Next collect the stacks of the native pids 4049 if (nativeProcs != null) { 4050 int[] pids = Process.getPidsForCommands(nativeProcs); 4051 if (pids != null) { 4052 for (int pid : pids) { 4053 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4054 } 4055 } 4056 } 4057 4058 // Lastly, measure CPU usage. 4059 if (processCpuTracker != null) { 4060 processCpuTracker.init(); 4061 System.gc(); 4062 processCpuTracker.update(); 4063 try { 4064 synchronized (processCpuTracker) { 4065 processCpuTracker.wait(500); // measure over 1/2 second. 4066 } 4067 } catch (InterruptedException e) { 4068 } 4069 processCpuTracker.update(); 4070 4071 // We'll take the stack crawls of just the top apps using CPU. 4072 final int N = processCpuTracker.countWorkingStats(); 4073 int numProcs = 0; 4074 for (int i=0; i<N && numProcs<5; i++) { 4075 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4076 if (lastPids.indexOfKey(stats.pid) >= 0) { 4077 numProcs++; 4078 try { 4079 synchronized (observer) { 4080 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4081 observer.wait(200); // Wait for write-close, give up after 200msec 4082 } 4083 } catch (InterruptedException e) { 4084 Log.wtf(TAG, e); 4085 } 4086 4087 } 4088 } 4089 } 4090 } finally { 4091 observer.stopWatching(); 4092 } 4093 } 4094 4095 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4096 if (true || IS_USER_BUILD) { 4097 return; 4098 } 4099 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4100 if (tracesPath == null || tracesPath.length() == 0) { 4101 return; 4102 } 4103 4104 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4105 StrictMode.allowThreadDiskWrites(); 4106 try { 4107 final File tracesFile = new File(tracesPath); 4108 final File tracesDir = tracesFile.getParentFile(); 4109 final File tracesTmp = new File(tracesDir, "__tmp__"); 4110 try { 4111 if (!tracesDir.exists()) { 4112 tracesFile.mkdirs(); 4113 if (!SELinux.restorecon(tracesDir.getPath())) { 4114 return; 4115 } 4116 } 4117 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4118 4119 if (tracesFile.exists()) { 4120 tracesTmp.delete(); 4121 tracesFile.renameTo(tracesTmp); 4122 } 4123 StringBuilder sb = new StringBuilder(); 4124 Time tobj = new Time(); 4125 tobj.set(System.currentTimeMillis()); 4126 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4127 sb.append(": "); 4128 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4129 sb.append(" since "); 4130 sb.append(msg); 4131 FileOutputStream fos = new FileOutputStream(tracesFile); 4132 fos.write(sb.toString().getBytes()); 4133 if (app == null) { 4134 fos.write("\n*** No application process!".getBytes()); 4135 } 4136 fos.close(); 4137 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4138 } catch (IOException e) { 4139 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4140 return; 4141 } 4142 4143 if (app != null) { 4144 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4145 firstPids.add(app.pid); 4146 dumpStackTraces(tracesPath, firstPids, null, null, null); 4147 } 4148 4149 File lastTracesFile = null; 4150 File curTracesFile = null; 4151 for (int i=9; i>=0; i--) { 4152 String name = String.format(Locale.US, "slow%02d.txt", i); 4153 curTracesFile = new File(tracesDir, name); 4154 if (curTracesFile.exists()) { 4155 if (lastTracesFile != null) { 4156 curTracesFile.renameTo(lastTracesFile); 4157 } else { 4158 curTracesFile.delete(); 4159 } 4160 } 4161 lastTracesFile = curTracesFile; 4162 } 4163 tracesFile.renameTo(curTracesFile); 4164 if (tracesTmp.exists()) { 4165 tracesTmp.renameTo(tracesFile); 4166 } 4167 } finally { 4168 StrictMode.setThreadPolicy(oldPolicy); 4169 } 4170 } 4171 4172 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4173 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4174 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4175 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4176 4177 if (mController != null) { 4178 try { 4179 // 0 == continue, -1 = kill process immediately 4180 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4181 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4182 } catch (RemoteException e) { 4183 mController = null; 4184 Watchdog.getInstance().setActivityController(null); 4185 } 4186 } 4187 4188 long anrTime = SystemClock.uptimeMillis(); 4189 if (MONITOR_CPU_USAGE) { 4190 updateCpuStatsNow(); 4191 } 4192 4193 synchronized (this) { 4194 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4195 if (mShuttingDown) { 4196 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4197 return; 4198 } else if (app.notResponding) { 4199 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4200 return; 4201 } else if (app.crashing) { 4202 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4203 return; 4204 } 4205 4206 // In case we come through here for the same app before completing 4207 // this one, mark as anring now so we will bail out. 4208 app.notResponding = true; 4209 4210 // Log the ANR to the event log. 4211 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4212 app.processName, app.info.flags, annotation); 4213 4214 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4215 firstPids.add(app.pid); 4216 4217 int parentPid = app.pid; 4218 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4219 if (parentPid != app.pid) firstPids.add(parentPid); 4220 4221 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4222 4223 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4224 ProcessRecord r = mLruProcesses.get(i); 4225 if (r != null && r.thread != null) { 4226 int pid = r.pid; 4227 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4228 if (r.persistent) { 4229 firstPids.add(pid); 4230 } else { 4231 lastPids.put(pid, Boolean.TRUE); 4232 } 4233 } 4234 } 4235 } 4236 } 4237 4238 // Log the ANR to the main log. 4239 StringBuilder info = new StringBuilder(); 4240 info.setLength(0); 4241 info.append("ANR in ").append(app.processName); 4242 if (activity != null && activity.shortComponentName != null) { 4243 info.append(" (").append(activity.shortComponentName).append(")"); 4244 } 4245 info.append("\n"); 4246 info.append("PID: ").append(app.pid).append("\n"); 4247 if (annotation != null) { 4248 info.append("Reason: ").append(annotation).append("\n"); 4249 } 4250 if (parent != null && parent != activity) { 4251 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4252 } 4253 4254 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4255 4256 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4257 NATIVE_STACKS_OF_INTEREST); 4258 4259 String cpuInfo = null; 4260 if (MONITOR_CPU_USAGE) { 4261 updateCpuStatsNow(); 4262 synchronized (mProcessCpuThread) { 4263 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4264 } 4265 info.append(processCpuTracker.printCurrentLoad()); 4266 info.append(cpuInfo); 4267 } 4268 4269 info.append(processCpuTracker.printCurrentState(anrTime)); 4270 4271 Slog.e(TAG, info.toString()); 4272 if (tracesFile == null) { 4273 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4274 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4275 } 4276 4277 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4278 cpuInfo, tracesFile, null); 4279 4280 if (mController != null) { 4281 try { 4282 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4283 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4284 if (res != 0) { 4285 if (res < 0 && app.pid != MY_PID) { 4286 Process.killProcess(app.pid); 4287 } else { 4288 synchronized (this) { 4289 mServices.scheduleServiceTimeoutLocked(app); 4290 } 4291 } 4292 return; 4293 } 4294 } catch (RemoteException e) { 4295 mController = null; 4296 Watchdog.getInstance().setActivityController(null); 4297 } 4298 } 4299 4300 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4301 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4302 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4303 4304 synchronized (this) { 4305 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4306 killUnneededProcessLocked(app, "background ANR"); 4307 return; 4308 } 4309 4310 // Set the app's notResponding state, and look up the errorReportReceiver 4311 makeAppNotRespondingLocked(app, 4312 activity != null ? activity.shortComponentName : null, 4313 annotation != null ? "ANR " + annotation : "ANR", 4314 info.toString()); 4315 4316 // Bring up the infamous App Not Responding dialog 4317 Message msg = Message.obtain(); 4318 HashMap<String, Object> map = new HashMap<String, Object>(); 4319 msg.what = SHOW_NOT_RESPONDING_MSG; 4320 msg.obj = map; 4321 msg.arg1 = aboveSystem ? 1 : 0; 4322 map.put("app", app); 4323 if (activity != null) { 4324 map.put("activity", activity); 4325 } 4326 4327 mHandler.sendMessage(msg); 4328 } 4329 } 4330 4331 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4332 if (!mLaunchWarningShown) { 4333 mLaunchWarningShown = true; 4334 mHandler.post(new Runnable() { 4335 @Override 4336 public void run() { 4337 synchronized (ActivityManagerService.this) { 4338 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4339 d.show(); 4340 mHandler.postDelayed(new Runnable() { 4341 @Override 4342 public void run() { 4343 synchronized (ActivityManagerService.this) { 4344 d.dismiss(); 4345 mLaunchWarningShown = false; 4346 } 4347 } 4348 }, 4000); 4349 } 4350 } 4351 }); 4352 } 4353 } 4354 4355 @Override 4356 public boolean clearApplicationUserData(final String packageName, 4357 final IPackageDataObserver observer, int userId) { 4358 enforceNotIsolatedCaller("clearApplicationUserData"); 4359 int uid = Binder.getCallingUid(); 4360 int pid = Binder.getCallingPid(); 4361 userId = handleIncomingUser(pid, uid, 4362 userId, false, true, "clearApplicationUserData", null); 4363 long callingId = Binder.clearCallingIdentity(); 4364 try { 4365 IPackageManager pm = AppGlobals.getPackageManager(); 4366 int pkgUid = -1; 4367 synchronized(this) { 4368 try { 4369 pkgUid = pm.getPackageUid(packageName, userId); 4370 } catch (RemoteException e) { 4371 } 4372 if (pkgUid == -1) { 4373 Slog.w(TAG, "Invalid packageName: " + packageName); 4374 if (observer != null) { 4375 try { 4376 observer.onRemoveCompleted(packageName, false); 4377 } catch (RemoteException e) { 4378 Slog.i(TAG, "Observer no longer exists."); 4379 } 4380 } 4381 return false; 4382 } 4383 if (uid == pkgUid || checkComponentPermission( 4384 android.Manifest.permission.CLEAR_APP_USER_DATA, 4385 pid, uid, -1, true) 4386 == PackageManager.PERMISSION_GRANTED) { 4387 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4388 } else { 4389 throw new SecurityException("PID " + pid + " does not have permission " 4390 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4391 + " of package " + packageName); 4392 } 4393 } 4394 4395 try { 4396 // Clear application user data 4397 pm.clearApplicationUserData(packageName, observer, userId); 4398 4399 // Remove all permissions granted from/to this package 4400 removeUriPermissionsForPackageLocked(packageName, userId, true); 4401 4402 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4403 Uri.fromParts("package", packageName, null)); 4404 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4405 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4406 null, null, 0, null, null, null, false, false, userId); 4407 } catch (RemoteException e) { 4408 } 4409 } finally { 4410 Binder.restoreCallingIdentity(callingId); 4411 } 4412 return true; 4413 } 4414 4415 @Override 4416 public void killBackgroundProcesses(final String packageName, int userId) { 4417 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4418 != PackageManager.PERMISSION_GRANTED && 4419 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4420 != PackageManager.PERMISSION_GRANTED) { 4421 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4422 + Binder.getCallingPid() 4423 + ", uid=" + Binder.getCallingUid() 4424 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4425 Slog.w(TAG, msg); 4426 throw new SecurityException(msg); 4427 } 4428 4429 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4430 userId, true, true, "killBackgroundProcesses", null); 4431 long callingId = Binder.clearCallingIdentity(); 4432 try { 4433 IPackageManager pm = AppGlobals.getPackageManager(); 4434 synchronized(this) { 4435 int appId = -1; 4436 try { 4437 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4438 } catch (RemoteException e) { 4439 } 4440 if (appId == -1) { 4441 Slog.w(TAG, "Invalid packageName: " + packageName); 4442 return; 4443 } 4444 killPackageProcessesLocked(packageName, appId, userId, 4445 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4446 } 4447 } finally { 4448 Binder.restoreCallingIdentity(callingId); 4449 } 4450 } 4451 4452 @Override 4453 public void killAllBackgroundProcesses() { 4454 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4455 != PackageManager.PERMISSION_GRANTED) { 4456 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4457 + Binder.getCallingPid() 4458 + ", uid=" + Binder.getCallingUid() 4459 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4460 Slog.w(TAG, msg); 4461 throw new SecurityException(msg); 4462 } 4463 4464 long callingId = Binder.clearCallingIdentity(); 4465 try { 4466 synchronized(this) { 4467 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4468 final int NP = mProcessNames.getMap().size(); 4469 for (int ip=0; ip<NP; ip++) { 4470 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4471 final int NA = apps.size(); 4472 for (int ia=0; ia<NA; ia++) { 4473 ProcessRecord app = apps.valueAt(ia); 4474 if (app.persistent) { 4475 // we don't kill persistent processes 4476 continue; 4477 } 4478 if (app.removed) { 4479 procs.add(app); 4480 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4481 app.removed = true; 4482 procs.add(app); 4483 } 4484 } 4485 } 4486 4487 int N = procs.size(); 4488 for (int i=0; i<N; i++) { 4489 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4490 } 4491 mAllowLowerMemLevel = true; 4492 updateOomAdjLocked(); 4493 doLowMemReportIfNeededLocked(null); 4494 } 4495 } finally { 4496 Binder.restoreCallingIdentity(callingId); 4497 } 4498 } 4499 4500 @Override 4501 public void forceStopPackage(final String packageName, int userId) { 4502 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4503 != PackageManager.PERMISSION_GRANTED) { 4504 String msg = "Permission Denial: forceStopPackage() from pid=" 4505 + Binder.getCallingPid() 4506 + ", uid=" + Binder.getCallingUid() 4507 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4508 Slog.w(TAG, msg); 4509 throw new SecurityException(msg); 4510 } 4511 final int callingPid = Binder.getCallingPid(); 4512 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4513 userId, true, true, "forceStopPackage", null); 4514 long callingId = Binder.clearCallingIdentity(); 4515 try { 4516 IPackageManager pm = AppGlobals.getPackageManager(); 4517 synchronized(this) { 4518 int[] users = userId == UserHandle.USER_ALL 4519 ? getUsersLocked() : new int[] { userId }; 4520 for (int user : users) { 4521 int pkgUid = -1; 4522 try { 4523 pkgUid = pm.getPackageUid(packageName, user); 4524 } catch (RemoteException e) { 4525 } 4526 if (pkgUid == -1) { 4527 Slog.w(TAG, "Invalid packageName: " + packageName); 4528 continue; 4529 } 4530 try { 4531 pm.setPackageStoppedState(packageName, true, user); 4532 } catch (RemoteException e) { 4533 } catch (IllegalArgumentException e) { 4534 Slog.w(TAG, "Failed trying to unstop package " 4535 + packageName + ": " + e); 4536 } 4537 if (isUserRunningLocked(user, false)) { 4538 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4539 } 4540 } 4541 } 4542 } finally { 4543 Binder.restoreCallingIdentity(callingId); 4544 } 4545 } 4546 4547 /* 4548 * The pkg name and app id have to be specified. 4549 */ 4550 @Override 4551 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4552 if (pkg == null) { 4553 return; 4554 } 4555 // Make sure the uid is valid. 4556 if (appid < 0) { 4557 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4558 return; 4559 } 4560 int callerUid = Binder.getCallingUid(); 4561 // Only the system server can kill an application 4562 if (callerUid == Process.SYSTEM_UID) { 4563 // Post an aysnc message to kill the application 4564 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4565 msg.arg1 = appid; 4566 msg.arg2 = 0; 4567 Bundle bundle = new Bundle(); 4568 bundle.putString("pkg", pkg); 4569 bundle.putString("reason", reason); 4570 msg.obj = bundle; 4571 mHandler.sendMessage(msg); 4572 } else { 4573 throw new SecurityException(callerUid + " cannot kill pkg: " + 4574 pkg); 4575 } 4576 } 4577 4578 @Override 4579 public void closeSystemDialogs(String reason) { 4580 enforceNotIsolatedCaller("closeSystemDialogs"); 4581 4582 final int pid = Binder.getCallingPid(); 4583 final int uid = Binder.getCallingUid(); 4584 final long origId = Binder.clearCallingIdentity(); 4585 try { 4586 synchronized (this) { 4587 // Only allow this from foreground processes, so that background 4588 // applications can't abuse it to prevent system UI from being shown. 4589 if (uid >= Process.FIRST_APPLICATION_UID) { 4590 ProcessRecord proc; 4591 synchronized (mPidsSelfLocked) { 4592 proc = mPidsSelfLocked.get(pid); 4593 } 4594 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4595 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4596 + " from background process " + proc); 4597 return; 4598 } 4599 } 4600 closeSystemDialogsLocked(reason); 4601 } 4602 } finally { 4603 Binder.restoreCallingIdentity(origId); 4604 } 4605 } 4606 4607 void closeSystemDialogsLocked(String reason) { 4608 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4609 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4610 | Intent.FLAG_RECEIVER_FOREGROUND); 4611 if (reason != null) { 4612 intent.putExtra("reason", reason); 4613 } 4614 mWindowManager.closeSystemDialogs(reason); 4615 4616 mStackSupervisor.closeSystemDialogsLocked(); 4617 4618 broadcastIntentLocked(null, null, intent, null, 4619 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4620 Process.SYSTEM_UID, UserHandle.USER_ALL); 4621 } 4622 4623 @Override 4624 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4625 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4626 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4627 for (int i=pids.length-1; i>=0; i--) { 4628 ProcessRecord proc; 4629 int oomAdj; 4630 synchronized (this) { 4631 synchronized (mPidsSelfLocked) { 4632 proc = mPidsSelfLocked.get(pids[i]); 4633 oomAdj = proc != null ? proc.setAdj : 0; 4634 } 4635 } 4636 infos[i] = new Debug.MemoryInfo(); 4637 Debug.getMemoryInfo(pids[i], infos[i]); 4638 if (proc != null) { 4639 synchronized (this) { 4640 if (proc.thread != null && proc.setAdj == oomAdj) { 4641 // Record this for posterity if the process has been stable. 4642 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4643 infos[i].getTotalUss(), false, proc.pkgList); 4644 } 4645 } 4646 } 4647 } 4648 return infos; 4649 } 4650 4651 @Override 4652 public long[] getProcessPss(int[] pids) { 4653 enforceNotIsolatedCaller("getProcessPss"); 4654 long[] pss = new long[pids.length]; 4655 for (int i=pids.length-1; i>=0; i--) { 4656 ProcessRecord proc; 4657 int oomAdj; 4658 synchronized (this) { 4659 synchronized (mPidsSelfLocked) { 4660 proc = mPidsSelfLocked.get(pids[i]); 4661 oomAdj = proc != null ? proc.setAdj : 0; 4662 } 4663 } 4664 long[] tmpUss = new long[1]; 4665 pss[i] = Debug.getPss(pids[i], tmpUss); 4666 if (proc != null) { 4667 synchronized (this) { 4668 if (proc.thread != null && proc.setAdj == oomAdj) { 4669 // Record this for posterity if the process has been stable. 4670 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4671 } 4672 } 4673 } 4674 } 4675 return pss; 4676 } 4677 4678 @Override 4679 public void killApplicationProcess(String processName, int uid) { 4680 if (processName == null) { 4681 return; 4682 } 4683 4684 int callerUid = Binder.getCallingUid(); 4685 // Only the system server can kill an application 4686 if (callerUid == Process.SYSTEM_UID) { 4687 synchronized (this) { 4688 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4689 if (app != null && app.thread != null) { 4690 try { 4691 app.thread.scheduleSuicide(); 4692 } catch (RemoteException e) { 4693 // If the other end already died, then our work here is done. 4694 } 4695 } else { 4696 Slog.w(TAG, "Process/uid not found attempting kill of " 4697 + processName + " / " + uid); 4698 } 4699 } 4700 } else { 4701 throw new SecurityException(callerUid + " cannot kill app process: " + 4702 processName); 4703 } 4704 } 4705 4706 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4707 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4708 false, true, false, false, UserHandle.getUserId(uid), reason); 4709 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4710 Uri.fromParts("package", packageName, null)); 4711 if (!mProcessesReady) { 4712 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4713 | Intent.FLAG_RECEIVER_FOREGROUND); 4714 } 4715 intent.putExtra(Intent.EXTRA_UID, uid); 4716 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4717 broadcastIntentLocked(null, null, intent, 4718 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4719 false, false, 4720 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4721 } 4722 4723 private void forceStopUserLocked(int userId, String reason) { 4724 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4725 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4726 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4727 | Intent.FLAG_RECEIVER_FOREGROUND); 4728 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4729 broadcastIntentLocked(null, null, intent, 4730 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4731 false, false, 4732 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4733 } 4734 4735 private final boolean killPackageProcessesLocked(String packageName, int appId, 4736 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4737 boolean doit, boolean evenPersistent, String reason) { 4738 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4739 4740 // Remove all processes this package may have touched: all with the 4741 // same UID (except for the system or root user), and all whose name 4742 // matches the package name. 4743 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4744 final int NP = mProcessNames.getMap().size(); 4745 for (int ip=0; ip<NP; ip++) { 4746 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4747 final int NA = apps.size(); 4748 for (int ia=0; ia<NA; ia++) { 4749 ProcessRecord app = apps.valueAt(ia); 4750 if (app.persistent && !evenPersistent) { 4751 // we don't kill persistent processes 4752 continue; 4753 } 4754 if (app.removed) { 4755 if (doit) { 4756 procs.add(app); 4757 } 4758 continue; 4759 } 4760 4761 // Skip process if it doesn't meet our oom adj requirement. 4762 if (app.setAdj < minOomAdj) { 4763 continue; 4764 } 4765 4766 // If no package is specified, we call all processes under the 4767 // give user id. 4768 if (packageName == null) { 4769 if (app.userId != userId) { 4770 continue; 4771 } 4772 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4773 continue; 4774 } 4775 // Package has been specified, we want to hit all processes 4776 // that match it. We need to qualify this by the processes 4777 // that are running under the specified app and user ID. 4778 } else { 4779 if (UserHandle.getAppId(app.uid) != appId) { 4780 continue; 4781 } 4782 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4783 continue; 4784 } 4785 if (!app.pkgList.containsKey(packageName)) { 4786 continue; 4787 } 4788 } 4789 4790 // Process has passed all conditions, kill it! 4791 if (!doit) { 4792 return true; 4793 } 4794 app.removed = true; 4795 procs.add(app); 4796 } 4797 } 4798 4799 int N = procs.size(); 4800 for (int i=0; i<N; i++) { 4801 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4802 } 4803 updateOomAdjLocked(); 4804 return N > 0; 4805 } 4806 4807 private final boolean forceStopPackageLocked(String name, int appId, 4808 boolean callerWillRestart, boolean purgeCache, boolean doit, 4809 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4810 int i; 4811 int N; 4812 4813 if (userId == UserHandle.USER_ALL && name == null) { 4814 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4815 } 4816 4817 if (appId < 0 && name != null) { 4818 try { 4819 appId = UserHandle.getAppId( 4820 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4821 } catch (RemoteException e) { 4822 } 4823 } 4824 4825 if (doit) { 4826 if (name != null) { 4827 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4828 + " user=" + userId + ": " + reason); 4829 } else { 4830 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4831 } 4832 4833 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4834 for (int ip=pmap.size()-1; ip>=0; ip--) { 4835 SparseArray<Long> ba = pmap.valueAt(ip); 4836 for (i=ba.size()-1; i>=0; i--) { 4837 boolean remove = false; 4838 final int entUid = ba.keyAt(i); 4839 if (name != null) { 4840 if (userId == UserHandle.USER_ALL) { 4841 if (UserHandle.getAppId(entUid) == appId) { 4842 remove = true; 4843 } 4844 } else { 4845 if (entUid == UserHandle.getUid(userId, appId)) { 4846 remove = true; 4847 } 4848 } 4849 } else if (UserHandle.getUserId(entUid) == userId) { 4850 remove = true; 4851 } 4852 if (remove) { 4853 ba.removeAt(i); 4854 } 4855 } 4856 if (ba.size() == 0) { 4857 pmap.removeAt(ip); 4858 } 4859 } 4860 } 4861 4862 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4863 -100, callerWillRestart, true, doit, evenPersistent, 4864 name == null ? ("stop user " + userId) : ("stop " + name)); 4865 4866 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4867 if (!doit) { 4868 return true; 4869 } 4870 didSomething = true; 4871 } 4872 4873 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4874 if (!doit) { 4875 return true; 4876 } 4877 didSomething = true; 4878 } 4879 4880 if (name == null) { 4881 // Remove all sticky broadcasts from this user. 4882 mStickyBroadcasts.remove(userId); 4883 } 4884 4885 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4886 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4887 userId, providers)) { 4888 if (!doit) { 4889 return true; 4890 } 4891 didSomething = true; 4892 } 4893 N = providers.size(); 4894 for (i=0; i<N; i++) { 4895 removeDyingProviderLocked(null, providers.get(i), true); 4896 } 4897 4898 // Remove transient permissions granted from/to this package/user 4899 removeUriPermissionsForPackageLocked(name, userId, false); 4900 4901 if (name == null || uninstalling) { 4902 // Remove pending intents. For now we only do this when force 4903 // stopping users, because we have some problems when doing this 4904 // for packages -- app widgets are not currently cleaned up for 4905 // such packages, so they can be left with bad pending intents. 4906 if (mIntentSenderRecords.size() > 0) { 4907 Iterator<WeakReference<PendingIntentRecord>> it 4908 = mIntentSenderRecords.values().iterator(); 4909 while (it.hasNext()) { 4910 WeakReference<PendingIntentRecord> wpir = it.next(); 4911 if (wpir == null) { 4912 it.remove(); 4913 continue; 4914 } 4915 PendingIntentRecord pir = wpir.get(); 4916 if (pir == null) { 4917 it.remove(); 4918 continue; 4919 } 4920 if (name == null) { 4921 // Stopping user, remove all objects for the user. 4922 if (pir.key.userId != userId) { 4923 // Not the same user, skip it. 4924 continue; 4925 } 4926 } else { 4927 if (UserHandle.getAppId(pir.uid) != appId) { 4928 // Different app id, skip it. 4929 continue; 4930 } 4931 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4932 // Different user, skip it. 4933 continue; 4934 } 4935 if (!pir.key.packageName.equals(name)) { 4936 // Different package, skip it. 4937 continue; 4938 } 4939 } 4940 if (!doit) { 4941 return true; 4942 } 4943 didSomething = true; 4944 it.remove(); 4945 pir.canceled = true; 4946 if (pir.key.activity != null) { 4947 pir.key.activity.pendingResults.remove(pir.ref); 4948 } 4949 } 4950 } 4951 } 4952 4953 if (doit) { 4954 if (purgeCache && name != null) { 4955 AttributeCache ac = AttributeCache.instance(); 4956 if (ac != null) { 4957 ac.removePackage(name); 4958 } 4959 } 4960 if (mBooted) { 4961 mStackSupervisor.resumeTopActivitiesLocked(); 4962 mStackSupervisor.scheduleIdleLocked(); 4963 } 4964 } 4965 4966 return didSomething; 4967 } 4968 4969 private final boolean removeProcessLocked(ProcessRecord app, 4970 boolean callerWillRestart, boolean allowRestart, String reason) { 4971 final String name = app.processName; 4972 final int uid = app.uid; 4973 if (DEBUG_PROCESSES) Slog.d( 4974 TAG, "Force removing proc " + app.toShortString() + " (" + name 4975 + "/" + uid + ")"); 4976 4977 mProcessNames.remove(name, uid); 4978 mIsolatedProcesses.remove(app.uid); 4979 if (mHeavyWeightProcess == app) { 4980 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4981 mHeavyWeightProcess.userId, 0)); 4982 mHeavyWeightProcess = null; 4983 } 4984 boolean needRestart = false; 4985 if (app.pid > 0 && app.pid != MY_PID) { 4986 int pid = app.pid; 4987 synchronized (mPidsSelfLocked) { 4988 mPidsSelfLocked.remove(pid); 4989 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4990 } 4991 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4992 app.processName, app.info.uid); 4993 if (app.isolated) { 4994 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4995 } 4996 killUnneededProcessLocked(app, reason); 4997 handleAppDiedLocked(app, true, allowRestart); 4998 removeLruProcessLocked(app); 4999 5000 if (app.persistent && !app.isolated) { 5001 if (!callerWillRestart) { 5002 addAppLocked(app.info, false); 5003 } else { 5004 needRestart = true; 5005 } 5006 } 5007 } else { 5008 mRemovedProcesses.add(app); 5009 } 5010 5011 return needRestart; 5012 } 5013 5014 private final void processStartTimedOutLocked(ProcessRecord app) { 5015 final int pid = app.pid; 5016 boolean gone = false; 5017 synchronized (mPidsSelfLocked) { 5018 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5019 if (knownApp != null && knownApp.thread == null) { 5020 mPidsSelfLocked.remove(pid); 5021 gone = true; 5022 } 5023 } 5024 5025 if (gone) { 5026 Slog.w(TAG, "Process " + app + " failed to attach"); 5027 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5028 pid, app.uid, app.processName); 5029 mProcessNames.remove(app.processName, app.uid); 5030 mIsolatedProcesses.remove(app.uid); 5031 if (mHeavyWeightProcess == app) { 5032 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5033 mHeavyWeightProcess.userId, 0)); 5034 mHeavyWeightProcess = null; 5035 } 5036 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5037 app.processName, app.info.uid); 5038 if (app.isolated) { 5039 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5040 } 5041 // Take care of any launching providers waiting for this process. 5042 checkAppInLaunchingProvidersLocked(app, true); 5043 // Take care of any services that are waiting for the process. 5044 mServices.processStartTimedOutLocked(app); 5045 killUnneededProcessLocked(app, "start timeout"); 5046 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5047 Slog.w(TAG, "Unattached app died before backup, skipping"); 5048 try { 5049 IBackupManager bm = IBackupManager.Stub.asInterface( 5050 ServiceManager.getService(Context.BACKUP_SERVICE)); 5051 bm.agentDisconnected(app.info.packageName); 5052 } catch (RemoteException e) { 5053 // Can't happen; the backup manager is local 5054 } 5055 } 5056 if (isPendingBroadcastProcessLocked(pid)) { 5057 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5058 skipPendingBroadcastLocked(pid); 5059 } 5060 } else { 5061 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5062 } 5063 } 5064 5065 private final boolean attachApplicationLocked(IApplicationThread thread, 5066 int pid) { 5067 5068 // Find the application record that is being attached... either via 5069 // the pid if we are running in multiple processes, or just pull the 5070 // next app record if we are emulating process with anonymous threads. 5071 ProcessRecord app; 5072 if (pid != MY_PID && pid >= 0) { 5073 synchronized (mPidsSelfLocked) { 5074 app = mPidsSelfLocked.get(pid); 5075 } 5076 } else { 5077 app = null; 5078 } 5079 5080 if (app == null) { 5081 Slog.w(TAG, "No pending application record for pid " + pid 5082 + " (IApplicationThread " + thread + "); dropping process"); 5083 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5084 if (pid > 0 && pid != MY_PID) { 5085 Process.killProcessQuiet(pid); 5086 } else { 5087 try { 5088 thread.scheduleExit(); 5089 } catch (Exception e) { 5090 // Ignore exceptions. 5091 } 5092 } 5093 return false; 5094 } 5095 5096 // If this application record is still attached to a previous 5097 // process, clean it up now. 5098 if (app.thread != null) { 5099 handleAppDiedLocked(app, true, true); 5100 } 5101 5102 // Tell the process all about itself. 5103 5104 if (localLOGV) Slog.v( 5105 TAG, "Binding process pid " + pid + " to record " + app); 5106 5107 final String processName = app.processName; 5108 try { 5109 AppDeathRecipient adr = new AppDeathRecipient( 5110 app, pid, thread); 5111 thread.asBinder().linkToDeath(adr, 0); 5112 app.deathRecipient = adr; 5113 } catch (RemoteException e) { 5114 app.resetPackageList(mProcessStats); 5115 startProcessLocked(app, "link fail", processName); 5116 return false; 5117 } 5118 5119 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5120 5121 app.makeActive(thread, mProcessStats); 5122 app.curAdj = app.setAdj = -100; 5123 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5124 app.forcingToForeground = null; 5125 updateProcessForegroundLocked(app, false, false); 5126 app.hasShownUi = false; 5127 app.debugging = false; 5128 app.cached = false; 5129 5130 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5131 5132 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5133 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5134 5135 if (!normalMode) { 5136 Slog.i(TAG, "Launching preboot mode app: " + app); 5137 } 5138 5139 if (localLOGV) Slog.v( 5140 TAG, "New app record " + app 5141 + " thread=" + thread.asBinder() + " pid=" + pid); 5142 try { 5143 int testMode = IApplicationThread.DEBUG_OFF; 5144 if (mDebugApp != null && mDebugApp.equals(processName)) { 5145 testMode = mWaitForDebugger 5146 ? IApplicationThread.DEBUG_WAIT 5147 : IApplicationThread.DEBUG_ON; 5148 app.debugging = true; 5149 if (mDebugTransient) { 5150 mDebugApp = mOrigDebugApp; 5151 mWaitForDebugger = mOrigWaitForDebugger; 5152 } 5153 } 5154 String profileFile = app.instrumentationProfileFile; 5155 ParcelFileDescriptor profileFd = null; 5156 boolean profileAutoStop = false; 5157 if (mProfileApp != null && mProfileApp.equals(processName)) { 5158 mProfileProc = app; 5159 profileFile = mProfileFile; 5160 profileFd = mProfileFd; 5161 profileAutoStop = mAutoStopProfiler; 5162 } 5163 boolean enableOpenGlTrace = false; 5164 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5165 enableOpenGlTrace = true; 5166 mOpenGlTraceApp = null; 5167 } 5168 5169 // If the app is being launched for restore or full backup, set it up specially 5170 boolean isRestrictedBackupMode = false; 5171 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5172 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5173 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5174 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5175 } 5176 5177 ensurePackageDexOpt(app.instrumentationInfo != null 5178 ? app.instrumentationInfo.packageName 5179 : app.info.packageName); 5180 if (app.instrumentationClass != null) { 5181 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5182 } 5183 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5184 + processName + " with config " + mConfiguration); 5185 ApplicationInfo appInfo = app.instrumentationInfo != null 5186 ? app.instrumentationInfo : app.info; 5187 app.compat = compatibilityInfoForPackageLocked(appInfo); 5188 if (profileFd != null) { 5189 profileFd = profileFd.dup(); 5190 } 5191 thread.bindApplication(processName, appInfo, providers, 5192 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5193 app.instrumentationArguments, app.instrumentationWatcher, 5194 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5195 isRestrictedBackupMode || !normalMode, app.persistent, 5196 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5197 mCoreSettingsObserver.getCoreSettingsLocked()); 5198 updateLruProcessLocked(app, false, null); 5199 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5200 } catch (Exception e) { 5201 // todo: Yikes! What should we do? For now we will try to 5202 // start another process, but that could easily get us in 5203 // an infinite loop of restarting processes... 5204 Slog.w(TAG, "Exception thrown during bind!", e); 5205 5206 app.resetPackageList(mProcessStats); 5207 app.unlinkDeathRecipient(); 5208 startProcessLocked(app, "bind fail", processName); 5209 return false; 5210 } 5211 5212 // Remove this record from the list of starting applications. 5213 mPersistentStartingProcesses.remove(app); 5214 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5215 "Attach application locked removing on hold: " + app); 5216 mProcessesOnHold.remove(app); 5217 5218 boolean badApp = false; 5219 boolean didSomething = false; 5220 5221 // See if the top visible activity is waiting to run in this process... 5222 if (normalMode) { 5223 try { 5224 if (mStackSupervisor.attachApplicationLocked(app)) { 5225 didSomething = true; 5226 } 5227 } catch (Exception e) { 5228 badApp = true; 5229 } 5230 } 5231 5232 // Find any services that should be running in this process... 5233 if (!badApp) { 5234 try { 5235 didSomething |= mServices.attachApplicationLocked(app, processName); 5236 } catch (Exception e) { 5237 badApp = true; 5238 } 5239 } 5240 5241 // Check if a next-broadcast receiver is in this process... 5242 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5243 try { 5244 didSomething |= sendPendingBroadcastsLocked(app); 5245 } catch (Exception e) { 5246 // If the app died trying to launch the receiver we declare it 'bad' 5247 badApp = true; 5248 } 5249 } 5250 5251 // Check whether the next backup agent is in this process... 5252 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5253 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5254 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5255 try { 5256 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5257 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5258 mBackupTarget.backupMode); 5259 } catch (Exception e) { 5260 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5261 e.printStackTrace(); 5262 } 5263 } 5264 5265 if (badApp) { 5266 // todo: Also need to kill application to deal with all 5267 // kinds of exceptions. 5268 handleAppDiedLocked(app, false, true); 5269 return false; 5270 } 5271 5272 if (!didSomething) { 5273 updateOomAdjLocked(); 5274 } 5275 5276 return true; 5277 } 5278 5279 @Override 5280 public final void attachApplication(IApplicationThread thread) { 5281 synchronized (this) { 5282 int callingPid = Binder.getCallingPid(); 5283 final long origId = Binder.clearCallingIdentity(); 5284 attachApplicationLocked(thread, callingPid); 5285 Binder.restoreCallingIdentity(origId); 5286 } 5287 } 5288 5289 @Override 5290 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5291 final long origId = Binder.clearCallingIdentity(); 5292 synchronized (this) { 5293 ActivityStack stack = ActivityRecord.getStackLocked(token); 5294 if (stack != null) { 5295 ActivityRecord r = 5296 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5297 if (stopProfiling) { 5298 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5299 try { 5300 mProfileFd.close(); 5301 } catch (IOException e) { 5302 } 5303 clearProfilerLocked(); 5304 } 5305 } 5306 } 5307 } 5308 Binder.restoreCallingIdentity(origId); 5309 } 5310 5311 void enableScreenAfterBoot() { 5312 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5313 SystemClock.uptimeMillis()); 5314 mWindowManager.enableScreenAfterBoot(); 5315 5316 synchronized (this) { 5317 updateEventDispatchingLocked(); 5318 } 5319 } 5320 5321 @Override 5322 public void showBootMessage(final CharSequence msg, final boolean always) { 5323 enforceNotIsolatedCaller("showBootMessage"); 5324 mWindowManager.showBootMessage(msg, always); 5325 } 5326 5327 @Override 5328 public void dismissKeyguardOnNextActivity() { 5329 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5330 final long token = Binder.clearCallingIdentity(); 5331 try { 5332 synchronized (this) { 5333 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5334 if (mLockScreenShown) { 5335 mLockScreenShown = false; 5336 comeOutOfSleepIfNeededLocked(); 5337 } 5338 mStackSupervisor.setDismissKeyguard(true); 5339 } 5340 } finally { 5341 Binder.restoreCallingIdentity(token); 5342 } 5343 } 5344 5345 final void finishBooting() { 5346 // Register receivers to handle package update events 5347 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5348 5349 synchronized (this) { 5350 // Ensure that any processes we had put on hold are now started 5351 // up. 5352 final int NP = mProcessesOnHold.size(); 5353 if (NP > 0) { 5354 ArrayList<ProcessRecord> procs = 5355 new ArrayList<ProcessRecord>(mProcessesOnHold); 5356 for (int ip=0; ip<NP; ip++) { 5357 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5358 + procs.get(ip)); 5359 startProcessLocked(procs.get(ip), "on-hold", null); 5360 } 5361 } 5362 5363 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5364 // Start looking for apps that are abusing wake locks. 5365 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5366 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5367 // Tell anyone interested that we are done booting! 5368 SystemProperties.set("sys.boot_completed", "1"); 5369 SystemProperties.set("dev.bootcomplete", "1"); 5370 for (int i=0; i<mStartedUsers.size(); i++) { 5371 UserStartedState uss = mStartedUsers.valueAt(i); 5372 if (uss.mState == UserStartedState.STATE_BOOTING) { 5373 uss.mState = UserStartedState.STATE_RUNNING; 5374 final int userId = mStartedUsers.keyAt(i); 5375 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5376 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5377 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5378 broadcastIntentLocked(null, null, intent, null, 5379 new IIntentReceiver.Stub() { 5380 @Override 5381 public void performReceive(Intent intent, int resultCode, 5382 String data, Bundle extras, boolean ordered, 5383 boolean sticky, int sendingUser) { 5384 synchronized (ActivityManagerService.this) { 5385 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5386 true, false); 5387 } 5388 } 5389 }, 5390 0, null, null, 5391 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5392 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5393 userId); 5394 } 5395 } 5396 scheduleStartProfilesLocked(); 5397 } 5398 } 5399 } 5400 5401 final void ensureBootCompleted() { 5402 boolean booting; 5403 boolean enableScreen; 5404 synchronized (this) { 5405 booting = mBooting; 5406 mBooting = false; 5407 enableScreen = !mBooted; 5408 mBooted = true; 5409 } 5410 5411 if (booting) { 5412 finishBooting(); 5413 } 5414 5415 if (enableScreen) { 5416 enableScreenAfterBoot(); 5417 } 5418 } 5419 5420 @Override 5421 public final void activityResumed(IBinder token) { 5422 final long origId = Binder.clearCallingIdentity(); 5423 synchronized(this) { 5424 ActivityStack stack = ActivityRecord.getStackLocked(token); 5425 if (stack != null) { 5426 ActivityRecord.activityResumedLocked(token); 5427 } 5428 } 5429 Binder.restoreCallingIdentity(origId); 5430 } 5431 5432 @Override 5433 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5434 final long origId = Binder.clearCallingIdentity(); 5435 synchronized(this) { 5436 ActivityStack stack = ActivityRecord.getStackLocked(token); 5437 if (stack != null) { 5438 stack.activityPausedLocked(token, false, persistentState); 5439 } 5440 } 5441 Binder.restoreCallingIdentity(origId); 5442 } 5443 5444 @Override 5445 public final void activityStopped(IBinder token, Bundle icicle, 5446 PersistableBundle persistentState, CharSequence description) { 5447 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5448 5449 // Refuse possible leaked file descriptors 5450 if (icicle != null && icicle.hasFileDescriptors()) { 5451 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5452 } 5453 5454 final long origId = Binder.clearCallingIdentity(); 5455 5456 synchronized (this) { 5457 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5458 if (r != null) { 5459 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5460 } 5461 } 5462 5463 trimApplications(); 5464 5465 Binder.restoreCallingIdentity(origId); 5466 } 5467 5468 @Override 5469 public final void activityDestroyed(IBinder token) { 5470 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5471 synchronized (this) { 5472 ActivityStack stack = ActivityRecord.getStackLocked(token); 5473 if (stack != null) { 5474 stack.activityDestroyedLocked(token); 5475 } 5476 } 5477 } 5478 5479 @Override 5480 public String getCallingPackage(IBinder token) { 5481 synchronized (this) { 5482 ActivityRecord r = getCallingRecordLocked(token); 5483 return r != null ? r.info.packageName : null; 5484 } 5485 } 5486 5487 @Override 5488 public ComponentName getCallingActivity(IBinder token) { 5489 synchronized (this) { 5490 ActivityRecord r = getCallingRecordLocked(token); 5491 return r != null ? r.intent.getComponent() : null; 5492 } 5493 } 5494 5495 private ActivityRecord getCallingRecordLocked(IBinder token) { 5496 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5497 if (r == null) { 5498 return null; 5499 } 5500 return r.resultTo; 5501 } 5502 5503 @Override 5504 public ComponentName getActivityClassForToken(IBinder token) { 5505 synchronized(this) { 5506 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5507 if (r == null) { 5508 return null; 5509 } 5510 return r.intent.getComponent(); 5511 } 5512 } 5513 5514 @Override 5515 public String getPackageForToken(IBinder token) { 5516 synchronized(this) { 5517 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5518 if (r == null) { 5519 return null; 5520 } 5521 return r.packageName; 5522 } 5523 } 5524 5525 @Override 5526 public IIntentSender getIntentSender(int type, 5527 String packageName, IBinder token, String resultWho, 5528 int requestCode, Intent[] intents, String[] resolvedTypes, 5529 int flags, Bundle options, int userId) { 5530 enforceNotIsolatedCaller("getIntentSender"); 5531 // Refuse possible leaked file descriptors 5532 if (intents != null) { 5533 if (intents.length < 1) { 5534 throw new IllegalArgumentException("Intents array length must be >= 1"); 5535 } 5536 for (int i=0; i<intents.length; i++) { 5537 Intent intent = intents[i]; 5538 if (intent != null) { 5539 if (intent.hasFileDescriptors()) { 5540 throw new IllegalArgumentException("File descriptors passed in Intent"); 5541 } 5542 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5543 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5544 throw new IllegalArgumentException( 5545 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5546 } 5547 intents[i] = new Intent(intent); 5548 } 5549 } 5550 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5551 throw new IllegalArgumentException( 5552 "Intent array length does not match resolvedTypes length"); 5553 } 5554 } 5555 if (options != null) { 5556 if (options.hasFileDescriptors()) { 5557 throw new IllegalArgumentException("File descriptors passed in options"); 5558 } 5559 } 5560 5561 synchronized(this) { 5562 int callingUid = Binder.getCallingUid(); 5563 int origUserId = userId; 5564 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5565 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5566 "getIntentSender", null); 5567 if (origUserId == UserHandle.USER_CURRENT) { 5568 // We don't want to evaluate this until the pending intent is 5569 // actually executed. However, we do want to always do the 5570 // security checking for it above. 5571 userId = UserHandle.USER_CURRENT; 5572 } 5573 try { 5574 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5575 int uid = AppGlobals.getPackageManager() 5576 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5577 if (!UserHandle.isSameApp(callingUid, uid)) { 5578 String msg = "Permission Denial: getIntentSender() from pid=" 5579 + Binder.getCallingPid() 5580 + ", uid=" + Binder.getCallingUid() 5581 + ", (need uid=" + uid + ")" 5582 + " is not allowed to send as package " + packageName; 5583 Slog.w(TAG, msg); 5584 throw new SecurityException(msg); 5585 } 5586 } 5587 5588 return getIntentSenderLocked(type, packageName, callingUid, userId, 5589 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5590 5591 } catch (RemoteException e) { 5592 throw new SecurityException(e); 5593 } 5594 } 5595 } 5596 5597 IIntentSender getIntentSenderLocked(int type, String packageName, 5598 int callingUid, int userId, IBinder token, String resultWho, 5599 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5600 Bundle options) { 5601 if (DEBUG_MU) 5602 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5603 ActivityRecord activity = null; 5604 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5605 activity = ActivityRecord.isInStackLocked(token); 5606 if (activity == null) { 5607 return null; 5608 } 5609 if (activity.finishing) { 5610 return null; 5611 } 5612 } 5613 5614 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5615 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5616 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5617 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5618 |PendingIntent.FLAG_UPDATE_CURRENT); 5619 5620 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5621 type, packageName, activity, resultWho, 5622 requestCode, intents, resolvedTypes, flags, options, userId); 5623 WeakReference<PendingIntentRecord> ref; 5624 ref = mIntentSenderRecords.get(key); 5625 PendingIntentRecord rec = ref != null ? ref.get() : null; 5626 if (rec != null) { 5627 if (!cancelCurrent) { 5628 if (updateCurrent) { 5629 if (rec.key.requestIntent != null) { 5630 rec.key.requestIntent.replaceExtras(intents != null ? 5631 intents[intents.length - 1] : null); 5632 } 5633 if (intents != null) { 5634 intents[intents.length-1] = rec.key.requestIntent; 5635 rec.key.allIntents = intents; 5636 rec.key.allResolvedTypes = resolvedTypes; 5637 } else { 5638 rec.key.allIntents = null; 5639 rec.key.allResolvedTypes = null; 5640 } 5641 } 5642 return rec; 5643 } 5644 rec.canceled = true; 5645 mIntentSenderRecords.remove(key); 5646 } 5647 if (noCreate) { 5648 return rec; 5649 } 5650 rec = new PendingIntentRecord(this, key, callingUid); 5651 mIntentSenderRecords.put(key, rec.ref); 5652 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5653 if (activity.pendingResults == null) { 5654 activity.pendingResults 5655 = new HashSet<WeakReference<PendingIntentRecord>>(); 5656 } 5657 activity.pendingResults.add(rec.ref); 5658 } 5659 return rec; 5660 } 5661 5662 @Override 5663 public void cancelIntentSender(IIntentSender sender) { 5664 if (!(sender instanceof PendingIntentRecord)) { 5665 return; 5666 } 5667 synchronized(this) { 5668 PendingIntentRecord rec = (PendingIntentRecord)sender; 5669 try { 5670 int uid = AppGlobals.getPackageManager() 5671 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5672 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5673 String msg = "Permission Denial: cancelIntentSender() from pid=" 5674 + Binder.getCallingPid() 5675 + ", uid=" + Binder.getCallingUid() 5676 + " is not allowed to cancel packges " 5677 + rec.key.packageName; 5678 Slog.w(TAG, msg); 5679 throw new SecurityException(msg); 5680 } 5681 } catch (RemoteException e) { 5682 throw new SecurityException(e); 5683 } 5684 cancelIntentSenderLocked(rec, true); 5685 } 5686 } 5687 5688 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5689 rec.canceled = true; 5690 mIntentSenderRecords.remove(rec.key); 5691 if (cleanActivity && rec.key.activity != null) { 5692 rec.key.activity.pendingResults.remove(rec.ref); 5693 } 5694 } 5695 5696 @Override 5697 public String getPackageForIntentSender(IIntentSender pendingResult) { 5698 if (!(pendingResult instanceof PendingIntentRecord)) { 5699 return null; 5700 } 5701 try { 5702 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5703 return res.key.packageName; 5704 } catch (ClassCastException e) { 5705 } 5706 return null; 5707 } 5708 5709 @Override 5710 public int getUidForIntentSender(IIntentSender sender) { 5711 if (sender instanceof PendingIntentRecord) { 5712 try { 5713 PendingIntentRecord res = (PendingIntentRecord)sender; 5714 return res.uid; 5715 } catch (ClassCastException e) { 5716 } 5717 } 5718 return -1; 5719 } 5720 5721 @Override 5722 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5723 if (!(pendingResult instanceof PendingIntentRecord)) { 5724 return false; 5725 } 5726 try { 5727 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5728 if (res.key.allIntents == null) { 5729 return false; 5730 } 5731 for (int i=0; i<res.key.allIntents.length; i++) { 5732 Intent intent = res.key.allIntents[i]; 5733 if (intent.getPackage() != null && intent.getComponent() != null) { 5734 return false; 5735 } 5736 } 5737 return true; 5738 } catch (ClassCastException e) { 5739 } 5740 return false; 5741 } 5742 5743 @Override 5744 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5745 if (!(pendingResult instanceof PendingIntentRecord)) { 5746 return false; 5747 } 5748 try { 5749 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5750 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5751 return true; 5752 } 5753 return false; 5754 } catch (ClassCastException e) { 5755 } 5756 return false; 5757 } 5758 5759 @Override 5760 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5761 if (!(pendingResult instanceof PendingIntentRecord)) { 5762 return null; 5763 } 5764 try { 5765 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5766 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5767 } catch (ClassCastException e) { 5768 } 5769 return null; 5770 } 5771 5772 @Override 5773 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5774 if (!(pendingResult instanceof PendingIntentRecord)) { 5775 return null; 5776 } 5777 try { 5778 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5779 Intent intent = res.key.requestIntent; 5780 if (intent != null) { 5781 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5782 || res.lastTagPrefix.equals(prefix))) { 5783 return res.lastTag; 5784 } 5785 res.lastTagPrefix = prefix; 5786 StringBuilder sb = new StringBuilder(128); 5787 if (prefix != null) { 5788 sb.append(prefix); 5789 } 5790 if (intent.getAction() != null) { 5791 sb.append(intent.getAction()); 5792 } else if (intent.getComponent() != null) { 5793 intent.getComponent().appendShortString(sb); 5794 } else { 5795 sb.append("?"); 5796 } 5797 return res.lastTag = sb.toString(); 5798 } 5799 } catch (ClassCastException e) { 5800 } 5801 return null; 5802 } 5803 5804 @Override 5805 public void setProcessLimit(int max) { 5806 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5807 "setProcessLimit()"); 5808 synchronized (this) { 5809 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5810 mProcessLimitOverride = max; 5811 } 5812 trimApplications(); 5813 } 5814 5815 @Override 5816 public int getProcessLimit() { 5817 synchronized (this) { 5818 return mProcessLimitOverride; 5819 } 5820 } 5821 5822 void foregroundTokenDied(ForegroundToken token) { 5823 synchronized (ActivityManagerService.this) { 5824 synchronized (mPidsSelfLocked) { 5825 ForegroundToken cur 5826 = mForegroundProcesses.get(token.pid); 5827 if (cur != token) { 5828 return; 5829 } 5830 mForegroundProcesses.remove(token.pid); 5831 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5832 if (pr == null) { 5833 return; 5834 } 5835 pr.forcingToForeground = null; 5836 updateProcessForegroundLocked(pr, false, false); 5837 } 5838 updateOomAdjLocked(); 5839 } 5840 } 5841 5842 @Override 5843 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5844 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5845 "setProcessForeground()"); 5846 synchronized(this) { 5847 boolean changed = false; 5848 5849 synchronized (mPidsSelfLocked) { 5850 ProcessRecord pr = mPidsSelfLocked.get(pid); 5851 if (pr == null && isForeground) { 5852 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5853 return; 5854 } 5855 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5856 if (oldToken != null) { 5857 oldToken.token.unlinkToDeath(oldToken, 0); 5858 mForegroundProcesses.remove(pid); 5859 if (pr != null) { 5860 pr.forcingToForeground = null; 5861 } 5862 changed = true; 5863 } 5864 if (isForeground && token != null) { 5865 ForegroundToken newToken = new ForegroundToken() { 5866 @Override 5867 public void binderDied() { 5868 foregroundTokenDied(this); 5869 } 5870 }; 5871 newToken.pid = pid; 5872 newToken.token = token; 5873 try { 5874 token.linkToDeath(newToken, 0); 5875 mForegroundProcesses.put(pid, newToken); 5876 pr.forcingToForeground = token; 5877 changed = true; 5878 } catch (RemoteException e) { 5879 // If the process died while doing this, we will later 5880 // do the cleanup with the process death link. 5881 } 5882 } 5883 } 5884 5885 if (changed) { 5886 updateOomAdjLocked(); 5887 } 5888 } 5889 } 5890 5891 // ========================================================= 5892 // PERMISSIONS 5893 // ========================================================= 5894 5895 static class PermissionController extends IPermissionController.Stub { 5896 ActivityManagerService mActivityManagerService; 5897 PermissionController(ActivityManagerService activityManagerService) { 5898 mActivityManagerService = activityManagerService; 5899 } 5900 5901 @Override 5902 public boolean checkPermission(String permission, int pid, int uid) { 5903 return mActivityManagerService.checkPermission(permission, pid, 5904 uid) == PackageManager.PERMISSION_GRANTED; 5905 } 5906 } 5907 5908 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5909 @Override 5910 public int checkComponentPermission(String permission, int pid, int uid, 5911 int owningUid, boolean exported) { 5912 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5913 owningUid, exported); 5914 } 5915 5916 @Override 5917 public Object getAMSLock() { 5918 return ActivityManagerService.this; 5919 } 5920 } 5921 5922 /** 5923 * This can be called with or without the global lock held. 5924 */ 5925 int checkComponentPermission(String permission, int pid, int uid, 5926 int owningUid, boolean exported) { 5927 // We might be performing an operation on behalf of an indirect binder 5928 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5929 // client identity accordingly before proceeding. 5930 Identity tlsIdentity = sCallerIdentity.get(); 5931 if (tlsIdentity != null) { 5932 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5933 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5934 uid = tlsIdentity.uid; 5935 pid = tlsIdentity.pid; 5936 } 5937 5938 if (pid == MY_PID) { 5939 return PackageManager.PERMISSION_GRANTED; 5940 } 5941 5942 return ActivityManager.checkComponentPermission(permission, uid, 5943 owningUid, exported); 5944 } 5945 5946 /** 5947 * As the only public entry point for permissions checking, this method 5948 * can enforce the semantic that requesting a check on a null global 5949 * permission is automatically denied. (Internally a null permission 5950 * string is used when calling {@link #checkComponentPermission} in cases 5951 * when only uid-based security is needed.) 5952 * 5953 * This can be called with or without the global lock held. 5954 */ 5955 @Override 5956 public int checkPermission(String permission, int pid, int uid) { 5957 if (permission == null) { 5958 return PackageManager.PERMISSION_DENIED; 5959 } 5960 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5961 } 5962 5963 /** 5964 * Binder IPC calls go through the public entry point. 5965 * This can be called with or without the global lock held. 5966 */ 5967 int checkCallingPermission(String permission) { 5968 return checkPermission(permission, 5969 Binder.getCallingPid(), 5970 UserHandle.getAppId(Binder.getCallingUid())); 5971 } 5972 5973 /** 5974 * This can be called with or without the global lock held. 5975 */ 5976 void enforceCallingPermission(String permission, String func) { 5977 if (checkCallingPermission(permission) 5978 == PackageManager.PERMISSION_GRANTED) { 5979 return; 5980 } 5981 5982 String msg = "Permission Denial: " + func + " from pid=" 5983 + Binder.getCallingPid() 5984 + ", uid=" + Binder.getCallingUid() 5985 + " requires " + permission; 5986 Slog.w(TAG, msg); 5987 throw new SecurityException(msg); 5988 } 5989 5990 /** 5991 * Determine if UID is holding permissions required to access {@link Uri} in 5992 * the given {@link ProviderInfo}. Final permission checking is always done 5993 * in {@link ContentProvider}. 5994 */ 5995 private final boolean checkHoldingPermissionsLocked( 5996 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) { 5997 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5998 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5999 6000 if (pi.applicationInfo.uid == uid) { 6001 return true; 6002 } else if (!pi.exported) { 6003 return false; 6004 } 6005 6006 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6007 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6008 try { 6009 // check if target holds top-level <provider> permissions 6010 if (!readMet && pi.readPermission != null 6011 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6012 readMet = true; 6013 } 6014 if (!writeMet && pi.writePermission != null 6015 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6016 writeMet = true; 6017 } 6018 6019 // track if unprotected read/write is allowed; any denied 6020 // <path-permission> below removes this ability 6021 boolean allowDefaultRead = pi.readPermission == null; 6022 boolean allowDefaultWrite = pi.writePermission == null; 6023 6024 // check if target holds any <path-permission> that match uri 6025 final PathPermission[] pps = pi.pathPermissions; 6026 if (pps != null) { 6027 final String path = uri.getPath(); 6028 int i = pps.length; 6029 while (i > 0 && (!readMet || !writeMet)) { 6030 i--; 6031 PathPermission pp = pps[i]; 6032 if (pp.match(path)) { 6033 if (!readMet) { 6034 final String pprperm = pp.getReadPermission(); 6035 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6036 + pprperm + " for " + pp.getPath() 6037 + ": match=" + pp.match(path) 6038 + " check=" + pm.checkUidPermission(pprperm, uid)); 6039 if (pprperm != null) { 6040 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 6041 readMet = true; 6042 } else { 6043 allowDefaultRead = false; 6044 } 6045 } 6046 } 6047 if (!writeMet) { 6048 final String ppwperm = pp.getWritePermission(); 6049 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6050 + ppwperm + " for " + pp.getPath() 6051 + ": match=" + pp.match(path) 6052 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6053 if (ppwperm != null) { 6054 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 6055 writeMet = true; 6056 } else { 6057 allowDefaultWrite = false; 6058 } 6059 } 6060 } 6061 } 6062 } 6063 } 6064 6065 // grant unprotected <provider> read/write, if not blocked by 6066 // <path-permission> above 6067 if (allowDefaultRead) readMet = true; 6068 if (allowDefaultWrite) writeMet = true; 6069 6070 } catch (RemoteException e) { 6071 return false; 6072 } 6073 6074 return readMet && writeMet; 6075 } 6076 6077 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6078 ProviderInfo pi = null; 6079 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6080 if (cpr != null) { 6081 pi = cpr.info; 6082 } else { 6083 try { 6084 pi = AppGlobals.getPackageManager().resolveContentProvider( 6085 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6086 } catch (RemoteException ex) { 6087 } 6088 } 6089 return pi; 6090 } 6091 6092 private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) { 6093 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6094 if (targetUris != null) { 6095 return targetUris.get(uri); 6096 } 6097 return null; 6098 } 6099 6100 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6101 String targetPkg, int targetUid, GrantUri uri) { 6102 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6103 if (targetUris == null) { 6104 targetUris = Maps.newArrayMap(); 6105 mGrantedUriPermissions.put(targetUid, targetUris); 6106 } 6107 6108 UriPermission perm = targetUris.get(uri); 6109 if (perm == null) { 6110 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 6111 targetUris.put(uri, perm); 6112 } 6113 6114 return perm; 6115 } 6116 6117 private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) { 6118 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6119 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6120 : UriPermission.STRENGTH_OWNED; 6121 6122 // Root gets to do everything. 6123 if (uid == 0) { 6124 return true; 6125 } 6126 6127 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6128 if (perms == null) return false; 6129 6130 // First look for exact match 6131 final UriPermission exactPerm = perms.get(new GrantUri(uri, false)); 6132 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6133 return true; 6134 } 6135 6136 // No exact match, look for prefixes 6137 final int N = perms.size(); 6138 for (int i = 0; i < N; i++) { 6139 final UriPermission perm = perms.valueAt(i); 6140 if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri) 6141 && perm.getStrength(modeFlags) >= minStrength) { 6142 return true; 6143 } 6144 } 6145 6146 return false; 6147 } 6148 6149 @Override 6150 public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) { 6151 enforceNotIsolatedCaller("checkUriPermission"); 6152 6153 // Another redirected-binder-call permissions check as in 6154 // {@link checkComponentPermission}. 6155 Identity tlsIdentity = sCallerIdentity.get(); 6156 if (tlsIdentity != null) { 6157 uid = tlsIdentity.uid; 6158 pid = tlsIdentity.pid; 6159 } 6160 6161 // Our own process gets to do everything. 6162 if (pid == MY_PID) { 6163 return PackageManager.PERMISSION_GRANTED; 6164 } 6165 synchronized (this) { 6166 return checkUriPermissionLocked(uri, uid, modeFlags) 6167 ? PackageManager.PERMISSION_GRANTED 6168 : PackageManager.PERMISSION_DENIED; 6169 } 6170 } 6171 6172 /** 6173 * Check if the targetPkg can be granted permission to access uri by 6174 * the callingUid using the given modeFlags. Throws a security exception 6175 * if callingUid is not allowed to do this. Returns the uid of the target 6176 * if the URI permission grant should be performed; returns -1 if it is not 6177 * needed (for example targetPkg already has permission to access the URI). 6178 * If you already know the uid of the target, you can supply it in 6179 * lastTargetUid else set that to -1. 6180 */ 6181 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 6182 Uri uri, final int modeFlags, int lastTargetUid) { 6183 if (!Intent.isAccessUriMode(modeFlags)) { 6184 return -1; 6185 } 6186 6187 if (targetPkg != null) { 6188 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6189 "Checking grant " + targetPkg + " permission to " + uri); 6190 } 6191 6192 final IPackageManager pm = AppGlobals.getPackageManager(); 6193 6194 // If this is not a content: uri, we can't do anything with it. 6195 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 6196 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6197 "Can't grant URI permission for non-content URI: " + uri); 6198 return -1; 6199 } 6200 6201 final String authority = uri.getAuthority(); 6202 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6203 if (pi == null) { 6204 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 6205 return -1; 6206 } 6207 6208 int targetUid = lastTargetUid; 6209 if (targetUid < 0 && targetPkg != null) { 6210 try { 6211 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6212 if (targetUid < 0) { 6213 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6214 "Can't grant URI permission no uid for: " + targetPkg); 6215 return -1; 6216 } 6217 } catch (RemoteException ex) { 6218 return -1; 6219 } 6220 } 6221 6222 if (targetUid >= 0) { 6223 // First... does the target actually need this permission? 6224 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 6225 // No need to grant the target this permission. 6226 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6227 "Target " + targetPkg + " already has full permission to " + uri); 6228 return -1; 6229 } 6230 } else { 6231 // First... there is no target package, so can anyone access it? 6232 boolean allowed = pi.exported; 6233 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6234 if (pi.readPermission != null) { 6235 allowed = false; 6236 } 6237 } 6238 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6239 if (pi.writePermission != null) { 6240 allowed = false; 6241 } 6242 } 6243 if (allowed) { 6244 return -1; 6245 } 6246 } 6247 6248 // Second... is the provider allowing granting of URI permissions? 6249 if (!pi.grantUriPermissions) { 6250 throw new SecurityException("Provider " + pi.packageName 6251 + "/" + pi.name 6252 + " does not allow granting of Uri permissions (uri " 6253 + uri + ")"); 6254 } 6255 if (pi.uriPermissionPatterns != null) { 6256 final int N = pi.uriPermissionPatterns.length; 6257 boolean allowed = false; 6258 for (int i=0; i<N; i++) { 6259 if (pi.uriPermissionPatterns[i] != null 6260 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6261 allowed = true; 6262 break; 6263 } 6264 } 6265 if (!allowed) { 6266 throw new SecurityException("Provider " + pi.packageName 6267 + "/" + pi.name 6268 + " does not allow granting of permission to path of Uri " 6269 + uri); 6270 } 6271 } 6272 6273 // Third... does the caller itself have permission to access 6274 // this uri? 6275 if (callingUid != Process.myUid()) { 6276 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6277 // Require they hold a strong enough Uri permission 6278 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6279 throw new SecurityException("Uid " + callingUid 6280 + " does not have permission to uri " + uri); 6281 } 6282 } 6283 } 6284 6285 return targetUid; 6286 } 6287 6288 @Override 6289 public int checkGrantUriPermission(int callingUid, String targetPkg, 6290 Uri uri, final int modeFlags) { 6291 enforceNotIsolatedCaller("checkGrantUriPermission"); 6292 synchronized(this) { 6293 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6294 } 6295 } 6296 6297 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri, 6298 final int modeFlags, UriPermissionOwner owner) { 6299 if (!Intent.isAccessUriMode(modeFlags)) { 6300 return; 6301 } 6302 6303 // So here we are: the caller has the assumed permission 6304 // to the uri, and the target doesn't. Let's now give this to 6305 // the target. 6306 6307 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6308 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6309 6310 final String authority = uri.getAuthority(); 6311 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6312 if (pi == null) { 6313 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6314 return; 6315 } 6316 6317 final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0; 6318 final UriPermission perm = findOrCreateUriPermissionLocked( 6319 pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix)); 6320 perm.grantModes(modeFlags, owner); 6321 } 6322 6323 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6324 final int modeFlags, UriPermissionOwner owner) { 6325 if (targetPkg == null) { 6326 throw new NullPointerException("targetPkg"); 6327 } 6328 6329 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6330 if (targetUid < 0) { 6331 return; 6332 } 6333 6334 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6335 } 6336 6337 static class NeededUriGrants extends ArrayList<Uri> { 6338 final String targetPkg; 6339 final int targetUid; 6340 final int flags; 6341 6342 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6343 this.targetPkg = targetPkg; 6344 this.targetUid = targetUid; 6345 this.flags = flags; 6346 } 6347 } 6348 6349 /** 6350 * Like checkGrantUriPermissionLocked, but takes an Intent. 6351 */ 6352 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6353 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6354 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6355 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6356 + " clip=" + (intent != null ? intent.getClipData() : null) 6357 + " from " + intent + "; flags=0x" 6358 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6359 6360 if (targetPkg == null) { 6361 throw new NullPointerException("targetPkg"); 6362 } 6363 6364 if (intent == null) { 6365 return null; 6366 } 6367 Uri data = intent.getData(); 6368 ClipData clip = intent.getClipData(); 6369 if (data == null && clip == null) { 6370 return null; 6371 } 6372 6373 if (data != null) { 6374 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6375 mode, needed != null ? needed.targetUid : -1); 6376 if (targetUid > 0) { 6377 if (needed == null) { 6378 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6379 } 6380 needed.add(data); 6381 } 6382 } 6383 if (clip != null) { 6384 for (int i=0; i<clip.getItemCount(); i++) { 6385 Uri uri = clip.getItemAt(i).getUri(); 6386 if (uri != null) { 6387 int targetUid = -1; 6388 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6389 mode, needed != null ? needed.targetUid : -1); 6390 if (targetUid > 0) { 6391 if (needed == null) { 6392 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6393 } 6394 needed.add(uri); 6395 } 6396 } else { 6397 Intent clipIntent = clip.getItemAt(i).getIntent(); 6398 if (clipIntent != null) { 6399 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6400 callingUid, targetPkg, clipIntent, mode, needed); 6401 if (newNeeded != null) { 6402 needed = newNeeded; 6403 } 6404 } 6405 } 6406 } 6407 } 6408 6409 return needed; 6410 } 6411 6412 /** 6413 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6414 */ 6415 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6416 UriPermissionOwner owner) { 6417 if (needed != null) { 6418 for (int i=0; i<needed.size(); i++) { 6419 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6420 needed.get(i), needed.flags, owner); 6421 } 6422 } 6423 } 6424 6425 void grantUriPermissionFromIntentLocked(int callingUid, 6426 String targetPkg, Intent intent, UriPermissionOwner owner) { 6427 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6428 intent, intent != null ? intent.getFlags() : 0, null); 6429 if (needed == null) { 6430 return; 6431 } 6432 6433 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6434 } 6435 6436 @Override 6437 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6438 Uri uri, final int modeFlags) { 6439 enforceNotIsolatedCaller("grantUriPermission"); 6440 synchronized(this) { 6441 final ProcessRecord r = getRecordForAppLocked(caller); 6442 if (r == null) { 6443 throw new SecurityException("Unable to find app for caller " 6444 + caller 6445 + " when granting permission to uri " + uri); 6446 } 6447 if (targetPkg == null) { 6448 throw new IllegalArgumentException("null target"); 6449 } 6450 if (uri == null) { 6451 throw new IllegalArgumentException("null uri"); 6452 } 6453 6454 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6455 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6456 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6457 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6458 6459 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null); 6460 } 6461 } 6462 6463 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6464 if (perm.modeFlags == 0) { 6465 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6466 perm.targetUid); 6467 if (perms != null) { 6468 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6469 "Removing " + perm.targetUid + " permission to " + perm.uri); 6470 6471 perms.remove(perm.uri); 6472 if (perms.isEmpty()) { 6473 mGrantedUriPermissions.remove(perm.targetUid); 6474 } 6475 } 6476 } 6477 } 6478 6479 private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) { 6480 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6481 6482 final IPackageManager pm = AppGlobals.getPackageManager(); 6483 final String authority = uri.getAuthority(); 6484 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6485 if (pi == null) { 6486 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6487 return; 6488 } 6489 6490 // Does the caller have this permission on the URI? 6491 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6492 // Right now, if you are not the original owner of the permission, 6493 // you are not allowed to revoke it. 6494 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6495 throw new SecurityException("Uid " + callingUid 6496 + " does not have permission to uri " + uri); 6497 //} 6498 } 6499 6500 boolean persistChanged = false; 6501 6502 // Go through all of the permissions and remove any that match. 6503 int N = mGrantedUriPermissions.size(); 6504 for (int i = 0; i < N; i++) { 6505 final int targetUid = mGrantedUriPermissions.keyAt(i); 6506 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6507 6508 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6509 final UriPermission perm = it.next(); 6510 if (perm.uri.uri.isPathPrefixMatch(uri)) { 6511 if (DEBUG_URI_PERMISSION) 6512 Slog.v(TAG, 6513 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6514 persistChanged |= perm.revokeModes( 6515 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6516 if (perm.modeFlags == 0) { 6517 it.remove(); 6518 } 6519 } 6520 } 6521 6522 if (perms.isEmpty()) { 6523 mGrantedUriPermissions.remove(targetUid); 6524 N--; 6525 i--; 6526 } 6527 } 6528 6529 if (persistChanged) { 6530 schedulePersistUriGrants(); 6531 } 6532 } 6533 6534 @Override 6535 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6536 final int modeFlags) { 6537 enforceNotIsolatedCaller("revokeUriPermission"); 6538 synchronized(this) { 6539 final ProcessRecord r = getRecordForAppLocked(caller); 6540 if (r == null) { 6541 throw new SecurityException("Unable to find app for caller " 6542 + caller 6543 + " when revoking permission to uri " + uri); 6544 } 6545 if (uri == null) { 6546 Slog.w(TAG, "revokeUriPermission: null uri"); 6547 return; 6548 } 6549 6550 if (!Intent.isAccessUriMode(modeFlags)) { 6551 return; 6552 } 6553 6554 final IPackageManager pm = AppGlobals.getPackageManager(); 6555 final String authority = uri.getAuthority(); 6556 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6557 if (pi == null) { 6558 Slog.w(TAG, "No content provider found for permission revoke: " 6559 + uri.toSafeString()); 6560 return; 6561 } 6562 6563 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6564 } 6565 } 6566 6567 /** 6568 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6569 * given package. 6570 * 6571 * @param packageName Package name to match, or {@code null} to apply to all 6572 * packages. 6573 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6574 * to all users. 6575 * @param persistable If persistable grants should be removed. 6576 */ 6577 private void removeUriPermissionsForPackageLocked( 6578 String packageName, int userHandle, boolean persistable) { 6579 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6580 throw new IllegalArgumentException("Must narrow by either package or user"); 6581 } 6582 6583 boolean persistChanged = false; 6584 6585 int N = mGrantedUriPermissions.size(); 6586 for (int i = 0; i < N; i++) { 6587 final int targetUid = mGrantedUriPermissions.keyAt(i); 6588 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6589 6590 // Only inspect grants matching user 6591 if (userHandle == UserHandle.USER_ALL 6592 || userHandle == UserHandle.getUserId(targetUid)) { 6593 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6594 final UriPermission perm = it.next(); 6595 6596 // Only inspect grants matching package 6597 if (packageName == null || perm.sourcePkg.equals(packageName) 6598 || perm.targetPkg.equals(packageName)) { 6599 persistChanged |= perm.revokeModes( 6600 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6601 6602 // Only remove when no modes remain; any persisted grants 6603 // will keep this alive. 6604 if (perm.modeFlags == 0) { 6605 it.remove(); 6606 } 6607 } 6608 } 6609 6610 if (perms.isEmpty()) { 6611 mGrantedUriPermissions.remove(targetUid); 6612 N--; 6613 i--; 6614 } 6615 } 6616 } 6617 6618 if (persistChanged) { 6619 schedulePersistUriGrants(); 6620 } 6621 } 6622 6623 @Override 6624 public IBinder newUriPermissionOwner(String name) { 6625 enforceNotIsolatedCaller("newUriPermissionOwner"); 6626 synchronized(this) { 6627 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6628 return owner.getExternalTokenLocked(); 6629 } 6630 } 6631 6632 @Override 6633 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6634 Uri uri, final int modeFlags) { 6635 synchronized(this) { 6636 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6637 if (owner == null) { 6638 throw new IllegalArgumentException("Unknown owner: " + token); 6639 } 6640 if (fromUid != Binder.getCallingUid()) { 6641 if (Binder.getCallingUid() != Process.myUid()) { 6642 // Only system code can grant URI permissions on behalf 6643 // of other users. 6644 throw new SecurityException("nice try"); 6645 } 6646 } 6647 if (targetPkg == null) { 6648 throw new IllegalArgumentException("null target"); 6649 } 6650 if (uri == null) { 6651 throw new IllegalArgumentException("null uri"); 6652 } 6653 6654 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6655 } 6656 } 6657 6658 @Override 6659 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6660 synchronized(this) { 6661 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6662 if (owner == null) { 6663 throw new IllegalArgumentException("Unknown owner: " + token); 6664 } 6665 6666 if (uri == null) { 6667 owner.removeUriPermissionsLocked(mode); 6668 } else { 6669 owner.removeUriPermissionLocked(uri, mode); 6670 } 6671 } 6672 } 6673 6674 private void schedulePersistUriGrants() { 6675 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6676 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6677 10 * DateUtils.SECOND_IN_MILLIS); 6678 } 6679 } 6680 6681 private void writeGrantedUriPermissions() { 6682 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6683 6684 // Snapshot permissions so we can persist without lock 6685 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6686 synchronized (this) { 6687 final int size = mGrantedUriPermissions.size(); 6688 for (int i = 0; i < size; i++) { 6689 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6690 for (UriPermission perm : perms.values()) { 6691 if (perm.persistedModeFlags != 0) { 6692 persist.add(perm.snapshot()); 6693 } 6694 } 6695 } 6696 } 6697 6698 FileOutputStream fos = null; 6699 try { 6700 fos = mGrantFile.startWrite(); 6701 6702 XmlSerializer out = new FastXmlSerializer(); 6703 out.setOutput(fos, "utf-8"); 6704 out.startDocument(null, true); 6705 out.startTag(null, TAG_URI_GRANTS); 6706 for (UriPermission.Snapshot perm : persist) { 6707 out.startTag(null, TAG_URI_GRANT); 6708 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6709 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6710 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6711 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6712 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6713 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6714 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6715 out.endTag(null, TAG_URI_GRANT); 6716 } 6717 out.endTag(null, TAG_URI_GRANTS); 6718 out.endDocument(); 6719 6720 mGrantFile.finishWrite(fos); 6721 } catch (IOException e) { 6722 if (fos != null) { 6723 mGrantFile.failWrite(fos); 6724 } 6725 } 6726 } 6727 6728 private void readGrantedUriPermissionsLocked() { 6729 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6730 6731 final long now = System.currentTimeMillis(); 6732 6733 FileInputStream fis = null; 6734 try { 6735 fis = mGrantFile.openRead(); 6736 final XmlPullParser in = Xml.newPullParser(); 6737 in.setInput(fis, null); 6738 6739 int type; 6740 while ((type = in.next()) != END_DOCUMENT) { 6741 final String tag = in.getName(); 6742 if (type == START_TAG) { 6743 if (TAG_URI_GRANT.equals(tag)) { 6744 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6745 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6746 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6747 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6748 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6749 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6750 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6751 6752 // Sanity check that provider still belongs to source package 6753 final ProviderInfo pi = getProviderInfoLocked( 6754 uri.getAuthority(), userHandle); 6755 if (pi != null && sourcePkg.equals(pi.packageName)) { 6756 int targetUid = -1; 6757 try { 6758 targetUid = AppGlobals.getPackageManager() 6759 .getPackageUid(targetPkg, userHandle); 6760 } catch (RemoteException e) { 6761 } 6762 if (targetUid != -1) { 6763 final UriPermission perm = findOrCreateUriPermissionLocked( 6764 sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix)); 6765 perm.initPersistedModes(modeFlags, createdTime); 6766 } 6767 } else { 6768 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6769 + " but instead found " + pi); 6770 } 6771 } 6772 } 6773 } 6774 } catch (FileNotFoundException e) { 6775 // Missing grants is okay 6776 } catch (IOException e) { 6777 Log.wtf(TAG, "Failed reading Uri grants", e); 6778 } catch (XmlPullParserException e) { 6779 Log.wtf(TAG, "Failed reading Uri grants", e); 6780 } finally { 6781 IoUtils.closeQuietly(fis); 6782 } 6783 } 6784 6785 @Override 6786 public void takePersistableUriPermission(Uri uri, final int modeFlags) { 6787 enforceNotIsolatedCaller("takePersistableUriPermission"); 6788 6789 Preconditions.checkFlagsArgument(modeFlags, 6790 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6791 6792 synchronized (this) { 6793 final int callingUid = Binder.getCallingUid(); 6794 boolean persistChanged = false; 6795 6796 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6797 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6798 6799 final boolean exactValid = (exactPerm != null) 6800 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6801 final boolean prefixValid = (prefixPerm != null) 6802 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6803 6804 if (!(exactValid || prefixValid)) { 6805 throw new SecurityException("No persistable permission grants found for UID " 6806 + callingUid + " and Uri " + uri.toSafeString()); 6807 } 6808 6809 if (exactValid) { 6810 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6811 } 6812 if (prefixValid) { 6813 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6814 } 6815 6816 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6817 6818 if (persistChanged) { 6819 schedulePersistUriGrants(); 6820 } 6821 } 6822 } 6823 6824 @Override 6825 public void releasePersistableUriPermission(Uri uri, final int modeFlags) { 6826 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6827 6828 Preconditions.checkFlagsArgument(modeFlags, 6829 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6830 6831 synchronized (this) { 6832 final int callingUid = Binder.getCallingUid(); 6833 boolean persistChanged = false; 6834 6835 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6836 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6837 if (exactPerm == null && prefixPerm == null) { 6838 throw new SecurityException("No permission grants found for UID " + callingUid 6839 + " and Uri " + uri.toSafeString()); 6840 } 6841 6842 if (exactPerm != null) { 6843 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6844 removeUriPermissionIfNeededLocked(exactPerm); 6845 } 6846 if (prefixPerm != null) { 6847 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6848 removeUriPermissionIfNeededLocked(prefixPerm); 6849 } 6850 6851 if (persistChanged) { 6852 schedulePersistUriGrants(); 6853 } 6854 } 6855 } 6856 6857 /** 6858 * Prune any older {@link UriPermission} for the given UID until outstanding 6859 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6860 * 6861 * @return if any mutations occured that require persisting. 6862 */ 6863 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6864 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6865 if (perms == null) return false; 6866 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6867 6868 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6869 for (UriPermission perm : perms.values()) { 6870 if (perm.persistedModeFlags != 0) { 6871 persisted.add(perm); 6872 } 6873 } 6874 6875 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6876 if (trimCount <= 0) return false; 6877 6878 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6879 for (int i = 0; i < trimCount; i++) { 6880 final UriPermission perm = persisted.get(i); 6881 6882 if (DEBUG_URI_PERMISSION) { 6883 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6884 } 6885 6886 perm.releasePersistableModes(~0); 6887 removeUriPermissionIfNeededLocked(perm); 6888 } 6889 6890 return true; 6891 } 6892 6893 @Override 6894 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6895 String packageName, boolean incoming) { 6896 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6897 Preconditions.checkNotNull(packageName, "packageName"); 6898 6899 final int callingUid = Binder.getCallingUid(); 6900 final IPackageManager pm = AppGlobals.getPackageManager(); 6901 try { 6902 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6903 if (packageUid != callingUid) { 6904 throw new SecurityException( 6905 "Package " + packageName + " does not belong to calling UID " + callingUid); 6906 } 6907 } catch (RemoteException e) { 6908 throw new SecurityException("Failed to verify package name ownership"); 6909 } 6910 6911 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6912 synchronized (this) { 6913 if (incoming) { 6914 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6915 callingUid); 6916 if (perms == null) { 6917 Slog.w(TAG, "No permission grants found for " + packageName); 6918 } else { 6919 for (UriPermission perm : perms.values()) { 6920 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6921 result.add(perm.buildPersistedPublicApiObject()); 6922 } 6923 } 6924 } 6925 } else { 6926 final int size = mGrantedUriPermissions.size(); 6927 for (int i = 0; i < size; i++) { 6928 final ArrayMap<GrantUri, UriPermission> perms = 6929 mGrantedUriPermissions.valueAt(i); 6930 for (UriPermission perm : perms.values()) { 6931 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6932 result.add(perm.buildPersistedPublicApiObject()); 6933 } 6934 } 6935 } 6936 } 6937 } 6938 return new ParceledListSlice<android.content.UriPermission>(result); 6939 } 6940 6941 @Override 6942 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6943 synchronized (this) { 6944 ProcessRecord app = 6945 who != null ? getRecordForAppLocked(who) : null; 6946 if (app == null) return; 6947 6948 Message msg = Message.obtain(); 6949 msg.what = WAIT_FOR_DEBUGGER_MSG; 6950 msg.obj = app; 6951 msg.arg1 = waiting ? 1 : 0; 6952 mHandler.sendMessage(msg); 6953 } 6954 } 6955 6956 @Override 6957 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6958 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6959 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6960 outInfo.availMem = Process.getFreeMemory(); 6961 outInfo.totalMem = Process.getTotalMemory(); 6962 outInfo.threshold = homeAppMem; 6963 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6964 outInfo.hiddenAppThreshold = cachedAppMem; 6965 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6966 ProcessList.SERVICE_ADJ); 6967 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6968 ProcessList.VISIBLE_APP_ADJ); 6969 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6970 ProcessList.FOREGROUND_APP_ADJ); 6971 } 6972 6973 // ========================================================= 6974 // TASK MANAGEMENT 6975 // ========================================================= 6976 6977 @Override 6978 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 6979 final int callingUid = Binder.getCallingUid(); 6980 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6981 6982 synchronized(this) { 6983 if (localLOGV) Slog.v( 6984 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 6985 6986 final boolean allowed = checkCallingPermission( 6987 android.Manifest.permission.GET_TASKS) 6988 == PackageManager.PERMISSION_GRANTED; 6989 if (!allowed) { 6990 Slog.w(TAG, "getTasks: caller " + callingUid 6991 + " does not hold GET_TASKS; limiting output"); 6992 } 6993 6994 // TODO: Improve with MRU list from all ActivityStacks. 6995 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 6996 } 6997 6998 return list; 6999 } 7000 7001 TaskRecord getMostRecentTask() { 7002 return mRecentTasks.get(0); 7003 } 7004 7005 @Override 7006 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7007 int flags, int userId) { 7008 final int callingUid = Binder.getCallingUid(); 7009 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7010 false, true, "getRecentTasks", null); 7011 7012 synchronized (this) { 7013 final boolean allowed = checkCallingPermission( 7014 android.Manifest.permission.GET_TASKS) 7015 == PackageManager.PERMISSION_GRANTED; 7016 if (!allowed) { 7017 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7018 + " does not hold GET_TASKS; limiting output"); 7019 } 7020 final boolean detailed = checkCallingPermission( 7021 android.Manifest.permission.GET_DETAILED_TASKS) 7022 == PackageManager.PERMISSION_GRANTED; 7023 7024 IPackageManager pm = AppGlobals.getPackageManager(); 7025 7026 final int N = mRecentTasks.size(); 7027 ArrayList<ActivityManager.RecentTaskInfo> res 7028 = new ArrayList<ActivityManager.RecentTaskInfo>( 7029 maxNum < N ? maxNum : N); 7030 7031 final Set<Integer> includedUsers; 7032 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7033 includedUsers = getProfileIdsLocked(userId); 7034 } else { 7035 includedUsers = new HashSet<Integer>(); 7036 } 7037 includedUsers.add(Integer.valueOf(userId)); 7038 for (int i=0; i<N && maxNum > 0; i++) { 7039 TaskRecord tr = mRecentTasks.get(i); 7040 // Only add calling user or related users recent tasks 7041 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7042 7043 // Return the entry if desired by the caller. We always return 7044 // the first entry, because callers always expect this to be the 7045 // foreground app. We may filter others if the caller has 7046 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7047 // we should exclude the entry. 7048 7049 if (i == 0 7050 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7051 || (tr.intent == null) 7052 || ((tr.intent.getFlags() 7053 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7054 if (!allowed) { 7055 // If the caller doesn't have the GET_TASKS permission, then only 7056 // allow them to see a small subset of tasks -- their own and home. 7057 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7058 continue; 7059 } 7060 } 7061 ActivityManager.RecentTaskInfo rti 7062 = new ActivityManager.RecentTaskInfo(); 7063 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 7064 rti.persistentId = tr.taskId; 7065 rti.baseIntent = new Intent( 7066 tr.intent != null ? tr.intent : tr.affinityIntent); 7067 if (!detailed) { 7068 rti.baseIntent.replaceExtras((Bundle)null); 7069 } 7070 rti.origActivity = tr.origActivity; 7071 rti.description = tr.lastDescription; 7072 rti.stackId = tr.stack.mStackId; 7073 rti.userId = tr.userId; 7074 7075 // Traverse upwards looking for any break between main task activities and 7076 // utility activities. 7077 final ArrayList<ActivityRecord> activities = tr.mActivities; 7078 int activityNdx; 7079 final int numActivities = activities.size(); 7080 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities; 7081 ++activityNdx) { 7082 final ActivityRecord r = activities.get(activityNdx); 7083 if (r.intent != null && 7084 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) 7085 != 0) { 7086 break; 7087 } 7088 } 7089 if (activityNdx > 0) { 7090 // Traverse downwards starting below break looking for set label, icon. 7091 // Note that if there are activities in the task but none of them set the 7092 // recent activity values, then we do not fall back to the last set 7093 // values in the TaskRecord. 7094 rti.activityValues = new ActivityManager.RecentsActivityValues(); 7095 for (--activityNdx; activityNdx >= 0; --activityNdx) { 7096 final ActivityRecord r = activities.get(activityNdx); 7097 if (r.activityValues != null) { 7098 if (rti.activityValues.label == null) { 7099 rti.activityValues.label = r.activityValues.label; 7100 tr.lastActivityValues.label = r.activityValues.label; 7101 } 7102 if (rti.activityValues.icon == null) { 7103 rti.activityValues.icon = r.activityValues.icon; 7104 tr.lastActivityValues.icon = r.activityValues.icon; 7105 } 7106 if (rti.activityValues.colorPrimary == 0) { 7107 rti.activityValues.colorPrimary = r.activityValues.colorPrimary; 7108 tr.lastActivityValues.colorPrimary = r.activityValues.colorPrimary; 7109 } 7110 } 7111 } 7112 } else { 7113 // If there are no activity records in this task, then we use the last 7114 // resolved values 7115 rti.activityValues = 7116 new ActivityManager.RecentsActivityValues(tr.lastActivityValues); 7117 } 7118 7119 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7120 // Check whether this activity is currently available. 7121 try { 7122 if (rti.origActivity != null) { 7123 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7124 == null) { 7125 continue; 7126 } 7127 } else if (rti.baseIntent != null) { 7128 if (pm.queryIntentActivities(rti.baseIntent, 7129 null, 0, userId) == null) { 7130 continue; 7131 } 7132 } 7133 } catch (RemoteException e) { 7134 // Will never happen. 7135 } 7136 } 7137 7138 res.add(rti); 7139 maxNum--; 7140 } 7141 } 7142 return res; 7143 } 7144 } 7145 7146 private TaskRecord recentTaskForIdLocked(int id) { 7147 final int N = mRecentTasks.size(); 7148 for (int i=0; i<N; i++) { 7149 TaskRecord tr = mRecentTasks.get(i); 7150 if (tr.taskId == id) { 7151 return tr; 7152 } 7153 } 7154 return null; 7155 } 7156 7157 @Override 7158 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7159 synchronized (this) { 7160 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7161 "getTaskThumbnails()"); 7162 TaskRecord tr = recentTaskForIdLocked(id); 7163 if (tr != null) { 7164 return tr.getTaskThumbnailsLocked(); 7165 } 7166 } 7167 return null; 7168 } 7169 7170 @Override 7171 public Bitmap getTaskTopThumbnail(int id) { 7172 synchronized (this) { 7173 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7174 "getTaskTopThumbnail()"); 7175 TaskRecord tr = recentTaskForIdLocked(id); 7176 if (tr != null) { 7177 return tr.getTaskTopThumbnailLocked(); 7178 } 7179 } 7180 return null; 7181 } 7182 7183 @Override 7184 public void setRecentsActivityValues(IBinder token, ActivityManager.RecentsActivityValues rav) { 7185 synchronized (this) { 7186 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7187 if (r != null) { 7188 r.activityValues = rav; 7189 } 7190 } 7191 } 7192 7193 @Override 7194 public boolean removeSubTask(int taskId, int subTaskIndex) { 7195 synchronized (this) { 7196 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7197 "removeSubTask()"); 7198 long ident = Binder.clearCallingIdentity(); 7199 try { 7200 TaskRecord tr = recentTaskForIdLocked(taskId); 7201 if (tr != null) { 7202 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7203 } 7204 return false; 7205 } finally { 7206 Binder.restoreCallingIdentity(ident); 7207 } 7208 } 7209 } 7210 7211 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7212 if (!pr.killedByAm) { 7213 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7214 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7215 pr.processName, pr.setAdj, reason); 7216 pr.killedByAm = true; 7217 Process.killProcessQuiet(pr.pid); 7218 } 7219 } 7220 7221 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7222 tr.disposeThumbnail(); 7223 mRecentTasks.remove(tr); 7224 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7225 Intent baseIntent = new Intent( 7226 tr.intent != null ? tr.intent : tr.affinityIntent); 7227 ComponentName component = baseIntent.getComponent(); 7228 if (component == null) { 7229 Slog.w(TAG, "Now component for base intent of task: " + tr); 7230 return; 7231 } 7232 7233 // Find any running services associated with this app. 7234 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7235 7236 if (killProcesses) { 7237 // Find any running processes associated with this app. 7238 final String pkg = component.getPackageName(); 7239 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7240 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7241 for (int i=0; i<pmap.size(); i++) { 7242 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7243 for (int j=0; j<uids.size(); j++) { 7244 ProcessRecord proc = uids.valueAt(j); 7245 if (proc.userId != tr.userId) { 7246 continue; 7247 } 7248 if (!proc.pkgList.containsKey(pkg)) { 7249 continue; 7250 } 7251 procs.add(proc); 7252 } 7253 } 7254 7255 // Kill the running processes. 7256 for (int i=0; i<procs.size(); i++) { 7257 ProcessRecord pr = procs.get(i); 7258 if (pr == mHomeProcess) { 7259 // Don't kill the home process along with tasks from the same package. 7260 continue; 7261 } 7262 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7263 killUnneededProcessLocked(pr, "remove task"); 7264 } else { 7265 pr.waitingToKill = "remove task"; 7266 } 7267 } 7268 } 7269 } 7270 7271 /** 7272 * Removes the task with the specified task id. 7273 * 7274 * @param taskId Identifier of the task to be removed. 7275 * @param flags Additional operational flags. May be 0 or 7276 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7277 * @return Returns true if the given task was found and removed. 7278 */ 7279 private boolean removeTaskByIdLocked(int taskId, int flags) { 7280 TaskRecord tr = recentTaskForIdLocked(taskId); 7281 if (tr != null) { 7282 tr.removeTaskActivitiesLocked(-1, false); 7283 cleanUpRemovedTaskLocked(tr, flags); 7284 return true; 7285 } 7286 return false; 7287 } 7288 7289 @Override 7290 public boolean removeTask(int taskId, int flags) { 7291 synchronized (this) { 7292 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7293 "removeTask()"); 7294 long ident = Binder.clearCallingIdentity(); 7295 try { 7296 return removeTaskByIdLocked(taskId, flags); 7297 } finally { 7298 Binder.restoreCallingIdentity(ident); 7299 } 7300 } 7301 } 7302 7303 /** 7304 * TODO: Add mController hook 7305 */ 7306 @Override 7307 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7308 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7309 "moveTaskToFront()"); 7310 7311 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7312 synchronized(this) { 7313 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7314 Binder.getCallingUid(), "Task to front")) { 7315 ActivityOptions.abort(options); 7316 return; 7317 } 7318 final long origId = Binder.clearCallingIdentity(); 7319 try { 7320 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7321 if (task == null) { 7322 return; 7323 } 7324 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7325 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7326 return; 7327 } 7328 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7329 } finally { 7330 Binder.restoreCallingIdentity(origId); 7331 } 7332 ActivityOptions.abort(options); 7333 } 7334 } 7335 7336 @Override 7337 public void moveTaskToBack(int taskId) { 7338 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7339 "moveTaskToBack()"); 7340 7341 synchronized(this) { 7342 TaskRecord tr = recentTaskForIdLocked(taskId); 7343 if (tr != null) { 7344 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7345 ActivityStack stack = tr.stack; 7346 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7347 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7348 Binder.getCallingUid(), "Task to back")) { 7349 return; 7350 } 7351 } 7352 final long origId = Binder.clearCallingIdentity(); 7353 try { 7354 stack.moveTaskToBackLocked(taskId, null); 7355 } finally { 7356 Binder.restoreCallingIdentity(origId); 7357 } 7358 } 7359 } 7360 } 7361 7362 /** 7363 * Moves an activity, and all of the other activities within the same task, to the bottom 7364 * of the history stack. The activity's order within the task is unchanged. 7365 * 7366 * @param token A reference to the activity we wish to move 7367 * @param nonRoot If false then this only works if the activity is the root 7368 * of a task; if true it will work for any activity in a task. 7369 * @return Returns true if the move completed, false if not. 7370 */ 7371 @Override 7372 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7373 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7374 synchronized(this) { 7375 final long origId = Binder.clearCallingIdentity(); 7376 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7377 if (taskId >= 0) { 7378 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7379 } 7380 Binder.restoreCallingIdentity(origId); 7381 } 7382 return false; 7383 } 7384 7385 @Override 7386 public void moveTaskBackwards(int task) { 7387 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7388 "moveTaskBackwards()"); 7389 7390 synchronized(this) { 7391 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7392 Binder.getCallingUid(), "Task backwards")) { 7393 return; 7394 } 7395 final long origId = Binder.clearCallingIdentity(); 7396 moveTaskBackwardsLocked(task); 7397 Binder.restoreCallingIdentity(origId); 7398 } 7399 } 7400 7401 private final void moveTaskBackwardsLocked(int task) { 7402 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7403 } 7404 7405 @Override 7406 public IBinder getHomeActivityToken() throws RemoteException { 7407 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7408 "getHomeActivityToken()"); 7409 synchronized (this) { 7410 return mStackSupervisor.getHomeActivityToken(); 7411 } 7412 } 7413 7414 @Override 7415 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7416 IActivityContainerCallback callback) throws RemoteException { 7417 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7418 "createActivityContainer()"); 7419 synchronized (this) { 7420 if (parentActivityToken == null) { 7421 throw new IllegalArgumentException("parent token must not be null"); 7422 } 7423 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7424 if (r == null) { 7425 return null; 7426 } 7427 if (callback == null) { 7428 throw new IllegalArgumentException("callback must not be null"); 7429 } 7430 return mStackSupervisor.createActivityContainer(r, callback); 7431 } 7432 } 7433 7434 @Override 7435 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7436 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7437 "deleteActivityContainer()"); 7438 synchronized (this) { 7439 mStackSupervisor.deleteActivityContainer(container); 7440 } 7441 } 7442 7443 @Override 7444 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7445 throws RemoteException { 7446 synchronized (this) { 7447 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7448 if (stack != null) { 7449 return stack.mActivityContainer; 7450 } 7451 return null; 7452 } 7453 } 7454 7455 @Override 7456 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7457 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7458 "moveTaskToStack()"); 7459 if (stackId == HOME_STACK_ID) { 7460 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7461 new RuntimeException("here").fillInStackTrace()); 7462 } 7463 synchronized (this) { 7464 long ident = Binder.clearCallingIdentity(); 7465 try { 7466 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7467 + stackId + " toTop=" + toTop); 7468 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7469 } finally { 7470 Binder.restoreCallingIdentity(ident); 7471 } 7472 } 7473 } 7474 7475 @Override 7476 public void resizeStack(int stackBoxId, Rect bounds) { 7477 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7478 "resizeStackBox()"); 7479 long ident = Binder.clearCallingIdentity(); 7480 try { 7481 mWindowManager.resizeStack(stackBoxId, bounds); 7482 } finally { 7483 Binder.restoreCallingIdentity(ident); 7484 } 7485 } 7486 7487 @Override 7488 public List<StackInfo> getAllStackInfos() { 7489 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7490 "getAllStackInfos()"); 7491 long ident = Binder.clearCallingIdentity(); 7492 try { 7493 synchronized (this) { 7494 return mStackSupervisor.getAllStackInfosLocked(); 7495 } 7496 } finally { 7497 Binder.restoreCallingIdentity(ident); 7498 } 7499 } 7500 7501 @Override 7502 public StackInfo getStackInfo(int stackId) { 7503 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7504 "getStackInfo()"); 7505 long ident = Binder.clearCallingIdentity(); 7506 try { 7507 synchronized (this) { 7508 return mStackSupervisor.getStackInfoLocked(stackId); 7509 } 7510 } finally { 7511 Binder.restoreCallingIdentity(ident); 7512 } 7513 } 7514 7515 @Override 7516 public boolean isInHomeStack(int taskId) { 7517 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7518 "getStackInfo()"); 7519 long ident = Binder.clearCallingIdentity(); 7520 try { 7521 synchronized (this) { 7522 TaskRecord tr = recentTaskForIdLocked(taskId); 7523 if (tr != null) { 7524 return tr.stack.isHomeStack(); 7525 } 7526 } 7527 } finally { 7528 Binder.restoreCallingIdentity(ident); 7529 } 7530 return false; 7531 } 7532 7533 @Override 7534 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7535 synchronized(this) { 7536 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7537 } 7538 } 7539 7540 private boolean isLockTaskAuthorized(ComponentName name) { 7541// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7542// "startLockTaskMode()"); 7543// DevicePolicyManager dpm = (DevicePolicyManager) 7544// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7545// return dpm != null && dpm.isLockTaskPermitted(name); 7546 return true; 7547 } 7548 7549 private void startLockTaskMode(TaskRecord task) { 7550 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7551 return; 7552 } 7553 long ident = Binder.clearCallingIdentity(); 7554 try { 7555 synchronized (this) { 7556 // Since we lost lock on task, make sure it is still there. 7557 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7558 if (task != null) { 7559 mStackSupervisor.setLockTaskModeLocked(task); 7560 } 7561 } 7562 } finally { 7563 Binder.restoreCallingIdentity(ident); 7564 } 7565 } 7566 7567 @Override 7568 public void startLockTaskMode(int taskId) { 7569 long ident = Binder.clearCallingIdentity(); 7570 try { 7571 final TaskRecord task; 7572 synchronized (this) { 7573 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7574 } 7575 if (task != null) { 7576 startLockTaskMode(task); 7577 } 7578 } finally { 7579 Binder.restoreCallingIdentity(ident); 7580 } 7581 } 7582 7583 @Override 7584 public void startLockTaskMode(IBinder token) { 7585 long ident = Binder.clearCallingIdentity(); 7586 try { 7587 final TaskRecord task; 7588 synchronized (this) { 7589 final ActivityRecord r = ActivityRecord.forToken(token); 7590 if (r == null) { 7591 return; 7592 } 7593 task = r.task; 7594 } 7595 if (task != null) { 7596 startLockTaskMode(task); 7597 } 7598 } finally { 7599 Binder.restoreCallingIdentity(ident); 7600 } 7601 } 7602 7603 @Override 7604 public void stopLockTaskMode() { 7605// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7606// "stopLockTaskMode()"); 7607 synchronized (this) { 7608 mStackSupervisor.setLockTaskModeLocked(null); 7609 } 7610 } 7611 7612 @Override 7613 public boolean isInLockTaskMode() { 7614 synchronized (this) { 7615 return mStackSupervisor.isInLockTaskMode(); 7616 } 7617 } 7618 7619 // ========================================================= 7620 // CONTENT PROVIDERS 7621 // ========================================================= 7622 7623 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7624 List<ProviderInfo> providers = null; 7625 try { 7626 providers = AppGlobals.getPackageManager(). 7627 queryContentProviders(app.processName, app.uid, 7628 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7629 } catch (RemoteException ex) { 7630 } 7631 if (DEBUG_MU) 7632 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7633 int userId = app.userId; 7634 if (providers != null) { 7635 int N = providers.size(); 7636 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7637 for (int i=0; i<N; i++) { 7638 ProviderInfo cpi = 7639 (ProviderInfo)providers.get(i); 7640 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7641 cpi.name, cpi.flags); 7642 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7643 // This is a singleton provider, but a user besides the 7644 // default user is asking to initialize a process it runs 7645 // in... well, no, it doesn't actually run in this process, 7646 // it runs in the process of the default user. Get rid of it. 7647 providers.remove(i); 7648 N--; 7649 i--; 7650 continue; 7651 } 7652 7653 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7654 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7655 if (cpr == null) { 7656 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7657 mProviderMap.putProviderByClass(comp, cpr); 7658 } 7659 if (DEBUG_MU) 7660 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7661 app.pubProviders.put(cpi.name, cpr); 7662 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7663 // Don't add this if it is a platform component that is marked 7664 // to run in multiple processes, because this is actually 7665 // part of the framework so doesn't make sense to track as a 7666 // separate apk in the process. 7667 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7668 } 7669 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7670 } 7671 } 7672 return providers; 7673 } 7674 7675 /** 7676 * Check if {@link ProcessRecord} has a possible chance at accessing the 7677 * given {@link ProviderInfo}. Final permission checking is always done 7678 * in {@link ContentProvider}. 7679 */ 7680 private final String checkContentProviderPermissionLocked( 7681 ProviderInfo cpi, ProcessRecord r) { 7682 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7683 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7684 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7685 cpi.applicationInfo.uid, cpi.exported) 7686 == PackageManager.PERMISSION_GRANTED) { 7687 return null; 7688 } 7689 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7690 cpi.applicationInfo.uid, cpi.exported) 7691 == PackageManager.PERMISSION_GRANTED) { 7692 return null; 7693 } 7694 7695 PathPermission[] pps = cpi.pathPermissions; 7696 if (pps != null) { 7697 int i = pps.length; 7698 while (i > 0) { 7699 i--; 7700 PathPermission pp = pps[i]; 7701 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7702 cpi.applicationInfo.uid, cpi.exported) 7703 == PackageManager.PERMISSION_GRANTED) { 7704 return null; 7705 } 7706 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7707 cpi.applicationInfo.uid, cpi.exported) 7708 == PackageManager.PERMISSION_GRANTED) { 7709 return null; 7710 } 7711 } 7712 } 7713 7714 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7715 if (perms != null) { 7716 for (GrantUri uri : perms.keySet()) { 7717 if (uri.uri.getAuthority().equals(cpi.authority)) { 7718 return null; 7719 } 7720 } 7721 } 7722 7723 String msg; 7724 if (!cpi.exported) { 7725 msg = "Permission Denial: opening provider " + cpi.name 7726 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7727 + ", uid=" + callingUid + ") that is not exported from uid " 7728 + cpi.applicationInfo.uid; 7729 } else { 7730 msg = "Permission Denial: opening provider " + cpi.name 7731 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7732 + ", uid=" + callingUid + ") requires " 7733 + cpi.readPermission + " or " + cpi.writePermission; 7734 } 7735 Slog.w(TAG, msg); 7736 return msg; 7737 } 7738 7739 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7740 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7741 if (r != null) { 7742 for (int i=0; i<r.conProviders.size(); i++) { 7743 ContentProviderConnection conn = r.conProviders.get(i); 7744 if (conn.provider == cpr) { 7745 if (DEBUG_PROVIDER) Slog.v(TAG, 7746 "Adding provider requested by " 7747 + r.processName + " from process " 7748 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7749 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7750 if (stable) { 7751 conn.stableCount++; 7752 conn.numStableIncs++; 7753 } else { 7754 conn.unstableCount++; 7755 conn.numUnstableIncs++; 7756 } 7757 return conn; 7758 } 7759 } 7760 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7761 if (stable) { 7762 conn.stableCount = 1; 7763 conn.numStableIncs = 1; 7764 } else { 7765 conn.unstableCount = 1; 7766 conn.numUnstableIncs = 1; 7767 } 7768 cpr.connections.add(conn); 7769 r.conProviders.add(conn); 7770 return conn; 7771 } 7772 cpr.addExternalProcessHandleLocked(externalProcessToken); 7773 return null; 7774 } 7775 7776 boolean decProviderCountLocked(ContentProviderConnection conn, 7777 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7778 if (conn != null) { 7779 cpr = conn.provider; 7780 if (DEBUG_PROVIDER) Slog.v(TAG, 7781 "Removing provider requested by " 7782 + conn.client.processName + " from process " 7783 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7784 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7785 if (stable) { 7786 conn.stableCount--; 7787 } else { 7788 conn.unstableCount--; 7789 } 7790 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7791 cpr.connections.remove(conn); 7792 conn.client.conProviders.remove(conn); 7793 return true; 7794 } 7795 return false; 7796 } 7797 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7798 return false; 7799 } 7800 7801 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7802 String name, IBinder token, boolean stable, int userId) { 7803 ContentProviderRecord cpr; 7804 ContentProviderConnection conn = null; 7805 ProviderInfo cpi = null; 7806 7807 synchronized(this) { 7808 ProcessRecord r = null; 7809 if (caller != null) { 7810 r = getRecordForAppLocked(caller); 7811 if (r == null) { 7812 throw new SecurityException( 7813 "Unable to find app for caller " + caller 7814 + " (pid=" + Binder.getCallingPid() 7815 + ") when getting content provider " + name); 7816 } 7817 } 7818 7819 // First check if this content provider has been published... 7820 cpr = mProviderMap.getProviderByName(name, userId); 7821 boolean providerRunning = cpr != null; 7822 if (providerRunning) { 7823 cpi = cpr.info; 7824 String msg; 7825 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7826 throw new SecurityException(msg); 7827 } 7828 7829 if (r != null && cpr.canRunHere(r)) { 7830 // This provider has been published or is in the process 7831 // of being published... but it is also allowed to run 7832 // in the caller's process, so don't make a connection 7833 // and just let the caller instantiate its own instance. 7834 ContentProviderHolder holder = cpr.newHolder(null); 7835 // don't give caller the provider object, it needs 7836 // to make its own. 7837 holder.provider = null; 7838 return holder; 7839 } 7840 7841 final long origId = Binder.clearCallingIdentity(); 7842 7843 // In this case the provider instance already exists, so we can 7844 // return it right away. 7845 conn = incProviderCountLocked(r, cpr, token, stable); 7846 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7847 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7848 // If this is a perceptible app accessing the provider, 7849 // make sure to count it as being accessed and thus 7850 // back up on the LRU list. This is good because 7851 // content providers are often expensive to start. 7852 updateLruProcessLocked(cpr.proc, false, null); 7853 } 7854 } 7855 7856 if (cpr.proc != null) { 7857 if (false) { 7858 if (cpr.name.flattenToShortString().equals( 7859 "com.android.providers.calendar/.CalendarProvider2")) { 7860 Slog.v(TAG, "****************** KILLING " 7861 + cpr.name.flattenToShortString()); 7862 Process.killProcess(cpr.proc.pid); 7863 } 7864 } 7865 boolean success = updateOomAdjLocked(cpr.proc); 7866 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7867 // NOTE: there is still a race here where a signal could be 7868 // pending on the process even though we managed to update its 7869 // adj level. Not sure what to do about this, but at least 7870 // the race is now smaller. 7871 if (!success) { 7872 // Uh oh... it looks like the provider's process 7873 // has been killed on us. We need to wait for a new 7874 // process to be started, and make sure its death 7875 // doesn't kill our process. 7876 Slog.i(TAG, 7877 "Existing provider " + cpr.name.flattenToShortString() 7878 + " is crashing; detaching " + r); 7879 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7880 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7881 if (!lastRef) { 7882 // This wasn't the last ref our process had on 7883 // the provider... we have now been killed, bail. 7884 return null; 7885 } 7886 providerRunning = false; 7887 conn = null; 7888 } 7889 } 7890 7891 Binder.restoreCallingIdentity(origId); 7892 } 7893 7894 boolean singleton; 7895 if (!providerRunning) { 7896 try { 7897 cpi = AppGlobals.getPackageManager(). 7898 resolveContentProvider(name, 7899 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7900 } catch (RemoteException ex) { 7901 } 7902 if (cpi == null) { 7903 return null; 7904 } 7905 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7906 cpi.name, cpi.flags); 7907 if (singleton) { 7908 userId = 0; 7909 } 7910 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7911 7912 String msg; 7913 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7914 throw new SecurityException(msg); 7915 } 7916 7917 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7918 && !cpi.processName.equals("system")) { 7919 // If this content provider does not run in the system 7920 // process, and the system is not yet ready to run other 7921 // processes, then fail fast instead of hanging. 7922 throw new IllegalArgumentException( 7923 "Attempt to launch content provider before system ready"); 7924 } 7925 7926 // Make sure that the user who owns this provider is started. If not, 7927 // we don't want to allow it to run. 7928 if (mStartedUsers.get(userId) == null) { 7929 Slog.w(TAG, "Unable to launch app " 7930 + cpi.applicationInfo.packageName + "/" 7931 + cpi.applicationInfo.uid + " for provider " 7932 + name + ": user " + userId + " is stopped"); 7933 return null; 7934 } 7935 7936 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7937 cpr = mProviderMap.getProviderByClass(comp, userId); 7938 final boolean firstClass = cpr == null; 7939 if (firstClass) { 7940 try { 7941 ApplicationInfo ai = 7942 AppGlobals.getPackageManager(). 7943 getApplicationInfo( 7944 cpi.applicationInfo.packageName, 7945 STOCK_PM_FLAGS, userId); 7946 if (ai == null) { 7947 Slog.w(TAG, "No package info for content provider " 7948 + cpi.name); 7949 return null; 7950 } 7951 ai = getAppInfoForUser(ai, userId); 7952 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7953 } catch (RemoteException ex) { 7954 // pm is in same process, this will never happen. 7955 } 7956 } 7957 7958 if (r != null && cpr.canRunHere(r)) { 7959 // If this is a multiprocess provider, then just return its 7960 // info and allow the caller to instantiate it. Only do 7961 // this if the provider is the same user as the caller's 7962 // process, or can run as root (so can be in any process). 7963 return cpr.newHolder(null); 7964 } 7965 7966 if (DEBUG_PROVIDER) { 7967 RuntimeException e = new RuntimeException("here"); 7968 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7969 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7970 } 7971 7972 // This is single process, and our app is now connecting to it. 7973 // See if we are already in the process of launching this 7974 // provider. 7975 final int N = mLaunchingProviders.size(); 7976 int i; 7977 for (i=0; i<N; i++) { 7978 if (mLaunchingProviders.get(i) == cpr) { 7979 break; 7980 } 7981 } 7982 7983 // If the provider is not already being launched, then get it 7984 // started. 7985 if (i >= N) { 7986 final long origId = Binder.clearCallingIdentity(); 7987 7988 try { 7989 // Content provider is now in use, its package can't be stopped. 7990 try { 7991 AppGlobals.getPackageManager().setPackageStoppedState( 7992 cpr.appInfo.packageName, false, userId); 7993 } catch (RemoteException e) { 7994 } catch (IllegalArgumentException e) { 7995 Slog.w(TAG, "Failed trying to unstop package " 7996 + cpr.appInfo.packageName + ": " + e); 7997 } 7998 7999 // Use existing process if already started 8000 ProcessRecord proc = getProcessRecordLocked( 8001 cpi.processName, cpr.appInfo.uid, false); 8002 if (proc != null && proc.thread != null) { 8003 if (DEBUG_PROVIDER) { 8004 Slog.d(TAG, "Installing in existing process " + proc); 8005 } 8006 proc.pubProviders.put(cpi.name, cpr); 8007 try { 8008 proc.thread.scheduleInstallProvider(cpi); 8009 } catch (RemoteException e) { 8010 } 8011 } else { 8012 proc = startProcessLocked(cpi.processName, 8013 cpr.appInfo, false, 0, "content provider", 8014 new ComponentName(cpi.applicationInfo.packageName, 8015 cpi.name), false, false, false); 8016 if (proc == null) { 8017 Slog.w(TAG, "Unable to launch app " 8018 + cpi.applicationInfo.packageName + "/" 8019 + cpi.applicationInfo.uid + " for provider " 8020 + name + ": process is bad"); 8021 return null; 8022 } 8023 } 8024 cpr.launchingApp = proc; 8025 mLaunchingProviders.add(cpr); 8026 } finally { 8027 Binder.restoreCallingIdentity(origId); 8028 } 8029 } 8030 8031 // Make sure the provider is published (the same provider class 8032 // may be published under multiple names). 8033 if (firstClass) { 8034 mProviderMap.putProviderByClass(comp, cpr); 8035 } 8036 8037 mProviderMap.putProviderByName(name, cpr); 8038 conn = incProviderCountLocked(r, cpr, token, stable); 8039 if (conn != null) { 8040 conn.waiting = true; 8041 } 8042 } 8043 } 8044 8045 // Wait for the provider to be published... 8046 synchronized (cpr) { 8047 while (cpr.provider == null) { 8048 if (cpr.launchingApp == null) { 8049 Slog.w(TAG, "Unable to launch app " 8050 + cpi.applicationInfo.packageName + "/" 8051 + cpi.applicationInfo.uid + " for provider " 8052 + name + ": launching app became null"); 8053 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8054 UserHandle.getUserId(cpi.applicationInfo.uid), 8055 cpi.applicationInfo.packageName, 8056 cpi.applicationInfo.uid, name); 8057 return null; 8058 } 8059 try { 8060 if (DEBUG_MU) { 8061 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8062 + cpr.launchingApp); 8063 } 8064 if (conn != null) { 8065 conn.waiting = true; 8066 } 8067 cpr.wait(); 8068 } catch (InterruptedException ex) { 8069 } finally { 8070 if (conn != null) { 8071 conn.waiting = false; 8072 } 8073 } 8074 } 8075 } 8076 return cpr != null ? cpr.newHolder(conn) : null; 8077 } 8078 8079 public final ContentProviderHolder getContentProvider( 8080 IApplicationThread caller, String name, int userId, boolean stable) { 8081 enforceNotIsolatedCaller("getContentProvider"); 8082 if (caller == null) { 8083 String msg = "null IApplicationThread when getting content provider " 8084 + name; 8085 Slog.w(TAG, msg); 8086 throw new SecurityException(msg); 8087 } 8088 8089 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8090 false, true, "getContentProvider", null); 8091 return getContentProviderImpl(caller, name, null, stable, userId); 8092 } 8093 8094 public ContentProviderHolder getContentProviderExternal( 8095 String name, int userId, IBinder token) { 8096 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8097 "Do not have permission in call getContentProviderExternal()"); 8098 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8099 false, true, "getContentProvider", null); 8100 return getContentProviderExternalUnchecked(name, token, userId); 8101 } 8102 8103 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8104 IBinder token, int userId) { 8105 return getContentProviderImpl(null, name, token, true, userId); 8106 } 8107 8108 /** 8109 * Drop a content provider from a ProcessRecord's bookkeeping 8110 */ 8111 public void removeContentProvider(IBinder connection, boolean stable) { 8112 enforceNotIsolatedCaller("removeContentProvider"); 8113 long ident = Binder.clearCallingIdentity(); 8114 try { 8115 synchronized (this) { 8116 ContentProviderConnection conn; 8117 try { 8118 conn = (ContentProviderConnection)connection; 8119 } catch (ClassCastException e) { 8120 String msg ="removeContentProvider: " + connection 8121 + " not a ContentProviderConnection"; 8122 Slog.w(TAG, msg); 8123 throw new IllegalArgumentException(msg); 8124 } 8125 if (conn == null) { 8126 throw new NullPointerException("connection is null"); 8127 } 8128 if (decProviderCountLocked(conn, null, null, stable)) { 8129 updateOomAdjLocked(); 8130 } 8131 } 8132 } finally { 8133 Binder.restoreCallingIdentity(ident); 8134 } 8135 } 8136 8137 public void removeContentProviderExternal(String name, IBinder token) { 8138 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8139 "Do not have permission in call removeContentProviderExternal()"); 8140 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8141 } 8142 8143 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8144 synchronized (this) { 8145 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8146 if(cpr == null) { 8147 //remove from mProvidersByClass 8148 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8149 return; 8150 } 8151 8152 //update content provider record entry info 8153 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8154 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8155 if (localCpr.hasExternalProcessHandles()) { 8156 if (localCpr.removeExternalProcessHandleLocked(token)) { 8157 updateOomAdjLocked(); 8158 } else { 8159 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8160 + " with no external reference for token: " 8161 + token + "."); 8162 } 8163 } else { 8164 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8165 + " with no external references."); 8166 } 8167 } 8168 } 8169 8170 public final void publishContentProviders(IApplicationThread caller, 8171 List<ContentProviderHolder> providers) { 8172 if (providers == null) { 8173 return; 8174 } 8175 8176 enforceNotIsolatedCaller("publishContentProviders"); 8177 synchronized (this) { 8178 final ProcessRecord r = getRecordForAppLocked(caller); 8179 if (DEBUG_MU) 8180 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8181 if (r == null) { 8182 throw new SecurityException( 8183 "Unable to find app for caller " + caller 8184 + " (pid=" + Binder.getCallingPid() 8185 + ") when publishing content providers"); 8186 } 8187 8188 final long origId = Binder.clearCallingIdentity(); 8189 8190 final int N = providers.size(); 8191 for (int i=0; i<N; i++) { 8192 ContentProviderHolder src = providers.get(i); 8193 if (src == null || src.info == null || src.provider == null) { 8194 continue; 8195 } 8196 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8197 if (DEBUG_MU) 8198 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8199 if (dst != null) { 8200 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8201 mProviderMap.putProviderByClass(comp, dst); 8202 String names[] = dst.info.authority.split(";"); 8203 for (int j = 0; j < names.length; j++) { 8204 mProviderMap.putProviderByName(names[j], dst); 8205 } 8206 8207 int NL = mLaunchingProviders.size(); 8208 int j; 8209 for (j=0; j<NL; j++) { 8210 if (mLaunchingProviders.get(j) == dst) { 8211 mLaunchingProviders.remove(j); 8212 j--; 8213 NL--; 8214 } 8215 } 8216 synchronized (dst) { 8217 dst.provider = src.provider; 8218 dst.proc = r; 8219 dst.notifyAll(); 8220 } 8221 updateOomAdjLocked(r); 8222 } 8223 } 8224 8225 Binder.restoreCallingIdentity(origId); 8226 } 8227 } 8228 8229 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8230 ContentProviderConnection conn; 8231 try { 8232 conn = (ContentProviderConnection)connection; 8233 } catch (ClassCastException e) { 8234 String msg ="refContentProvider: " + connection 8235 + " not a ContentProviderConnection"; 8236 Slog.w(TAG, msg); 8237 throw new IllegalArgumentException(msg); 8238 } 8239 if (conn == null) { 8240 throw new NullPointerException("connection is null"); 8241 } 8242 8243 synchronized (this) { 8244 if (stable > 0) { 8245 conn.numStableIncs += stable; 8246 } 8247 stable = conn.stableCount + stable; 8248 if (stable < 0) { 8249 throw new IllegalStateException("stableCount < 0: " + stable); 8250 } 8251 8252 if (unstable > 0) { 8253 conn.numUnstableIncs += unstable; 8254 } 8255 unstable = conn.unstableCount + unstable; 8256 if (unstable < 0) { 8257 throw new IllegalStateException("unstableCount < 0: " + unstable); 8258 } 8259 8260 if ((stable+unstable) <= 0) { 8261 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8262 + stable + " unstable=" + unstable); 8263 } 8264 conn.stableCount = stable; 8265 conn.unstableCount = unstable; 8266 return !conn.dead; 8267 } 8268 } 8269 8270 public void unstableProviderDied(IBinder connection) { 8271 ContentProviderConnection conn; 8272 try { 8273 conn = (ContentProviderConnection)connection; 8274 } catch (ClassCastException e) { 8275 String msg ="refContentProvider: " + connection 8276 + " not a ContentProviderConnection"; 8277 Slog.w(TAG, msg); 8278 throw new IllegalArgumentException(msg); 8279 } 8280 if (conn == null) { 8281 throw new NullPointerException("connection is null"); 8282 } 8283 8284 // Safely retrieve the content provider associated with the connection. 8285 IContentProvider provider; 8286 synchronized (this) { 8287 provider = conn.provider.provider; 8288 } 8289 8290 if (provider == null) { 8291 // Um, yeah, we're way ahead of you. 8292 return; 8293 } 8294 8295 // Make sure the caller is being honest with us. 8296 if (provider.asBinder().pingBinder()) { 8297 // Er, no, still looks good to us. 8298 synchronized (this) { 8299 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8300 + " says " + conn + " died, but we don't agree"); 8301 return; 8302 } 8303 } 8304 8305 // Well look at that! It's dead! 8306 synchronized (this) { 8307 if (conn.provider.provider != provider) { 8308 // But something changed... good enough. 8309 return; 8310 } 8311 8312 ProcessRecord proc = conn.provider.proc; 8313 if (proc == null || proc.thread == null) { 8314 // Seems like the process is already cleaned up. 8315 return; 8316 } 8317 8318 // As far as we're concerned, this is just like receiving a 8319 // death notification... just a bit prematurely. 8320 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8321 + ") early provider death"); 8322 final long ident = Binder.clearCallingIdentity(); 8323 try { 8324 appDiedLocked(proc, proc.pid, proc.thread); 8325 } finally { 8326 Binder.restoreCallingIdentity(ident); 8327 } 8328 } 8329 } 8330 8331 @Override 8332 public void appNotRespondingViaProvider(IBinder connection) { 8333 enforceCallingPermission( 8334 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8335 8336 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8337 if (conn == null) { 8338 Slog.w(TAG, "ContentProviderConnection is null"); 8339 return; 8340 } 8341 8342 final ProcessRecord host = conn.provider.proc; 8343 if (host == null) { 8344 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8345 return; 8346 } 8347 8348 final long token = Binder.clearCallingIdentity(); 8349 try { 8350 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8351 } finally { 8352 Binder.restoreCallingIdentity(token); 8353 } 8354 } 8355 8356 public final void installSystemProviders() { 8357 List<ProviderInfo> providers; 8358 synchronized (this) { 8359 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8360 providers = generateApplicationProvidersLocked(app); 8361 if (providers != null) { 8362 for (int i=providers.size()-1; i>=0; i--) { 8363 ProviderInfo pi = (ProviderInfo)providers.get(i); 8364 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8365 Slog.w(TAG, "Not installing system proc provider " + pi.name 8366 + ": not system .apk"); 8367 providers.remove(i); 8368 } 8369 } 8370 } 8371 } 8372 if (providers != null) { 8373 mSystemThread.installSystemProviders(providers); 8374 } 8375 8376 mCoreSettingsObserver = new CoreSettingsObserver(this); 8377 8378 mUsageStatsService.monitorPackages(); 8379 } 8380 8381 /** 8382 * Allows app to retrieve the MIME type of a URI without having permission 8383 * to access its content provider. 8384 * 8385 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8386 * 8387 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8388 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8389 */ 8390 public String getProviderMimeType(Uri uri, int userId) { 8391 enforceNotIsolatedCaller("getProviderMimeType"); 8392 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8393 userId, false, true, "getProviderMimeType", null); 8394 final String name = uri.getAuthority(); 8395 final long ident = Binder.clearCallingIdentity(); 8396 ContentProviderHolder holder = null; 8397 8398 try { 8399 holder = getContentProviderExternalUnchecked(name, null, userId); 8400 if (holder != null) { 8401 return holder.provider.getType(uri); 8402 } 8403 } catch (RemoteException e) { 8404 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8405 return null; 8406 } finally { 8407 if (holder != null) { 8408 removeContentProviderExternalUnchecked(name, null, userId); 8409 } 8410 Binder.restoreCallingIdentity(ident); 8411 } 8412 8413 return null; 8414 } 8415 8416 // ========================================================= 8417 // GLOBAL MANAGEMENT 8418 // ========================================================= 8419 8420 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8421 boolean isolated) { 8422 String proc = customProcess != null ? customProcess : info.processName; 8423 BatteryStatsImpl.Uid.Proc ps = null; 8424 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8425 int uid = info.uid; 8426 if (isolated) { 8427 int userId = UserHandle.getUserId(uid); 8428 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8429 while (true) { 8430 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8431 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8432 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8433 } 8434 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8435 mNextIsolatedProcessUid++; 8436 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8437 // No process for this uid, use it. 8438 break; 8439 } 8440 stepsLeft--; 8441 if (stepsLeft <= 0) { 8442 return null; 8443 } 8444 } 8445 } 8446 return new ProcessRecord(stats, info, proc, uid); 8447 } 8448 8449 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8450 ProcessRecord app; 8451 if (!isolated) { 8452 app = getProcessRecordLocked(info.processName, info.uid, true); 8453 } else { 8454 app = null; 8455 } 8456 8457 if (app == null) { 8458 app = newProcessRecordLocked(info, null, isolated); 8459 mProcessNames.put(info.processName, app.uid, app); 8460 if (isolated) { 8461 mIsolatedProcesses.put(app.uid, app); 8462 } 8463 updateLruProcessLocked(app, false, null); 8464 updateOomAdjLocked(); 8465 } 8466 8467 // This package really, really can not be stopped. 8468 try { 8469 AppGlobals.getPackageManager().setPackageStoppedState( 8470 info.packageName, false, UserHandle.getUserId(app.uid)); 8471 } catch (RemoteException e) { 8472 } catch (IllegalArgumentException e) { 8473 Slog.w(TAG, "Failed trying to unstop package " 8474 + info.packageName + ": " + e); 8475 } 8476 8477 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8478 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8479 app.persistent = true; 8480 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8481 } 8482 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8483 mPersistentStartingProcesses.add(app); 8484 startProcessLocked(app, "added application", app.processName); 8485 } 8486 8487 return app; 8488 } 8489 8490 public void unhandledBack() { 8491 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8492 "unhandledBack()"); 8493 8494 synchronized(this) { 8495 final long origId = Binder.clearCallingIdentity(); 8496 try { 8497 getFocusedStack().unhandledBackLocked(); 8498 } finally { 8499 Binder.restoreCallingIdentity(origId); 8500 } 8501 } 8502 } 8503 8504 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8505 enforceNotIsolatedCaller("openContentUri"); 8506 final int userId = UserHandle.getCallingUserId(); 8507 String name = uri.getAuthority(); 8508 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8509 ParcelFileDescriptor pfd = null; 8510 if (cph != null) { 8511 // We record the binder invoker's uid in thread-local storage before 8512 // going to the content provider to open the file. Later, in the code 8513 // that handles all permissions checks, we look for this uid and use 8514 // that rather than the Activity Manager's own uid. The effect is that 8515 // we do the check against the caller's permissions even though it looks 8516 // to the content provider like the Activity Manager itself is making 8517 // the request. 8518 sCallerIdentity.set(new Identity( 8519 Binder.getCallingPid(), Binder.getCallingUid())); 8520 try { 8521 pfd = cph.provider.openFile(null, uri, "r", null); 8522 } catch (FileNotFoundException e) { 8523 // do nothing; pfd will be returned null 8524 } finally { 8525 // Ensure that whatever happens, we clean up the identity state 8526 sCallerIdentity.remove(); 8527 } 8528 8529 // We've got the fd now, so we're done with the provider. 8530 removeContentProviderExternalUnchecked(name, null, userId); 8531 } else { 8532 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8533 } 8534 return pfd; 8535 } 8536 8537 // Actually is sleeping or shutting down or whatever else in the future 8538 // is an inactive state. 8539 public boolean isSleepingOrShuttingDown() { 8540 return mSleeping || mShuttingDown; 8541 } 8542 8543 public boolean isSleeping() { 8544 return mSleeping; 8545 } 8546 8547 void goingToSleep() { 8548 synchronized(this) { 8549 mWentToSleep = true; 8550 updateEventDispatchingLocked(); 8551 goToSleepIfNeededLocked(); 8552 } 8553 } 8554 8555 void finishRunningVoiceLocked() { 8556 if (mRunningVoice) { 8557 mRunningVoice = false; 8558 goToSleepIfNeededLocked(); 8559 } 8560 } 8561 8562 void goToSleepIfNeededLocked() { 8563 if (mWentToSleep && !mRunningVoice) { 8564 if (!mSleeping) { 8565 mSleeping = true; 8566 mStackSupervisor.goingToSleepLocked(); 8567 8568 // Initialize the wake times of all processes. 8569 checkExcessivePowerUsageLocked(false); 8570 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8571 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8572 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8573 } 8574 } 8575 } 8576 8577 @Override 8578 public boolean shutdown(int timeout) { 8579 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8580 != PackageManager.PERMISSION_GRANTED) { 8581 throw new SecurityException("Requires permission " 8582 + android.Manifest.permission.SHUTDOWN); 8583 } 8584 8585 boolean timedout = false; 8586 8587 synchronized(this) { 8588 mShuttingDown = true; 8589 updateEventDispatchingLocked(); 8590 timedout = mStackSupervisor.shutdownLocked(timeout); 8591 } 8592 8593 mAppOpsService.shutdown(); 8594 mUsageStatsService.shutdown(); 8595 mBatteryStatsService.shutdown(); 8596 synchronized (this) { 8597 mProcessStats.shutdownLocked(); 8598 } 8599 8600 return timedout; 8601 } 8602 8603 public final void activitySlept(IBinder token) { 8604 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8605 8606 final long origId = Binder.clearCallingIdentity(); 8607 8608 synchronized (this) { 8609 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8610 if (r != null) { 8611 mStackSupervisor.activitySleptLocked(r); 8612 } 8613 } 8614 8615 Binder.restoreCallingIdentity(origId); 8616 } 8617 8618 void logLockScreen(String msg) { 8619 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8620 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8621 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8622 mStackSupervisor.mDismissKeyguardOnNextActivity); 8623 } 8624 8625 private void comeOutOfSleepIfNeededLocked() { 8626 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8627 if (mSleeping) { 8628 mSleeping = false; 8629 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8630 } 8631 } 8632 } 8633 8634 void wakingUp() { 8635 synchronized(this) { 8636 mWentToSleep = false; 8637 updateEventDispatchingLocked(); 8638 comeOutOfSleepIfNeededLocked(); 8639 } 8640 } 8641 8642 void startRunningVoiceLocked() { 8643 if (!mRunningVoice) { 8644 mRunningVoice = true; 8645 comeOutOfSleepIfNeededLocked(); 8646 } 8647 } 8648 8649 private void updateEventDispatchingLocked() { 8650 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8651 } 8652 8653 public void setLockScreenShown(boolean shown) { 8654 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8655 != PackageManager.PERMISSION_GRANTED) { 8656 throw new SecurityException("Requires permission " 8657 + android.Manifest.permission.DEVICE_POWER); 8658 } 8659 8660 synchronized(this) { 8661 long ident = Binder.clearCallingIdentity(); 8662 try { 8663 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8664 mLockScreenShown = shown; 8665 comeOutOfSleepIfNeededLocked(); 8666 } finally { 8667 Binder.restoreCallingIdentity(ident); 8668 } 8669 } 8670 } 8671 8672 public void stopAppSwitches() { 8673 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8674 != PackageManager.PERMISSION_GRANTED) { 8675 throw new SecurityException("Requires permission " 8676 + android.Manifest.permission.STOP_APP_SWITCHES); 8677 } 8678 8679 synchronized(this) { 8680 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8681 + APP_SWITCH_DELAY_TIME; 8682 mDidAppSwitch = false; 8683 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8684 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8685 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8686 } 8687 } 8688 8689 public void resumeAppSwitches() { 8690 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8691 != PackageManager.PERMISSION_GRANTED) { 8692 throw new SecurityException("Requires permission " 8693 + android.Manifest.permission.STOP_APP_SWITCHES); 8694 } 8695 8696 synchronized(this) { 8697 // Note that we don't execute any pending app switches... we will 8698 // let those wait until either the timeout, or the next start 8699 // activity request. 8700 mAppSwitchesAllowedTime = 0; 8701 } 8702 } 8703 8704 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8705 String name) { 8706 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8707 return true; 8708 } 8709 8710 final int perm = checkComponentPermission( 8711 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8712 callingUid, -1, true); 8713 if (perm == PackageManager.PERMISSION_GRANTED) { 8714 return true; 8715 } 8716 8717 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8718 return false; 8719 } 8720 8721 public void setDebugApp(String packageName, boolean waitForDebugger, 8722 boolean persistent) { 8723 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8724 "setDebugApp()"); 8725 8726 long ident = Binder.clearCallingIdentity(); 8727 try { 8728 // Note that this is not really thread safe if there are multiple 8729 // callers into it at the same time, but that's not a situation we 8730 // care about. 8731 if (persistent) { 8732 final ContentResolver resolver = mContext.getContentResolver(); 8733 Settings.Global.putString( 8734 resolver, Settings.Global.DEBUG_APP, 8735 packageName); 8736 Settings.Global.putInt( 8737 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8738 waitForDebugger ? 1 : 0); 8739 } 8740 8741 synchronized (this) { 8742 if (!persistent) { 8743 mOrigDebugApp = mDebugApp; 8744 mOrigWaitForDebugger = mWaitForDebugger; 8745 } 8746 mDebugApp = packageName; 8747 mWaitForDebugger = waitForDebugger; 8748 mDebugTransient = !persistent; 8749 if (packageName != null) { 8750 forceStopPackageLocked(packageName, -1, false, false, true, true, 8751 false, UserHandle.USER_ALL, "set debug app"); 8752 } 8753 } 8754 } finally { 8755 Binder.restoreCallingIdentity(ident); 8756 } 8757 } 8758 8759 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8760 synchronized (this) { 8761 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8762 if (!isDebuggable) { 8763 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8764 throw new SecurityException("Process not debuggable: " + app.packageName); 8765 } 8766 } 8767 8768 mOpenGlTraceApp = processName; 8769 } 8770 } 8771 8772 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8773 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8774 synchronized (this) { 8775 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8776 if (!isDebuggable) { 8777 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8778 throw new SecurityException("Process not debuggable: " + app.packageName); 8779 } 8780 } 8781 mProfileApp = processName; 8782 mProfileFile = profileFile; 8783 if (mProfileFd != null) { 8784 try { 8785 mProfileFd.close(); 8786 } catch (IOException e) { 8787 } 8788 mProfileFd = null; 8789 } 8790 mProfileFd = profileFd; 8791 mProfileType = 0; 8792 mAutoStopProfiler = autoStopProfiler; 8793 } 8794 } 8795 8796 @Override 8797 public void setAlwaysFinish(boolean enabled) { 8798 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8799 "setAlwaysFinish()"); 8800 8801 Settings.Global.putInt( 8802 mContext.getContentResolver(), 8803 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8804 8805 synchronized (this) { 8806 mAlwaysFinishActivities = enabled; 8807 } 8808 } 8809 8810 @Override 8811 public void setActivityController(IActivityController controller) { 8812 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8813 "setActivityController()"); 8814 synchronized (this) { 8815 mController = controller; 8816 Watchdog.getInstance().setActivityController(controller); 8817 } 8818 } 8819 8820 @Override 8821 public void setUserIsMonkey(boolean userIsMonkey) { 8822 synchronized (this) { 8823 synchronized (mPidsSelfLocked) { 8824 final int callingPid = Binder.getCallingPid(); 8825 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8826 if (precessRecord == null) { 8827 throw new SecurityException("Unknown process: " + callingPid); 8828 } 8829 if (precessRecord.instrumentationUiAutomationConnection == null) { 8830 throw new SecurityException("Only an instrumentation process " 8831 + "with a UiAutomation can call setUserIsMonkey"); 8832 } 8833 } 8834 mUserIsMonkey = userIsMonkey; 8835 } 8836 } 8837 8838 @Override 8839 public boolean isUserAMonkey() { 8840 synchronized (this) { 8841 // If there is a controller also implies the user is a monkey. 8842 return (mUserIsMonkey || mController != null); 8843 } 8844 } 8845 8846 public void requestBugReport() { 8847 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8848 SystemProperties.set("ctl.start", "bugreport"); 8849 } 8850 8851 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8852 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8853 } 8854 8855 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8856 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8857 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8858 } 8859 return KEY_DISPATCHING_TIMEOUT; 8860 } 8861 8862 @Override 8863 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8864 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8865 != PackageManager.PERMISSION_GRANTED) { 8866 throw new SecurityException("Requires permission " 8867 + android.Manifest.permission.FILTER_EVENTS); 8868 } 8869 ProcessRecord proc; 8870 long timeout; 8871 synchronized (this) { 8872 synchronized (mPidsSelfLocked) { 8873 proc = mPidsSelfLocked.get(pid); 8874 } 8875 timeout = getInputDispatchingTimeoutLocked(proc); 8876 } 8877 8878 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8879 return -1; 8880 } 8881 8882 return timeout; 8883 } 8884 8885 /** 8886 * Handle input dispatching timeouts. 8887 * Returns whether input dispatching should be aborted or not. 8888 */ 8889 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8890 final ActivityRecord activity, final ActivityRecord parent, 8891 final boolean aboveSystem, String reason) { 8892 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8893 != PackageManager.PERMISSION_GRANTED) { 8894 throw new SecurityException("Requires permission " 8895 + android.Manifest.permission.FILTER_EVENTS); 8896 } 8897 8898 final String annotation; 8899 if (reason == null) { 8900 annotation = "Input dispatching timed out"; 8901 } else { 8902 annotation = "Input dispatching timed out (" + reason + ")"; 8903 } 8904 8905 if (proc != null) { 8906 synchronized (this) { 8907 if (proc.debugging) { 8908 return false; 8909 } 8910 8911 if (mDidDexOpt) { 8912 // Give more time since we were dexopting. 8913 mDidDexOpt = false; 8914 return false; 8915 } 8916 8917 if (proc.instrumentationClass != null) { 8918 Bundle info = new Bundle(); 8919 info.putString("shortMsg", "keyDispatchingTimedOut"); 8920 info.putString("longMsg", annotation); 8921 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8922 return true; 8923 } 8924 } 8925 mHandler.post(new Runnable() { 8926 @Override 8927 public void run() { 8928 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8929 } 8930 }); 8931 } 8932 8933 return true; 8934 } 8935 8936 public Bundle getAssistContextExtras(int requestType) { 8937 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8938 "getAssistContextExtras()"); 8939 PendingAssistExtras pae; 8940 Bundle extras = new Bundle(); 8941 synchronized (this) { 8942 ActivityRecord activity = getFocusedStack().mResumedActivity; 8943 if (activity == null) { 8944 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8945 return null; 8946 } 8947 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8948 if (activity.app == null || activity.app.thread == null) { 8949 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8950 return extras; 8951 } 8952 if (activity.app.pid == Binder.getCallingPid()) { 8953 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8954 return extras; 8955 } 8956 pae = new PendingAssistExtras(activity); 8957 try { 8958 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8959 requestType); 8960 mPendingAssistExtras.add(pae); 8961 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8962 } catch (RemoteException e) { 8963 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8964 return extras; 8965 } 8966 } 8967 synchronized (pae) { 8968 while (!pae.haveResult) { 8969 try { 8970 pae.wait(); 8971 } catch (InterruptedException e) { 8972 } 8973 } 8974 if (pae.result != null) { 8975 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8976 } 8977 } 8978 synchronized (this) { 8979 mPendingAssistExtras.remove(pae); 8980 mHandler.removeCallbacks(pae); 8981 } 8982 return extras; 8983 } 8984 8985 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8986 PendingAssistExtras pae = (PendingAssistExtras)token; 8987 synchronized (pae) { 8988 pae.result = extras; 8989 pae.haveResult = true; 8990 pae.notifyAll(); 8991 } 8992 } 8993 8994 public void registerProcessObserver(IProcessObserver observer) { 8995 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8996 "registerProcessObserver()"); 8997 synchronized (this) { 8998 mProcessObservers.register(observer); 8999 } 9000 } 9001 9002 @Override 9003 public void unregisterProcessObserver(IProcessObserver observer) { 9004 synchronized (this) { 9005 mProcessObservers.unregister(observer); 9006 } 9007 } 9008 9009 @Override 9010 public boolean convertFromTranslucent(IBinder token) { 9011 final long origId = Binder.clearCallingIdentity(); 9012 try { 9013 synchronized (this) { 9014 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9015 if (r == null) { 9016 return false; 9017 } 9018 if (r.changeWindowTranslucency(true)) { 9019 mWindowManager.setAppFullscreen(token, true); 9020 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9021 return true; 9022 } 9023 return false; 9024 } 9025 } finally { 9026 Binder.restoreCallingIdentity(origId); 9027 } 9028 } 9029 9030 @Override 9031 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9032 final long origId = Binder.clearCallingIdentity(); 9033 try { 9034 synchronized (this) { 9035 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9036 if (r == null) { 9037 return false; 9038 } 9039 if (r.changeWindowTranslucency(false)) { 9040 r.task.stack.convertToTranslucent(r, options); 9041 mWindowManager.setAppFullscreen(token, false); 9042 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9043 return true; 9044 } 9045 return false; 9046 } 9047 } finally { 9048 Binder.restoreCallingIdentity(origId); 9049 } 9050 } 9051 9052 @Override 9053 public ActivityOptions getActivityOptions(IBinder token) { 9054 final long origId = Binder.clearCallingIdentity(); 9055 try { 9056 synchronized (this) { 9057 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9058 if (r != null) { 9059 final ActivityOptions activityOptions = r.pendingOptions; 9060 r.pendingOptions = null; 9061 return activityOptions; 9062 } 9063 return null; 9064 } 9065 } finally { 9066 Binder.restoreCallingIdentity(origId); 9067 } 9068 } 9069 9070 @Override 9071 public void setImmersive(IBinder token, boolean immersive) { 9072 synchronized(this) { 9073 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9074 if (r == null) { 9075 throw new IllegalArgumentException(); 9076 } 9077 r.immersive = immersive; 9078 9079 // update associated state if we're frontmost 9080 if (r == mFocusedActivity) { 9081 if (DEBUG_IMMERSIVE) { 9082 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9083 } 9084 applyUpdateLockStateLocked(r); 9085 } 9086 } 9087 } 9088 9089 @Override 9090 public boolean isImmersive(IBinder token) { 9091 synchronized (this) { 9092 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9093 if (r == null) { 9094 throw new IllegalArgumentException(); 9095 } 9096 return r.immersive; 9097 } 9098 } 9099 9100 public boolean isTopActivityImmersive() { 9101 enforceNotIsolatedCaller("startActivity"); 9102 synchronized (this) { 9103 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9104 return (r != null) ? r.immersive : false; 9105 } 9106 } 9107 9108 public final void enterSafeMode() { 9109 synchronized(this) { 9110 // It only makes sense to do this before the system is ready 9111 // and started launching other packages. 9112 if (!mSystemReady) { 9113 try { 9114 AppGlobals.getPackageManager().enterSafeMode(); 9115 } catch (RemoteException e) { 9116 } 9117 } 9118 9119 mSafeMode = true; 9120 } 9121 } 9122 9123 public final void showSafeModeOverlay() { 9124 View v = LayoutInflater.from(mContext).inflate( 9125 com.android.internal.R.layout.safe_mode, null); 9126 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9127 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9128 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9129 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9130 lp.gravity = Gravity.BOTTOM | Gravity.START; 9131 lp.format = v.getBackground().getOpacity(); 9132 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9133 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9134 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9135 ((WindowManager)mContext.getSystemService( 9136 Context.WINDOW_SERVICE)).addView(v, lp); 9137 } 9138 9139 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9140 if (!(sender instanceof PendingIntentRecord)) { 9141 return; 9142 } 9143 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9144 synchronized (stats) { 9145 if (mBatteryStatsService.isOnBattery()) { 9146 mBatteryStatsService.enforceCallingPermission(); 9147 PendingIntentRecord rec = (PendingIntentRecord)sender; 9148 int MY_UID = Binder.getCallingUid(); 9149 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9150 BatteryStatsImpl.Uid.Pkg pkg = 9151 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9152 sourcePkg != null ? sourcePkg : rec.key.packageName); 9153 pkg.incWakeupsLocked(); 9154 } 9155 } 9156 } 9157 9158 public boolean killPids(int[] pids, String pReason, boolean secure) { 9159 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9160 throw new SecurityException("killPids only available to the system"); 9161 } 9162 String reason = (pReason == null) ? "Unknown" : pReason; 9163 // XXX Note: don't acquire main activity lock here, because the window 9164 // manager calls in with its locks held. 9165 9166 boolean killed = false; 9167 synchronized (mPidsSelfLocked) { 9168 int[] types = new int[pids.length]; 9169 int worstType = 0; 9170 for (int i=0; i<pids.length; i++) { 9171 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9172 if (proc != null) { 9173 int type = proc.setAdj; 9174 types[i] = type; 9175 if (type > worstType) { 9176 worstType = type; 9177 } 9178 } 9179 } 9180 9181 // If the worst oom_adj is somewhere in the cached proc LRU range, 9182 // then constrain it so we will kill all cached procs. 9183 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9184 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9185 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9186 } 9187 9188 // If this is not a secure call, don't let it kill processes that 9189 // are important. 9190 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9191 worstType = ProcessList.SERVICE_ADJ; 9192 } 9193 9194 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9195 for (int i=0; i<pids.length; i++) { 9196 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9197 if (proc == null) { 9198 continue; 9199 } 9200 int adj = proc.setAdj; 9201 if (adj >= worstType && !proc.killedByAm) { 9202 killUnneededProcessLocked(proc, reason); 9203 killed = true; 9204 } 9205 } 9206 } 9207 return killed; 9208 } 9209 9210 @Override 9211 public void killUid(int uid, String reason) { 9212 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9213 throw new SecurityException("killUid only available to the system"); 9214 } 9215 synchronized (this) { 9216 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9217 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9218 reason != null ? reason : "kill uid"); 9219 } 9220 } 9221 9222 @Override 9223 public boolean killProcessesBelowForeground(String reason) { 9224 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9225 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9226 } 9227 9228 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9229 } 9230 9231 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9232 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9233 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9234 } 9235 9236 boolean killed = false; 9237 synchronized (mPidsSelfLocked) { 9238 final int size = mPidsSelfLocked.size(); 9239 for (int i = 0; i < size; i++) { 9240 final int pid = mPidsSelfLocked.keyAt(i); 9241 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9242 if (proc == null) continue; 9243 9244 final int adj = proc.setAdj; 9245 if (adj > belowAdj && !proc.killedByAm) { 9246 killUnneededProcessLocked(proc, reason); 9247 killed = true; 9248 } 9249 } 9250 } 9251 return killed; 9252 } 9253 9254 @Override 9255 public void hang(final IBinder who, boolean allowRestart) { 9256 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9257 != PackageManager.PERMISSION_GRANTED) { 9258 throw new SecurityException("Requires permission " 9259 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9260 } 9261 9262 final IBinder.DeathRecipient death = new DeathRecipient() { 9263 @Override 9264 public void binderDied() { 9265 synchronized (this) { 9266 notifyAll(); 9267 } 9268 } 9269 }; 9270 9271 try { 9272 who.linkToDeath(death, 0); 9273 } catch (RemoteException e) { 9274 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9275 return; 9276 } 9277 9278 synchronized (this) { 9279 Watchdog.getInstance().setAllowRestart(allowRestart); 9280 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9281 synchronized (death) { 9282 while (who.isBinderAlive()) { 9283 try { 9284 death.wait(); 9285 } catch (InterruptedException e) { 9286 } 9287 } 9288 } 9289 Watchdog.getInstance().setAllowRestart(true); 9290 } 9291 } 9292 9293 @Override 9294 public void restart() { 9295 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9296 != PackageManager.PERMISSION_GRANTED) { 9297 throw new SecurityException("Requires permission " 9298 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9299 } 9300 9301 Log.i(TAG, "Sending shutdown broadcast..."); 9302 9303 BroadcastReceiver br = new BroadcastReceiver() { 9304 @Override public void onReceive(Context context, Intent intent) { 9305 // Now the broadcast is done, finish up the low-level shutdown. 9306 Log.i(TAG, "Shutting down activity manager..."); 9307 shutdown(10000); 9308 Log.i(TAG, "Shutdown complete, restarting!"); 9309 Process.killProcess(Process.myPid()); 9310 System.exit(10); 9311 } 9312 }; 9313 9314 // First send the high-level shut down broadcast. 9315 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9316 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9317 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9318 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9319 mContext.sendOrderedBroadcastAsUser(intent, 9320 UserHandle.ALL, null, br, mHandler, 0, null, null); 9321 */ 9322 br.onReceive(mContext, intent); 9323 } 9324 9325 private long getLowRamTimeSinceIdle(long now) { 9326 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9327 } 9328 9329 @Override 9330 public void performIdleMaintenance() { 9331 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9332 != PackageManager.PERMISSION_GRANTED) { 9333 throw new SecurityException("Requires permission " 9334 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9335 } 9336 9337 synchronized (this) { 9338 final long now = SystemClock.uptimeMillis(); 9339 final long timeSinceLastIdle = now - mLastIdleTime; 9340 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9341 mLastIdleTime = now; 9342 mLowRamTimeSinceLastIdle = 0; 9343 if (mLowRamStartTime != 0) { 9344 mLowRamStartTime = now; 9345 } 9346 9347 StringBuilder sb = new StringBuilder(128); 9348 sb.append("Idle maintenance over "); 9349 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9350 sb.append(" low RAM for "); 9351 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9352 Slog.i(TAG, sb.toString()); 9353 9354 // If at least 1/3 of our time since the last idle period has been spent 9355 // with RAM low, then we want to kill processes. 9356 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9357 9358 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9359 ProcessRecord proc = mLruProcesses.get(i); 9360 if (proc.notCachedSinceIdle) { 9361 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9362 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9363 if (doKilling && proc.initialIdlePss != 0 9364 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9365 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9366 + " from " + proc.initialIdlePss + ")"); 9367 } 9368 } 9369 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9370 proc.notCachedSinceIdle = true; 9371 proc.initialIdlePss = 0; 9372 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9373 isSleeping(), now); 9374 } 9375 } 9376 9377 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9378 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9379 } 9380 } 9381 9382 private void retrieveSettings() { 9383 final ContentResolver resolver = mContext.getContentResolver(); 9384 String debugApp = Settings.Global.getString( 9385 resolver, Settings.Global.DEBUG_APP); 9386 boolean waitForDebugger = Settings.Global.getInt( 9387 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9388 boolean alwaysFinishActivities = Settings.Global.getInt( 9389 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9390 boolean forceRtl = Settings.Global.getInt( 9391 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9392 // Transfer any global setting for forcing RTL layout, into a System Property 9393 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9394 9395 Configuration configuration = new Configuration(); 9396 Settings.System.getConfiguration(resolver, configuration); 9397 if (forceRtl) { 9398 // This will take care of setting the correct layout direction flags 9399 configuration.setLayoutDirection(configuration.locale); 9400 } 9401 9402 synchronized (this) { 9403 mDebugApp = mOrigDebugApp = debugApp; 9404 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9405 mAlwaysFinishActivities = alwaysFinishActivities; 9406 // This happens before any activities are started, so we can 9407 // change mConfiguration in-place. 9408 updateConfigurationLocked(configuration, null, false, true); 9409 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9410 } 9411 } 9412 9413 public boolean testIsSystemReady() { 9414 // no need to synchronize(this) just to read & return the value 9415 return mSystemReady; 9416 } 9417 9418 private static File getCalledPreBootReceiversFile() { 9419 File dataDir = Environment.getDataDirectory(); 9420 File systemDir = new File(dataDir, "system"); 9421 File fname = new File(systemDir, "called_pre_boots.dat"); 9422 return fname; 9423 } 9424 9425 static final int LAST_DONE_VERSION = 10000; 9426 9427 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9428 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9429 File file = getCalledPreBootReceiversFile(); 9430 FileInputStream fis = null; 9431 try { 9432 fis = new FileInputStream(file); 9433 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9434 int fvers = dis.readInt(); 9435 if (fvers == LAST_DONE_VERSION) { 9436 String vers = dis.readUTF(); 9437 String codename = dis.readUTF(); 9438 String build = dis.readUTF(); 9439 if (android.os.Build.VERSION.RELEASE.equals(vers) 9440 && android.os.Build.VERSION.CODENAME.equals(codename) 9441 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9442 int num = dis.readInt(); 9443 while (num > 0) { 9444 num--; 9445 String pkg = dis.readUTF(); 9446 String cls = dis.readUTF(); 9447 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9448 } 9449 } 9450 } 9451 } catch (FileNotFoundException e) { 9452 } catch (IOException e) { 9453 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9454 } finally { 9455 if (fis != null) { 9456 try { 9457 fis.close(); 9458 } catch (IOException e) { 9459 } 9460 } 9461 } 9462 return lastDoneReceivers; 9463 } 9464 9465 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9466 File file = getCalledPreBootReceiversFile(); 9467 FileOutputStream fos = null; 9468 DataOutputStream dos = null; 9469 try { 9470 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9471 fos = new FileOutputStream(file); 9472 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9473 dos.writeInt(LAST_DONE_VERSION); 9474 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9475 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9476 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9477 dos.writeInt(list.size()); 9478 for (int i=0; i<list.size(); i++) { 9479 dos.writeUTF(list.get(i).getPackageName()); 9480 dos.writeUTF(list.get(i).getClassName()); 9481 } 9482 } catch (IOException e) { 9483 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9484 file.delete(); 9485 } finally { 9486 FileUtils.sync(fos); 9487 if (dos != null) { 9488 try { 9489 dos.close(); 9490 } catch (IOException e) { 9491 // TODO Auto-generated catch block 9492 e.printStackTrace(); 9493 } 9494 } 9495 } 9496 } 9497 9498 public void systemReady(final Runnable goingCallback) { 9499 synchronized(this) { 9500 if (mSystemReady) { 9501 if (goingCallback != null) goingCallback.run(); 9502 return; 9503 } 9504 9505 // Check to see if there are any update receivers to run. 9506 if (!mDidUpdate) { 9507 if (mWaitingUpdate) { 9508 return; 9509 } 9510 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9511 List<ResolveInfo> ris = null; 9512 try { 9513 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9514 intent, null, 0, 0); 9515 } catch (RemoteException e) { 9516 } 9517 if (ris != null) { 9518 for (int i=ris.size()-1; i>=0; i--) { 9519 if ((ris.get(i).activityInfo.applicationInfo.flags 9520 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9521 ris.remove(i); 9522 } 9523 } 9524 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9525 9526 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9527 9528 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9529 for (int i=0; i<ris.size(); i++) { 9530 ActivityInfo ai = ris.get(i).activityInfo; 9531 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9532 if (lastDoneReceivers.contains(comp)) { 9533 // We already did the pre boot receiver for this app with the current 9534 // platform version, so don't do it again... 9535 ris.remove(i); 9536 i--; 9537 // ...however, do keep it as one that has been done, so we don't 9538 // forget about it when rewriting the file of last done receivers. 9539 doneReceivers.add(comp); 9540 } 9541 } 9542 9543 final int[] users = getUsersLocked(); 9544 for (int i=0; i<ris.size(); i++) { 9545 ActivityInfo ai = ris.get(i).activityInfo; 9546 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9547 doneReceivers.add(comp); 9548 intent.setComponent(comp); 9549 for (int j=0; j<users.length; j++) { 9550 IIntentReceiver finisher = null; 9551 if (i == ris.size()-1 && j == users.length-1) { 9552 finisher = new IIntentReceiver.Stub() { 9553 public void performReceive(Intent intent, int resultCode, 9554 String data, Bundle extras, boolean ordered, 9555 boolean sticky, int sendingUser) { 9556 // The raw IIntentReceiver interface is called 9557 // with the AM lock held, so redispatch to 9558 // execute our code without the lock. 9559 mHandler.post(new Runnable() { 9560 public void run() { 9561 synchronized (ActivityManagerService.this) { 9562 mDidUpdate = true; 9563 } 9564 writeLastDonePreBootReceivers(doneReceivers); 9565 showBootMessage(mContext.getText( 9566 R.string.android_upgrading_complete), 9567 false); 9568 systemReady(goingCallback); 9569 } 9570 }); 9571 } 9572 }; 9573 } 9574 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9575 + " for user " + users[j]); 9576 broadcastIntentLocked(null, null, intent, null, finisher, 9577 0, null, null, null, AppOpsManager.OP_NONE, 9578 true, false, MY_PID, Process.SYSTEM_UID, 9579 users[j]); 9580 if (finisher != null) { 9581 mWaitingUpdate = true; 9582 } 9583 } 9584 } 9585 } 9586 if (mWaitingUpdate) { 9587 return; 9588 } 9589 mDidUpdate = true; 9590 } 9591 9592 mAppOpsService.systemReady(); 9593 mUsageStatsService.systemReady(); 9594 mSystemReady = true; 9595 } 9596 9597 ArrayList<ProcessRecord> procsToKill = null; 9598 synchronized(mPidsSelfLocked) { 9599 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9600 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9601 if (!isAllowedWhileBooting(proc.info)){ 9602 if (procsToKill == null) { 9603 procsToKill = new ArrayList<ProcessRecord>(); 9604 } 9605 procsToKill.add(proc); 9606 } 9607 } 9608 } 9609 9610 synchronized(this) { 9611 if (procsToKill != null) { 9612 for (int i=procsToKill.size()-1; i>=0; i--) { 9613 ProcessRecord proc = procsToKill.get(i); 9614 Slog.i(TAG, "Removing system update proc: " + proc); 9615 removeProcessLocked(proc, true, false, "system update done"); 9616 } 9617 } 9618 9619 // Now that we have cleaned up any update processes, we 9620 // are ready to start launching real processes and know that 9621 // we won't trample on them any more. 9622 mProcessesReady = true; 9623 } 9624 9625 Slog.i(TAG, "System now ready"); 9626 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9627 SystemClock.uptimeMillis()); 9628 9629 synchronized(this) { 9630 // Make sure we have no pre-ready processes sitting around. 9631 9632 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9633 ResolveInfo ri = mContext.getPackageManager() 9634 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9635 STOCK_PM_FLAGS); 9636 CharSequence errorMsg = null; 9637 if (ri != null) { 9638 ActivityInfo ai = ri.activityInfo; 9639 ApplicationInfo app = ai.applicationInfo; 9640 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9641 mTopAction = Intent.ACTION_FACTORY_TEST; 9642 mTopData = null; 9643 mTopComponent = new ComponentName(app.packageName, 9644 ai.name); 9645 } else { 9646 errorMsg = mContext.getResources().getText( 9647 com.android.internal.R.string.factorytest_not_system); 9648 } 9649 } else { 9650 errorMsg = mContext.getResources().getText( 9651 com.android.internal.R.string.factorytest_no_action); 9652 } 9653 if (errorMsg != null) { 9654 mTopAction = null; 9655 mTopData = null; 9656 mTopComponent = null; 9657 Message msg = Message.obtain(); 9658 msg.what = SHOW_FACTORY_ERROR_MSG; 9659 msg.getData().putCharSequence("msg", errorMsg); 9660 mHandler.sendMessage(msg); 9661 } 9662 } 9663 } 9664 9665 retrieveSettings(); 9666 9667 synchronized (this) { 9668 readGrantedUriPermissionsLocked(); 9669 } 9670 9671 if (goingCallback != null) goingCallback.run(); 9672 9673 mSystemServiceManager.startUser(mCurrentUserId); 9674 9675 synchronized (this) { 9676 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9677 try { 9678 List apps = AppGlobals.getPackageManager(). 9679 getPersistentApplications(STOCK_PM_FLAGS); 9680 if (apps != null) { 9681 int N = apps.size(); 9682 int i; 9683 for (i=0; i<N; i++) { 9684 ApplicationInfo info 9685 = (ApplicationInfo)apps.get(i); 9686 if (info != null && 9687 !info.packageName.equals("android")) { 9688 addAppLocked(info, false); 9689 } 9690 } 9691 } 9692 } catch (RemoteException ex) { 9693 // pm is in same process, this will never happen. 9694 } 9695 } 9696 9697 // Start up initial activity. 9698 mBooting = true; 9699 9700 try { 9701 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9702 Message msg = Message.obtain(); 9703 msg.what = SHOW_UID_ERROR_MSG; 9704 mHandler.sendMessage(msg); 9705 } 9706 } catch (RemoteException e) { 9707 } 9708 9709 long ident = Binder.clearCallingIdentity(); 9710 try { 9711 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9712 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9713 | Intent.FLAG_RECEIVER_FOREGROUND); 9714 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9715 broadcastIntentLocked(null, null, intent, 9716 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9717 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9718 intent = new Intent(Intent.ACTION_USER_STARTING); 9719 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9720 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9721 broadcastIntentLocked(null, null, intent, 9722 null, new IIntentReceiver.Stub() { 9723 @Override 9724 public void performReceive(Intent intent, int resultCode, String data, 9725 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9726 throws RemoteException { 9727 } 9728 }, 0, null, null, 9729 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9730 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9731 } catch (Throwable t) { 9732 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 9733 } finally { 9734 Binder.restoreCallingIdentity(ident); 9735 } 9736 mStackSupervisor.resumeTopActivitiesLocked(); 9737 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9738 } 9739 } 9740 9741 private boolean makeAppCrashingLocked(ProcessRecord app, 9742 String shortMsg, String longMsg, String stackTrace) { 9743 app.crashing = true; 9744 app.crashingReport = generateProcessError(app, 9745 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9746 startAppProblemLocked(app); 9747 app.stopFreezingAllLocked(); 9748 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9749 } 9750 9751 private void makeAppNotRespondingLocked(ProcessRecord app, 9752 String activity, String shortMsg, String longMsg) { 9753 app.notResponding = true; 9754 app.notRespondingReport = generateProcessError(app, 9755 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9756 activity, shortMsg, longMsg, null); 9757 startAppProblemLocked(app); 9758 app.stopFreezingAllLocked(); 9759 } 9760 9761 /** 9762 * Generate a process error record, suitable for attachment to a ProcessRecord. 9763 * 9764 * @param app The ProcessRecord in which the error occurred. 9765 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9766 * ActivityManager.AppErrorStateInfo 9767 * @param activity The activity associated with the crash, if known. 9768 * @param shortMsg Short message describing the crash. 9769 * @param longMsg Long message describing the crash. 9770 * @param stackTrace Full crash stack trace, may be null. 9771 * 9772 * @return Returns a fully-formed AppErrorStateInfo record. 9773 */ 9774 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9775 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9776 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9777 9778 report.condition = condition; 9779 report.processName = app.processName; 9780 report.pid = app.pid; 9781 report.uid = app.info.uid; 9782 report.tag = activity; 9783 report.shortMsg = shortMsg; 9784 report.longMsg = longMsg; 9785 report.stackTrace = stackTrace; 9786 9787 return report; 9788 } 9789 9790 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9791 synchronized (this) { 9792 app.crashing = false; 9793 app.crashingReport = null; 9794 app.notResponding = false; 9795 app.notRespondingReport = null; 9796 if (app.anrDialog == fromDialog) { 9797 app.anrDialog = null; 9798 } 9799 if (app.waitDialog == fromDialog) { 9800 app.waitDialog = null; 9801 } 9802 if (app.pid > 0 && app.pid != MY_PID) { 9803 handleAppCrashLocked(app, null, null, null); 9804 killUnneededProcessLocked(app, "user request after error"); 9805 } 9806 } 9807 } 9808 9809 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9810 String stackTrace) { 9811 long now = SystemClock.uptimeMillis(); 9812 9813 Long crashTime; 9814 if (!app.isolated) { 9815 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9816 } else { 9817 crashTime = null; 9818 } 9819 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9820 // This process loses! 9821 Slog.w(TAG, "Process " + app.info.processName 9822 + " has crashed too many times: killing!"); 9823 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9824 app.userId, app.info.processName, app.uid); 9825 mStackSupervisor.handleAppCrashLocked(app); 9826 if (!app.persistent) { 9827 // We don't want to start this process again until the user 9828 // explicitly does so... but for persistent process, we really 9829 // need to keep it running. If a persistent process is actually 9830 // repeatedly crashing, then badness for everyone. 9831 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9832 app.info.processName); 9833 if (!app.isolated) { 9834 // XXX We don't have a way to mark isolated processes 9835 // as bad, since they don't have a peristent identity. 9836 mBadProcesses.put(app.info.processName, app.uid, 9837 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9838 mProcessCrashTimes.remove(app.info.processName, app.uid); 9839 } 9840 app.bad = true; 9841 app.removed = true; 9842 // Don't let services in this process be restarted and potentially 9843 // annoy the user repeatedly. Unless it is persistent, since those 9844 // processes run critical code. 9845 removeProcessLocked(app, false, false, "crash"); 9846 mStackSupervisor.resumeTopActivitiesLocked(); 9847 return false; 9848 } 9849 mStackSupervisor.resumeTopActivitiesLocked(); 9850 } else { 9851 mStackSupervisor.finishTopRunningActivityLocked(app); 9852 } 9853 9854 // Bump up the crash count of any services currently running in the proc. 9855 for (int i=app.services.size()-1; i>=0; i--) { 9856 // Any services running in the application need to be placed 9857 // back in the pending list. 9858 ServiceRecord sr = app.services.valueAt(i); 9859 sr.crashCount++; 9860 } 9861 9862 // If the crashing process is what we consider to be the "home process" and it has been 9863 // replaced by a third-party app, clear the package preferred activities from packages 9864 // with a home activity running in the process to prevent a repeatedly crashing app 9865 // from blocking the user to manually clear the list. 9866 final ArrayList<ActivityRecord> activities = app.activities; 9867 if (app == mHomeProcess && activities.size() > 0 9868 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9869 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9870 final ActivityRecord r = activities.get(activityNdx); 9871 if (r.isHomeActivity()) { 9872 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9873 try { 9874 ActivityThread.getPackageManager() 9875 .clearPackagePreferredActivities(r.packageName); 9876 } catch (RemoteException c) { 9877 // pm is in same process, this will never happen. 9878 } 9879 } 9880 } 9881 } 9882 9883 if (!app.isolated) { 9884 // XXX Can't keep track of crash times for isolated processes, 9885 // because they don't have a perisistent identity. 9886 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9887 } 9888 9889 return true; 9890 } 9891 9892 void startAppProblemLocked(ProcessRecord app) { 9893 if (app.userId == mCurrentUserId) { 9894 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9895 mContext, app.info.packageName, app.info.flags); 9896 } else { 9897 // If this app is not running under the current user, then we 9898 // can't give it a report button because that would require 9899 // launching the report UI under a different user. 9900 app.errorReportReceiver = null; 9901 } 9902 skipCurrentReceiverLocked(app); 9903 } 9904 9905 void skipCurrentReceiverLocked(ProcessRecord app) { 9906 for (BroadcastQueue queue : mBroadcastQueues) { 9907 queue.skipCurrentReceiverLocked(app); 9908 } 9909 } 9910 9911 /** 9912 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9913 * The application process will exit immediately after this call returns. 9914 * @param app object of the crashing app, null for the system server 9915 * @param crashInfo describing the exception 9916 */ 9917 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9918 ProcessRecord r = findAppProcess(app, "Crash"); 9919 final String processName = app == null ? "system_server" 9920 : (r == null ? "unknown" : r.processName); 9921 9922 handleApplicationCrashInner("crash", r, processName, crashInfo); 9923 } 9924 9925 /* Native crash reporting uses this inner version because it needs to be somewhat 9926 * decoupled from the AM-managed cleanup lifecycle 9927 */ 9928 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9929 ApplicationErrorReport.CrashInfo crashInfo) { 9930 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9931 UserHandle.getUserId(Binder.getCallingUid()), processName, 9932 r == null ? -1 : r.info.flags, 9933 crashInfo.exceptionClassName, 9934 crashInfo.exceptionMessage, 9935 crashInfo.throwFileName, 9936 crashInfo.throwLineNumber); 9937 9938 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9939 9940 crashApplication(r, crashInfo); 9941 } 9942 9943 public void handleApplicationStrictModeViolation( 9944 IBinder app, 9945 int violationMask, 9946 StrictMode.ViolationInfo info) { 9947 ProcessRecord r = findAppProcess(app, "StrictMode"); 9948 if (r == null) { 9949 return; 9950 } 9951 9952 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9953 Integer stackFingerprint = info.hashCode(); 9954 boolean logIt = true; 9955 synchronized (mAlreadyLoggedViolatedStacks) { 9956 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9957 logIt = false; 9958 // TODO: sub-sample into EventLog for these, with 9959 // the info.durationMillis? Then we'd get 9960 // the relative pain numbers, without logging all 9961 // the stack traces repeatedly. We'd want to do 9962 // likewise in the client code, which also does 9963 // dup suppression, before the Binder call. 9964 } else { 9965 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9966 mAlreadyLoggedViolatedStacks.clear(); 9967 } 9968 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9969 } 9970 } 9971 if (logIt) { 9972 logStrictModeViolationToDropBox(r, info); 9973 } 9974 } 9975 9976 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9977 AppErrorResult result = new AppErrorResult(); 9978 synchronized (this) { 9979 final long origId = Binder.clearCallingIdentity(); 9980 9981 Message msg = Message.obtain(); 9982 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9983 HashMap<String, Object> data = new HashMap<String, Object>(); 9984 data.put("result", result); 9985 data.put("app", r); 9986 data.put("violationMask", violationMask); 9987 data.put("info", info); 9988 msg.obj = data; 9989 mHandler.sendMessage(msg); 9990 9991 Binder.restoreCallingIdentity(origId); 9992 } 9993 int res = result.get(); 9994 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9995 } 9996 } 9997 9998 // Depending on the policy in effect, there could be a bunch of 9999 // these in quick succession so we try to batch these together to 10000 // minimize disk writes, number of dropbox entries, and maximize 10001 // compression, by having more fewer, larger records. 10002 private void logStrictModeViolationToDropBox( 10003 ProcessRecord process, 10004 StrictMode.ViolationInfo info) { 10005 if (info == null) { 10006 return; 10007 } 10008 final boolean isSystemApp = process == null || 10009 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10010 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10011 final String processName = process == null ? "unknown" : process.processName; 10012 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10013 final DropBoxManager dbox = (DropBoxManager) 10014 mContext.getSystemService(Context.DROPBOX_SERVICE); 10015 10016 // Exit early if the dropbox isn't configured to accept this report type. 10017 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10018 10019 boolean bufferWasEmpty; 10020 boolean needsFlush; 10021 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10022 synchronized (sb) { 10023 bufferWasEmpty = sb.length() == 0; 10024 appendDropBoxProcessHeaders(process, processName, sb); 10025 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10026 sb.append("System-App: ").append(isSystemApp).append("\n"); 10027 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10028 if (info.violationNumThisLoop != 0) { 10029 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10030 } 10031 if (info.numAnimationsRunning != 0) { 10032 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10033 } 10034 if (info.broadcastIntentAction != null) { 10035 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10036 } 10037 if (info.durationMillis != -1) { 10038 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10039 } 10040 if (info.numInstances != -1) { 10041 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10042 } 10043 if (info.tags != null) { 10044 for (String tag : info.tags) { 10045 sb.append("Span-Tag: ").append(tag).append("\n"); 10046 } 10047 } 10048 sb.append("\n"); 10049 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10050 sb.append(info.crashInfo.stackTrace); 10051 } 10052 sb.append("\n"); 10053 10054 // Only buffer up to ~64k. Various logging bits truncate 10055 // things at 128k. 10056 needsFlush = (sb.length() > 64 * 1024); 10057 } 10058 10059 // Flush immediately if the buffer's grown too large, or this 10060 // is a non-system app. Non-system apps are isolated with a 10061 // different tag & policy and not batched. 10062 // 10063 // Batching is useful during internal testing with 10064 // StrictMode settings turned up high. Without batching, 10065 // thousands of separate files could be created on boot. 10066 if (!isSystemApp || needsFlush) { 10067 new Thread("Error dump: " + dropboxTag) { 10068 @Override 10069 public void run() { 10070 String report; 10071 synchronized (sb) { 10072 report = sb.toString(); 10073 sb.delete(0, sb.length()); 10074 sb.trimToSize(); 10075 } 10076 if (report.length() != 0) { 10077 dbox.addText(dropboxTag, report); 10078 } 10079 } 10080 }.start(); 10081 return; 10082 } 10083 10084 // System app batching: 10085 if (!bufferWasEmpty) { 10086 // An existing dropbox-writing thread is outstanding, so 10087 // we don't need to start it up. The existing thread will 10088 // catch the buffer appends we just did. 10089 return; 10090 } 10091 10092 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10093 // (After this point, we shouldn't access AMS internal data structures.) 10094 new Thread("Error dump: " + dropboxTag) { 10095 @Override 10096 public void run() { 10097 // 5 second sleep to let stacks arrive and be batched together 10098 try { 10099 Thread.sleep(5000); // 5 seconds 10100 } catch (InterruptedException e) {} 10101 10102 String errorReport; 10103 synchronized (mStrictModeBuffer) { 10104 errorReport = mStrictModeBuffer.toString(); 10105 if (errorReport.length() == 0) { 10106 return; 10107 } 10108 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10109 mStrictModeBuffer.trimToSize(); 10110 } 10111 dbox.addText(dropboxTag, errorReport); 10112 } 10113 }.start(); 10114 } 10115 10116 /** 10117 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10118 * @param app object of the crashing app, null for the system server 10119 * @param tag reported by the caller 10120 * @param crashInfo describing the context of the error 10121 * @return true if the process should exit immediately (WTF is fatal) 10122 */ 10123 public boolean handleApplicationWtf(IBinder app, String tag, 10124 ApplicationErrorReport.CrashInfo crashInfo) { 10125 ProcessRecord r = findAppProcess(app, "WTF"); 10126 final String processName = app == null ? "system_server" 10127 : (r == null ? "unknown" : r.processName); 10128 10129 EventLog.writeEvent(EventLogTags.AM_WTF, 10130 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10131 processName, 10132 r == null ? -1 : r.info.flags, 10133 tag, crashInfo.exceptionMessage); 10134 10135 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10136 10137 if (r != null && r.pid != Process.myPid() && 10138 Settings.Global.getInt(mContext.getContentResolver(), 10139 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10140 crashApplication(r, crashInfo); 10141 return true; 10142 } else { 10143 return false; 10144 } 10145 } 10146 10147 /** 10148 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10149 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10150 */ 10151 private ProcessRecord findAppProcess(IBinder app, String reason) { 10152 if (app == null) { 10153 return null; 10154 } 10155 10156 synchronized (this) { 10157 final int NP = mProcessNames.getMap().size(); 10158 for (int ip=0; ip<NP; ip++) { 10159 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10160 final int NA = apps.size(); 10161 for (int ia=0; ia<NA; ia++) { 10162 ProcessRecord p = apps.valueAt(ia); 10163 if (p.thread != null && p.thread.asBinder() == app) { 10164 return p; 10165 } 10166 } 10167 } 10168 10169 Slog.w(TAG, "Can't find mystery application for " + reason 10170 + " from pid=" + Binder.getCallingPid() 10171 + " uid=" + Binder.getCallingUid() + ": " + app); 10172 return null; 10173 } 10174 } 10175 10176 /** 10177 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10178 * to append various headers to the dropbox log text. 10179 */ 10180 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10181 StringBuilder sb) { 10182 // Watchdog thread ends up invoking this function (with 10183 // a null ProcessRecord) to add the stack file to dropbox. 10184 // Do not acquire a lock on this (am) in such cases, as it 10185 // could cause a potential deadlock, if and when watchdog 10186 // is invoked due to unavailability of lock on am and it 10187 // would prevent watchdog from killing system_server. 10188 if (process == null) { 10189 sb.append("Process: ").append(processName).append("\n"); 10190 return; 10191 } 10192 // Note: ProcessRecord 'process' is guarded by the service 10193 // instance. (notably process.pkgList, which could otherwise change 10194 // concurrently during execution of this method) 10195 synchronized (this) { 10196 sb.append("Process: ").append(processName).append("\n"); 10197 int flags = process.info.flags; 10198 IPackageManager pm = AppGlobals.getPackageManager(); 10199 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10200 for (int ip=0; ip<process.pkgList.size(); ip++) { 10201 String pkg = process.pkgList.keyAt(ip); 10202 sb.append("Package: ").append(pkg); 10203 try { 10204 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10205 if (pi != null) { 10206 sb.append(" v").append(pi.versionCode); 10207 if (pi.versionName != null) { 10208 sb.append(" (").append(pi.versionName).append(")"); 10209 } 10210 } 10211 } catch (RemoteException e) { 10212 Slog.e(TAG, "Error getting package info: " + pkg, e); 10213 } 10214 sb.append("\n"); 10215 } 10216 } 10217 } 10218 10219 private static String processClass(ProcessRecord process) { 10220 if (process == null || process.pid == MY_PID) { 10221 return "system_server"; 10222 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10223 return "system_app"; 10224 } else { 10225 return "data_app"; 10226 } 10227 } 10228 10229 /** 10230 * Write a description of an error (crash, WTF, ANR) to the drop box. 10231 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10232 * @param process which caused the error, null means the system server 10233 * @param activity which triggered the error, null if unknown 10234 * @param parent activity related to the error, null if unknown 10235 * @param subject line related to the error, null if absent 10236 * @param report in long form describing the error, null if absent 10237 * @param logFile to include in the report, null if none 10238 * @param crashInfo giving an application stack trace, null if absent 10239 */ 10240 public void addErrorToDropBox(String eventType, 10241 ProcessRecord process, String processName, ActivityRecord activity, 10242 ActivityRecord parent, String subject, 10243 final String report, final File logFile, 10244 final ApplicationErrorReport.CrashInfo crashInfo) { 10245 // NOTE -- this must never acquire the ActivityManagerService lock, 10246 // otherwise the watchdog may be prevented from resetting the system. 10247 10248 final String dropboxTag = processClass(process) + "_" + eventType; 10249 final DropBoxManager dbox = (DropBoxManager) 10250 mContext.getSystemService(Context.DROPBOX_SERVICE); 10251 10252 // Exit early if the dropbox isn't configured to accept this report type. 10253 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10254 10255 final StringBuilder sb = new StringBuilder(1024); 10256 appendDropBoxProcessHeaders(process, processName, sb); 10257 if (activity != null) { 10258 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10259 } 10260 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10261 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10262 } 10263 if (parent != null && parent != activity) { 10264 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10265 } 10266 if (subject != null) { 10267 sb.append("Subject: ").append(subject).append("\n"); 10268 } 10269 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10270 if (Debug.isDebuggerConnected()) { 10271 sb.append("Debugger: Connected\n"); 10272 } 10273 sb.append("\n"); 10274 10275 // Do the rest in a worker thread to avoid blocking the caller on I/O 10276 // (After this point, we shouldn't access AMS internal data structures.) 10277 Thread worker = new Thread("Error dump: " + dropboxTag) { 10278 @Override 10279 public void run() { 10280 if (report != null) { 10281 sb.append(report); 10282 } 10283 if (logFile != null) { 10284 try { 10285 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10286 "\n\n[[TRUNCATED]]")); 10287 } catch (IOException e) { 10288 Slog.e(TAG, "Error reading " + logFile, e); 10289 } 10290 } 10291 if (crashInfo != null && crashInfo.stackTrace != null) { 10292 sb.append(crashInfo.stackTrace); 10293 } 10294 10295 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10296 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10297 if (lines > 0) { 10298 sb.append("\n"); 10299 10300 // Merge several logcat streams, and take the last N lines 10301 InputStreamReader input = null; 10302 try { 10303 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10304 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10305 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10306 10307 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10308 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10309 input = new InputStreamReader(logcat.getInputStream()); 10310 10311 int num; 10312 char[] buf = new char[8192]; 10313 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10314 } catch (IOException e) { 10315 Slog.e(TAG, "Error running logcat", e); 10316 } finally { 10317 if (input != null) try { input.close(); } catch (IOException e) {} 10318 } 10319 } 10320 10321 dbox.addText(dropboxTag, sb.toString()); 10322 } 10323 }; 10324 10325 if (process == null) { 10326 // If process is null, we are being called from some internal code 10327 // and may be about to die -- run this synchronously. 10328 worker.run(); 10329 } else { 10330 worker.start(); 10331 } 10332 } 10333 10334 /** 10335 * Bring up the "unexpected error" dialog box for a crashing app. 10336 * Deal with edge cases (intercepts from instrumented applications, 10337 * ActivityController, error intent receivers, that sort of thing). 10338 * @param r the application crashing 10339 * @param crashInfo describing the failure 10340 */ 10341 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10342 long timeMillis = System.currentTimeMillis(); 10343 String shortMsg = crashInfo.exceptionClassName; 10344 String longMsg = crashInfo.exceptionMessage; 10345 String stackTrace = crashInfo.stackTrace; 10346 if (shortMsg != null && longMsg != null) { 10347 longMsg = shortMsg + ": " + longMsg; 10348 } else if (shortMsg != null) { 10349 longMsg = shortMsg; 10350 } 10351 10352 AppErrorResult result = new AppErrorResult(); 10353 synchronized (this) { 10354 if (mController != null) { 10355 try { 10356 String name = r != null ? r.processName : null; 10357 int pid = r != null ? r.pid : Binder.getCallingPid(); 10358 if (!mController.appCrashed(name, pid, 10359 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10360 Slog.w(TAG, "Force-killing crashed app " + name 10361 + " at watcher's request"); 10362 Process.killProcess(pid); 10363 return; 10364 } 10365 } catch (RemoteException e) { 10366 mController = null; 10367 Watchdog.getInstance().setActivityController(null); 10368 } 10369 } 10370 10371 final long origId = Binder.clearCallingIdentity(); 10372 10373 // If this process is running instrumentation, finish it. 10374 if (r != null && r.instrumentationClass != null) { 10375 Slog.w(TAG, "Error in app " + r.processName 10376 + " running instrumentation " + r.instrumentationClass + ":"); 10377 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10378 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10379 Bundle info = new Bundle(); 10380 info.putString("shortMsg", shortMsg); 10381 info.putString("longMsg", longMsg); 10382 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10383 Binder.restoreCallingIdentity(origId); 10384 return; 10385 } 10386 10387 // If we can't identify the process or it's already exceeded its crash quota, 10388 // quit right away without showing a crash dialog. 10389 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10390 Binder.restoreCallingIdentity(origId); 10391 return; 10392 } 10393 10394 Message msg = Message.obtain(); 10395 msg.what = SHOW_ERROR_MSG; 10396 HashMap data = new HashMap(); 10397 data.put("result", result); 10398 data.put("app", r); 10399 msg.obj = data; 10400 mHandler.sendMessage(msg); 10401 10402 Binder.restoreCallingIdentity(origId); 10403 } 10404 10405 int res = result.get(); 10406 10407 Intent appErrorIntent = null; 10408 synchronized (this) { 10409 if (r != null && !r.isolated) { 10410 // XXX Can't keep track of crash time for isolated processes, 10411 // since they don't have a persistent identity. 10412 mProcessCrashTimes.put(r.info.processName, r.uid, 10413 SystemClock.uptimeMillis()); 10414 } 10415 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10416 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10417 } 10418 } 10419 10420 if (appErrorIntent != null) { 10421 try { 10422 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10423 } catch (ActivityNotFoundException e) { 10424 Slog.w(TAG, "bug report receiver dissappeared", e); 10425 } 10426 } 10427 } 10428 10429 Intent createAppErrorIntentLocked(ProcessRecord r, 10430 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10431 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10432 if (report == null) { 10433 return null; 10434 } 10435 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10436 result.setComponent(r.errorReportReceiver); 10437 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10438 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10439 return result; 10440 } 10441 10442 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10443 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10444 if (r.errorReportReceiver == null) { 10445 return null; 10446 } 10447 10448 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10449 return null; 10450 } 10451 10452 ApplicationErrorReport report = new ApplicationErrorReport(); 10453 report.packageName = r.info.packageName; 10454 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10455 report.processName = r.processName; 10456 report.time = timeMillis; 10457 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10458 10459 if (r.crashing || r.forceCrashReport) { 10460 report.type = ApplicationErrorReport.TYPE_CRASH; 10461 report.crashInfo = crashInfo; 10462 } else if (r.notResponding) { 10463 report.type = ApplicationErrorReport.TYPE_ANR; 10464 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10465 10466 report.anrInfo.activity = r.notRespondingReport.tag; 10467 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10468 report.anrInfo.info = r.notRespondingReport.longMsg; 10469 } 10470 10471 return report; 10472 } 10473 10474 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10475 enforceNotIsolatedCaller("getProcessesInErrorState"); 10476 // assume our apps are happy - lazy create the list 10477 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10478 10479 final boolean allUsers = ActivityManager.checkUidPermission( 10480 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10481 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10482 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10483 10484 synchronized (this) { 10485 10486 // iterate across all processes 10487 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10488 ProcessRecord app = mLruProcesses.get(i); 10489 if (!allUsers && app.userId != userId) { 10490 continue; 10491 } 10492 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10493 // This one's in trouble, so we'll generate a report for it 10494 // crashes are higher priority (in case there's a crash *and* an anr) 10495 ActivityManager.ProcessErrorStateInfo report = null; 10496 if (app.crashing) { 10497 report = app.crashingReport; 10498 } else if (app.notResponding) { 10499 report = app.notRespondingReport; 10500 } 10501 10502 if (report != null) { 10503 if (errList == null) { 10504 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10505 } 10506 errList.add(report); 10507 } else { 10508 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10509 " crashing = " + app.crashing + 10510 " notResponding = " + app.notResponding); 10511 } 10512 } 10513 } 10514 } 10515 10516 return errList; 10517 } 10518 10519 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10520 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10521 if (currApp != null) { 10522 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10523 } 10524 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10525 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10526 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10527 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10528 if (currApp != null) { 10529 currApp.lru = 0; 10530 } 10531 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10532 } else if (adj >= ProcessList.SERVICE_ADJ) { 10533 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10534 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10535 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10536 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10537 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10538 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10539 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10540 } else { 10541 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10542 } 10543 } 10544 10545 private void fillInProcMemInfo(ProcessRecord app, 10546 ActivityManager.RunningAppProcessInfo outInfo) { 10547 outInfo.pid = app.pid; 10548 outInfo.uid = app.info.uid; 10549 if (mHeavyWeightProcess == app) { 10550 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10551 } 10552 if (app.persistent) { 10553 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10554 } 10555 if (app.activities.size() > 0) { 10556 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10557 } 10558 outInfo.lastTrimLevel = app.trimMemoryLevel; 10559 int adj = app.curAdj; 10560 outInfo.importance = oomAdjToImportance(adj, outInfo); 10561 outInfo.importanceReasonCode = app.adjTypeCode; 10562 outInfo.processState = app.curProcState; 10563 } 10564 10565 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10566 enforceNotIsolatedCaller("getRunningAppProcesses"); 10567 // Lazy instantiation of list 10568 List<ActivityManager.RunningAppProcessInfo> runList = null; 10569 final boolean allUsers = ActivityManager.checkUidPermission( 10570 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10571 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10572 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10573 synchronized (this) { 10574 // Iterate across all processes 10575 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10576 ProcessRecord app = mLruProcesses.get(i); 10577 if (!allUsers && app.userId != userId) { 10578 continue; 10579 } 10580 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10581 // Generate process state info for running application 10582 ActivityManager.RunningAppProcessInfo currApp = 10583 new ActivityManager.RunningAppProcessInfo(app.processName, 10584 app.pid, app.getPackageList()); 10585 fillInProcMemInfo(app, currApp); 10586 if (app.adjSource instanceof ProcessRecord) { 10587 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10588 currApp.importanceReasonImportance = oomAdjToImportance( 10589 app.adjSourceOom, null); 10590 } else if (app.adjSource instanceof ActivityRecord) { 10591 ActivityRecord r = (ActivityRecord)app.adjSource; 10592 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10593 } 10594 if (app.adjTarget instanceof ComponentName) { 10595 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10596 } 10597 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10598 // + " lru=" + currApp.lru); 10599 if (runList == null) { 10600 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10601 } 10602 runList.add(currApp); 10603 } 10604 } 10605 } 10606 return runList; 10607 } 10608 10609 public List<ApplicationInfo> getRunningExternalApplications() { 10610 enforceNotIsolatedCaller("getRunningExternalApplications"); 10611 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10612 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10613 if (runningApps != null && runningApps.size() > 0) { 10614 Set<String> extList = new HashSet<String>(); 10615 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10616 if (app.pkgList != null) { 10617 for (String pkg : app.pkgList) { 10618 extList.add(pkg); 10619 } 10620 } 10621 } 10622 IPackageManager pm = AppGlobals.getPackageManager(); 10623 for (String pkg : extList) { 10624 try { 10625 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10626 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10627 retList.add(info); 10628 } 10629 } catch (RemoteException e) { 10630 } 10631 } 10632 } 10633 return retList; 10634 } 10635 10636 @Override 10637 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10638 enforceNotIsolatedCaller("getMyMemoryState"); 10639 synchronized (this) { 10640 ProcessRecord proc; 10641 synchronized (mPidsSelfLocked) { 10642 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10643 } 10644 fillInProcMemInfo(proc, outInfo); 10645 } 10646 } 10647 10648 @Override 10649 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10650 if (checkCallingPermission(android.Manifest.permission.DUMP) 10651 != PackageManager.PERMISSION_GRANTED) { 10652 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10653 + Binder.getCallingPid() 10654 + ", uid=" + Binder.getCallingUid() 10655 + " without permission " 10656 + android.Manifest.permission.DUMP); 10657 return; 10658 } 10659 10660 boolean dumpAll = false; 10661 boolean dumpClient = false; 10662 String dumpPackage = null; 10663 10664 int opti = 0; 10665 while (opti < args.length) { 10666 String opt = args[opti]; 10667 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10668 break; 10669 } 10670 opti++; 10671 if ("-a".equals(opt)) { 10672 dumpAll = true; 10673 } else if ("-c".equals(opt)) { 10674 dumpClient = true; 10675 } else if ("-h".equals(opt)) { 10676 pw.println("Activity manager dump options:"); 10677 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10678 pw.println(" cmd may be one of:"); 10679 pw.println(" a[ctivities]: activity stack state"); 10680 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10681 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10682 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10683 pw.println(" o[om]: out of memory management"); 10684 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10685 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10686 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10687 pw.println(" service [COMP_SPEC]: service client-side state"); 10688 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10689 pw.println(" all: dump all activities"); 10690 pw.println(" top: dump the top activity"); 10691 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10692 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10693 pw.println(" a partial substring in a component name, a"); 10694 pw.println(" hex object identifier."); 10695 pw.println(" -a: include all available server state."); 10696 pw.println(" -c: include client state."); 10697 return; 10698 } else { 10699 pw.println("Unknown argument: " + opt + "; use -h for help"); 10700 } 10701 } 10702 10703 long origId = Binder.clearCallingIdentity(); 10704 boolean more = false; 10705 // Is the caller requesting to dump a particular piece of data? 10706 if (opti < args.length) { 10707 String cmd = args[opti]; 10708 opti++; 10709 if ("activities".equals(cmd) || "a".equals(cmd)) { 10710 synchronized (this) { 10711 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10712 } 10713 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10714 String[] newArgs; 10715 String name; 10716 if (opti >= args.length) { 10717 name = null; 10718 newArgs = EMPTY_STRING_ARRAY; 10719 } else { 10720 name = args[opti]; 10721 opti++; 10722 newArgs = new String[args.length - opti]; 10723 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10724 args.length - opti); 10725 } 10726 synchronized (this) { 10727 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10728 } 10729 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10730 String[] newArgs; 10731 String name; 10732 if (opti >= args.length) { 10733 name = null; 10734 newArgs = EMPTY_STRING_ARRAY; 10735 } else { 10736 name = args[opti]; 10737 opti++; 10738 newArgs = new String[args.length - opti]; 10739 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10740 args.length - opti); 10741 } 10742 synchronized (this) { 10743 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10744 } 10745 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10746 String[] newArgs; 10747 String name; 10748 if (opti >= args.length) { 10749 name = null; 10750 newArgs = EMPTY_STRING_ARRAY; 10751 } else { 10752 name = args[opti]; 10753 opti++; 10754 newArgs = new String[args.length - opti]; 10755 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10756 args.length - opti); 10757 } 10758 synchronized (this) { 10759 dumpProcessesLocked(fd, pw, args, opti, true, name); 10760 } 10761 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10762 synchronized (this) { 10763 dumpOomLocked(fd, pw, args, opti, true); 10764 } 10765 } else if ("provider".equals(cmd)) { 10766 String[] newArgs; 10767 String name; 10768 if (opti >= args.length) { 10769 name = null; 10770 newArgs = EMPTY_STRING_ARRAY; 10771 } else { 10772 name = args[opti]; 10773 opti++; 10774 newArgs = new String[args.length - opti]; 10775 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10776 } 10777 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10778 pw.println("No providers match: " + name); 10779 pw.println("Use -h for help."); 10780 } 10781 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10782 synchronized (this) { 10783 dumpProvidersLocked(fd, pw, args, opti, true, null); 10784 } 10785 } else if ("service".equals(cmd)) { 10786 String[] newArgs; 10787 String name; 10788 if (opti >= args.length) { 10789 name = null; 10790 newArgs = EMPTY_STRING_ARRAY; 10791 } else { 10792 name = args[opti]; 10793 opti++; 10794 newArgs = new String[args.length - opti]; 10795 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10796 args.length - opti); 10797 } 10798 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10799 pw.println("No services match: " + name); 10800 pw.println("Use -h for help."); 10801 } 10802 } else if ("package".equals(cmd)) { 10803 String[] newArgs; 10804 if (opti >= args.length) { 10805 pw.println("package: no package name specified"); 10806 pw.println("Use -h for help."); 10807 } else { 10808 dumpPackage = args[opti]; 10809 opti++; 10810 newArgs = new String[args.length - opti]; 10811 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10812 args.length - opti); 10813 args = newArgs; 10814 opti = 0; 10815 more = true; 10816 } 10817 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10818 synchronized (this) { 10819 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10820 } 10821 } else { 10822 // Dumping a single activity? 10823 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10824 pw.println("Bad activity command, or no activities match: " + cmd); 10825 pw.println("Use -h for help."); 10826 } 10827 } 10828 if (!more) { 10829 Binder.restoreCallingIdentity(origId); 10830 return; 10831 } 10832 } 10833 10834 // No piece of data specified, dump everything. 10835 synchronized (this) { 10836 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10837 pw.println(); 10838 if (dumpAll) { 10839 pw.println("-------------------------------------------------------------------------------"); 10840 } 10841 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10842 pw.println(); 10843 if (dumpAll) { 10844 pw.println("-------------------------------------------------------------------------------"); 10845 } 10846 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10847 pw.println(); 10848 if (dumpAll) { 10849 pw.println("-------------------------------------------------------------------------------"); 10850 } 10851 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10852 pw.println(); 10853 if (dumpAll) { 10854 pw.println("-------------------------------------------------------------------------------"); 10855 } 10856 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10857 pw.println(); 10858 if (dumpAll) { 10859 pw.println("-------------------------------------------------------------------------------"); 10860 } 10861 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10862 } 10863 Binder.restoreCallingIdentity(origId); 10864 } 10865 10866 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10867 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10868 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10869 10870 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10871 dumpPackage); 10872 boolean needSep = printedAnything; 10873 10874 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10875 dumpPackage, needSep, " mFocusedActivity: "); 10876 if (printed) { 10877 printedAnything = true; 10878 needSep = false; 10879 } 10880 10881 if (dumpPackage == null) { 10882 if (needSep) { 10883 pw.println(); 10884 } 10885 needSep = true; 10886 printedAnything = true; 10887 mStackSupervisor.dump(pw, " "); 10888 } 10889 10890 if (mRecentTasks.size() > 0) { 10891 boolean printedHeader = false; 10892 10893 final int N = mRecentTasks.size(); 10894 for (int i=0; i<N; i++) { 10895 TaskRecord tr = mRecentTasks.get(i); 10896 if (dumpPackage != null) { 10897 if (tr.realActivity == null || 10898 !dumpPackage.equals(tr.realActivity)) { 10899 continue; 10900 } 10901 } 10902 if (!printedHeader) { 10903 if (needSep) { 10904 pw.println(); 10905 } 10906 pw.println(" Recent tasks:"); 10907 printedHeader = true; 10908 printedAnything = true; 10909 } 10910 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10911 pw.println(tr); 10912 if (dumpAll) { 10913 mRecentTasks.get(i).dump(pw, " "); 10914 } 10915 } 10916 } 10917 10918 if (!printedAnything) { 10919 pw.println(" (nothing)"); 10920 } 10921 } 10922 10923 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10924 int opti, boolean dumpAll, String dumpPackage) { 10925 boolean needSep = false; 10926 boolean printedAnything = false; 10927 int numPers = 0; 10928 10929 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10930 10931 if (dumpAll) { 10932 final int NP = mProcessNames.getMap().size(); 10933 for (int ip=0; ip<NP; ip++) { 10934 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10935 final int NA = procs.size(); 10936 for (int ia=0; ia<NA; ia++) { 10937 ProcessRecord r = procs.valueAt(ia); 10938 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10939 continue; 10940 } 10941 if (!needSep) { 10942 pw.println(" All known processes:"); 10943 needSep = true; 10944 printedAnything = true; 10945 } 10946 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10947 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10948 pw.print(" "); pw.println(r); 10949 r.dump(pw, " "); 10950 if (r.persistent) { 10951 numPers++; 10952 } 10953 } 10954 } 10955 } 10956 10957 if (mIsolatedProcesses.size() > 0) { 10958 boolean printed = false; 10959 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10960 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10961 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10962 continue; 10963 } 10964 if (!printed) { 10965 if (needSep) { 10966 pw.println(); 10967 } 10968 pw.println(" Isolated process list (sorted by uid):"); 10969 printedAnything = true; 10970 printed = true; 10971 needSep = true; 10972 } 10973 pw.println(String.format("%sIsolated #%2d: %s", 10974 " ", i, r.toString())); 10975 } 10976 } 10977 10978 if (mLruProcesses.size() > 0) { 10979 if (needSep) { 10980 pw.println(); 10981 } 10982 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10983 pw.print(" total, non-act at "); 10984 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10985 pw.print(", non-svc at "); 10986 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10987 pw.println("):"); 10988 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10989 needSep = true; 10990 printedAnything = true; 10991 } 10992 10993 if (dumpAll || dumpPackage != null) { 10994 synchronized (mPidsSelfLocked) { 10995 boolean printed = false; 10996 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10997 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10998 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10999 continue; 11000 } 11001 if (!printed) { 11002 if (needSep) pw.println(); 11003 needSep = true; 11004 pw.println(" PID mappings:"); 11005 printed = true; 11006 printedAnything = true; 11007 } 11008 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11009 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11010 } 11011 } 11012 } 11013 11014 if (mForegroundProcesses.size() > 0) { 11015 synchronized (mPidsSelfLocked) { 11016 boolean printed = false; 11017 for (int i=0; i<mForegroundProcesses.size(); i++) { 11018 ProcessRecord r = mPidsSelfLocked.get( 11019 mForegroundProcesses.valueAt(i).pid); 11020 if (dumpPackage != null && (r == null 11021 || !r.pkgList.containsKey(dumpPackage))) { 11022 continue; 11023 } 11024 if (!printed) { 11025 if (needSep) pw.println(); 11026 needSep = true; 11027 pw.println(" Foreground Processes:"); 11028 printed = true; 11029 printedAnything = true; 11030 } 11031 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11032 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11033 } 11034 } 11035 } 11036 11037 if (mPersistentStartingProcesses.size() > 0) { 11038 if (needSep) pw.println(); 11039 needSep = true; 11040 printedAnything = true; 11041 pw.println(" Persisent processes that are starting:"); 11042 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11043 "Starting Norm", "Restarting PERS", dumpPackage); 11044 } 11045 11046 if (mRemovedProcesses.size() > 0) { 11047 if (needSep) pw.println(); 11048 needSep = true; 11049 printedAnything = true; 11050 pw.println(" Processes that are being removed:"); 11051 dumpProcessList(pw, this, mRemovedProcesses, " ", 11052 "Removed Norm", "Removed PERS", dumpPackage); 11053 } 11054 11055 if (mProcessesOnHold.size() > 0) { 11056 if (needSep) pw.println(); 11057 needSep = true; 11058 printedAnything = true; 11059 pw.println(" Processes that are on old until the system is ready:"); 11060 dumpProcessList(pw, this, mProcessesOnHold, " ", 11061 "OnHold Norm", "OnHold PERS", dumpPackage); 11062 } 11063 11064 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11065 11066 if (mProcessCrashTimes.getMap().size() > 0) { 11067 boolean printed = false; 11068 long now = SystemClock.uptimeMillis(); 11069 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11070 final int NP = pmap.size(); 11071 for (int ip=0; ip<NP; ip++) { 11072 String pname = pmap.keyAt(ip); 11073 SparseArray<Long> uids = pmap.valueAt(ip); 11074 final int N = uids.size(); 11075 for (int i=0; i<N; i++) { 11076 int puid = uids.keyAt(i); 11077 ProcessRecord r = mProcessNames.get(pname, puid); 11078 if (dumpPackage != null && (r == null 11079 || !r.pkgList.containsKey(dumpPackage))) { 11080 continue; 11081 } 11082 if (!printed) { 11083 if (needSep) pw.println(); 11084 needSep = true; 11085 pw.println(" Time since processes crashed:"); 11086 printed = true; 11087 printedAnything = true; 11088 } 11089 pw.print(" Process "); pw.print(pname); 11090 pw.print(" uid "); pw.print(puid); 11091 pw.print(": last crashed "); 11092 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11093 pw.println(" ago"); 11094 } 11095 } 11096 } 11097 11098 if (mBadProcesses.getMap().size() > 0) { 11099 boolean printed = false; 11100 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11101 final int NP = pmap.size(); 11102 for (int ip=0; ip<NP; ip++) { 11103 String pname = pmap.keyAt(ip); 11104 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11105 final int N = uids.size(); 11106 for (int i=0; i<N; i++) { 11107 int puid = uids.keyAt(i); 11108 ProcessRecord r = mProcessNames.get(pname, puid); 11109 if (dumpPackage != null && (r == null 11110 || !r.pkgList.containsKey(dumpPackage))) { 11111 continue; 11112 } 11113 if (!printed) { 11114 if (needSep) pw.println(); 11115 needSep = true; 11116 pw.println(" Bad processes:"); 11117 printedAnything = true; 11118 } 11119 BadProcessInfo info = uids.valueAt(i); 11120 pw.print(" Bad process "); pw.print(pname); 11121 pw.print(" uid "); pw.print(puid); 11122 pw.print(": crashed at time "); pw.println(info.time); 11123 if (info.shortMsg != null) { 11124 pw.print(" Short msg: "); pw.println(info.shortMsg); 11125 } 11126 if (info.longMsg != null) { 11127 pw.print(" Long msg: "); pw.println(info.longMsg); 11128 } 11129 if (info.stack != null) { 11130 pw.println(" Stack:"); 11131 int lastPos = 0; 11132 for (int pos=0; pos<info.stack.length(); pos++) { 11133 if (info.stack.charAt(pos) == '\n') { 11134 pw.print(" "); 11135 pw.write(info.stack, lastPos, pos-lastPos); 11136 pw.println(); 11137 lastPos = pos+1; 11138 } 11139 } 11140 if (lastPos < info.stack.length()) { 11141 pw.print(" "); 11142 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11143 pw.println(); 11144 } 11145 } 11146 } 11147 } 11148 } 11149 11150 if (dumpPackage == null) { 11151 pw.println(); 11152 needSep = false; 11153 pw.println(" mStartedUsers:"); 11154 for (int i=0; i<mStartedUsers.size(); i++) { 11155 UserStartedState uss = mStartedUsers.valueAt(i); 11156 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11157 pw.print(": "); uss.dump("", pw); 11158 } 11159 pw.print(" mStartedUserArray: ["); 11160 for (int i=0; i<mStartedUserArray.length; i++) { 11161 if (i > 0) pw.print(", "); 11162 pw.print(mStartedUserArray[i]); 11163 } 11164 pw.println("]"); 11165 pw.print(" mUserLru: ["); 11166 for (int i=0; i<mUserLru.size(); i++) { 11167 if (i > 0) pw.print(", "); 11168 pw.print(mUserLru.get(i)); 11169 } 11170 pw.println("]"); 11171 if (dumpAll) { 11172 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11173 } 11174 } 11175 if (mHomeProcess != null && (dumpPackage == null 11176 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11177 if (needSep) { 11178 pw.println(); 11179 needSep = false; 11180 } 11181 pw.println(" mHomeProcess: " + mHomeProcess); 11182 } 11183 if (mPreviousProcess != null && (dumpPackage == null 11184 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11185 if (needSep) { 11186 pw.println(); 11187 needSep = false; 11188 } 11189 pw.println(" mPreviousProcess: " + mPreviousProcess); 11190 } 11191 if (dumpAll) { 11192 StringBuilder sb = new StringBuilder(128); 11193 sb.append(" mPreviousProcessVisibleTime: "); 11194 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11195 pw.println(sb); 11196 } 11197 if (mHeavyWeightProcess != null && (dumpPackage == null 11198 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11199 if (needSep) { 11200 pw.println(); 11201 needSep = false; 11202 } 11203 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11204 } 11205 if (dumpPackage == null) { 11206 pw.println(" mConfiguration: " + mConfiguration); 11207 } 11208 if (dumpAll) { 11209 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11210 if (mCompatModePackages.getPackages().size() > 0) { 11211 boolean printed = false; 11212 for (Map.Entry<String, Integer> entry 11213 : mCompatModePackages.getPackages().entrySet()) { 11214 String pkg = entry.getKey(); 11215 int mode = entry.getValue(); 11216 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11217 continue; 11218 } 11219 if (!printed) { 11220 pw.println(" mScreenCompatPackages:"); 11221 printed = true; 11222 } 11223 pw.print(" "); pw.print(pkg); pw.print(": "); 11224 pw.print(mode); pw.println(); 11225 } 11226 } 11227 } 11228 if (dumpPackage == null) { 11229 if (mSleeping || mWentToSleep || mLockScreenShown) { 11230 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11231 + " mLockScreenShown " + mLockScreenShown); 11232 } 11233 if (mShuttingDown || mRunningVoice) { 11234 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11235 } 11236 } 11237 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11238 || mOrigWaitForDebugger) { 11239 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11240 || dumpPackage.equals(mOrigDebugApp)) { 11241 if (needSep) { 11242 pw.println(); 11243 needSep = false; 11244 } 11245 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11246 + " mDebugTransient=" + mDebugTransient 11247 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11248 } 11249 } 11250 if (mOpenGlTraceApp != null) { 11251 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11252 if (needSep) { 11253 pw.println(); 11254 needSep = false; 11255 } 11256 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11257 } 11258 } 11259 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11260 || mProfileFd != null) { 11261 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11262 if (needSep) { 11263 pw.println(); 11264 needSep = false; 11265 } 11266 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11267 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11268 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11269 + mAutoStopProfiler); 11270 } 11271 } 11272 if (dumpPackage == null) { 11273 if (mAlwaysFinishActivities || mController != null) { 11274 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11275 + " mController=" + mController); 11276 } 11277 if (dumpAll) { 11278 pw.println(" Total persistent processes: " + numPers); 11279 pw.println(" mProcessesReady=" + mProcessesReady 11280 + " mSystemReady=" + mSystemReady); 11281 pw.println(" mBooting=" + mBooting 11282 + " mBooted=" + mBooted 11283 + " mFactoryTest=" + mFactoryTest); 11284 pw.print(" mLastPowerCheckRealtime="); 11285 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11286 pw.println(""); 11287 pw.print(" mLastPowerCheckUptime="); 11288 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11289 pw.println(""); 11290 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11291 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11292 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11293 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11294 + " (" + mLruProcesses.size() + " total)" 11295 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11296 + " mNumServiceProcs=" + mNumServiceProcs 11297 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11298 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11299 + " mLastMemoryLevel" + mLastMemoryLevel 11300 + " mLastNumProcesses" + mLastNumProcesses); 11301 long now = SystemClock.uptimeMillis(); 11302 pw.print(" mLastIdleTime="); 11303 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11304 pw.print(" mLowRamSinceLastIdle="); 11305 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11306 pw.println(); 11307 } 11308 } 11309 11310 if (!printedAnything) { 11311 pw.println(" (nothing)"); 11312 } 11313 } 11314 11315 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11316 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11317 if (mProcessesToGc.size() > 0) { 11318 boolean printed = false; 11319 long now = SystemClock.uptimeMillis(); 11320 for (int i=0; i<mProcessesToGc.size(); i++) { 11321 ProcessRecord proc = mProcessesToGc.get(i); 11322 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11323 continue; 11324 } 11325 if (!printed) { 11326 if (needSep) pw.println(); 11327 needSep = true; 11328 pw.println(" Processes that are waiting to GC:"); 11329 printed = true; 11330 } 11331 pw.print(" Process "); pw.println(proc); 11332 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11333 pw.print(", last gced="); 11334 pw.print(now-proc.lastRequestedGc); 11335 pw.print(" ms ago, last lowMem="); 11336 pw.print(now-proc.lastLowMemory); 11337 pw.println(" ms ago"); 11338 11339 } 11340 } 11341 return needSep; 11342 } 11343 11344 void printOomLevel(PrintWriter pw, String name, int adj) { 11345 pw.print(" "); 11346 if (adj >= 0) { 11347 pw.print(' '); 11348 if (adj < 10) pw.print(' '); 11349 } else { 11350 if (adj > -10) pw.print(' '); 11351 } 11352 pw.print(adj); 11353 pw.print(": "); 11354 pw.print(name); 11355 pw.print(" ("); 11356 pw.print(mProcessList.getMemLevel(adj)/1024); 11357 pw.println(" kB)"); 11358 } 11359 11360 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11361 int opti, boolean dumpAll) { 11362 boolean needSep = false; 11363 11364 if (mLruProcesses.size() > 0) { 11365 if (needSep) pw.println(); 11366 needSep = true; 11367 pw.println(" OOM levels:"); 11368 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11369 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11370 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11371 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11372 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11373 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11374 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11375 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11376 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11377 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11378 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11379 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11380 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11381 11382 if (needSep) pw.println(); 11383 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11384 pw.print(" total, non-act at "); 11385 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11386 pw.print(", non-svc at "); 11387 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11388 pw.println("):"); 11389 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11390 needSep = true; 11391 } 11392 11393 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11394 11395 pw.println(); 11396 pw.println(" mHomeProcess: " + mHomeProcess); 11397 pw.println(" mPreviousProcess: " + mPreviousProcess); 11398 if (mHeavyWeightProcess != null) { 11399 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11400 } 11401 11402 return true; 11403 } 11404 11405 /** 11406 * There are three ways to call this: 11407 * - no provider specified: dump all the providers 11408 * - a flattened component name that matched an existing provider was specified as the 11409 * first arg: dump that one provider 11410 * - the first arg isn't the flattened component name of an existing provider: 11411 * dump all providers whose component contains the first arg as a substring 11412 */ 11413 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11414 int opti, boolean dumpAll) { 11415 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11416 } 11417 11418 static class ItemMatcher { 11419 ArrayList<ComponentName> components; 11420 ArrayList<String> strings; 11421 ArrayList<Integer> objects; 11422 boolean all; 11423 11424 ItemMatcher() { 11425 all = true; 11426 } 11427 11428 void build(String name) { 11429 ComponentName componentName = ComponentName.unflattenFromString(name); 11430 if (componentName != null) { 11431 if (components == null) { 11432 components = new ArrayList<ComponentName>(); 11433 } 11434 components.add(componentName); 11435 all = false; 11436 } else { 11437 int objectId = 0; 11438 // Not a '/' separated full component name; maybe an object ID? 11439 try { 11440 objectId = Integer.parseInt(name, 16); 11441 if (objects == null) { 11442 objects = new ArrayList<Integer>(); 11443 } 11444 objects.add(objectId); 11445 all = false; 11446 } catch (RuntimeException e) { 11447 // Not an integer; just do string match. 11448 if (strings == null) { 11449 strings = new ArrayList<String>(); 11450 } 11451 strings.add(name); 11452 all = false; 11453 } 11454 } 11455 } 11456 11457 int build(String[] args, int opti) { 11458 for (; opti<args.length; opti++) { 11459 String name = args[opti]; 11460 if ("--".equals(name)) { 11461 return opti+1; 11462 } 11463 build(name); 11464 } 11465 return opti; 11466 } 11467 11468 boolean match(Object object, ComponentName comp) { 11469 if (all) { 11470 return true; 11471 } 11472 if (components != null) { 11473 for (int i=0; i<components.size(); i++) { 11474 if (components.get(i).equals(comp)) { 11475 return true; 11476 } 11477 } 11478 } 11479 if (objects != null) { 11480 for (int i=0; i<objects.size(); i++) { 11481 if (System.identityHashCode(object) == objects.get(i)) { 11482 return true; 11483 } 11484 } 11485 } 11486 if (strings != null) { 11487 String flat = comp.flattenToString(); 11488 for (int i=0; i<strings.size(); i++) { 11489 if (flat.contains(strings.get(i))) { 11490 return true; 11491 } 11492 } 11493 } 11494 return false; 11495 } 11496 } 11497 11498 /** 11499 * There are three things that cmd can be: 11500 * - a flattened component name that matches an existing activity 11501 * - the cmd arg isn't the flattened component name of an existing activity: 11502 * dump all activity whose component contains the cmd as a substring 11503 * - A hex number of the ActivityRecord object instance. 11504 */ 11505 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11506 int opti, boolean dumpAll) { 11507 ArrayList<ActivityRecord> activities; 11508 11509 synchronized (this) { 11510 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11511 } 11512 11513 if (activities.size() <= 0) { 11514 return false; 11515 } 11516 11517 String[] newArgs = new String[args.length - opti]; 11518 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11519 11520 TaskRecord lastTask = null; 11521 boolean needSep = false; 11522 for (int i=activities.size()-1; i>=0; i--) { 11523 ActivityRecord r = activities.get(i); 11524 if (needSep) { 11525 pw.println(); 11526 } 11527 needSep = true; 11528 synchronized (this) { 11529 if (lastTask != r.task) { 11530 lastTask = r.task; 11531 pw.print("TASK "); pw.print(lastTask.affinity); 11532 pw.print(" id="); pw.println(lastTask.taskId); 11533 if (dumpAll) { 11534 lastTask.dump(pw, " "); 11535 } 11536 } 11537 } 11538 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11539 } 11540 return true; 11541 } 11542 11543 /** 11544 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11545 * there is a thread associated with the activity. 11546 */ 11547 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11548 final ActivityRecord r, String[] args, boolean dumpAll) { 11549 String innerPrefix = prefix + " "; 11550 synchronized (this) { 11551 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11552 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11553 pw.print(" pid="); 11554 if (r.app != null) pw.println(r.app.pid); 11555 else pw.println("(not running)"); 11556 if (dumpAll) { 11557 r.dump(pw, innerPrefix); 11558 } 11559 } 11560 if (r.app != null && r.app.thread != null) { 11561 // flush anything that is already in the PrintWriter since the thread is going 11562 // to write to the file descriptor directly 11563 pw.flush(); 11564 try { 11565 TransferPipe tp = new TransferPipe(); 11566 try { 11567 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11568 r.appToken, innerPrefix, args); 11569 tp.go(fd); 11570 } finally { 11571 tp.kill(); 11572 } 11573 } catch (IOException e) { 11574 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11575 } catch (RemoteException e) { 11576 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11577 } 11578 } 11579 } 11580 11581 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11582 int opti, boolean dumpAll, String dumpPackage) { 11583 boolean needSep = false; 11584 boolean onlyHistory = false; 11585 boolean printedAnything = false; 11586 11587 if ("history".equals(dumpPackage)) { 11588 if (opti < args.length && "-s".equals(args[opti])) { 11589 dumpAll = false; 11590 } 11591 onlyHistory = true; 11592 dumpPackage = null; 11593 } 11594 11595 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11596 if (!onlyHistory && dumpAll) { 11597 if (mRegisteredReceivers.size() > 0) { 11598 boolean printed = false; 11599 Iterator it = mRegisteredReceivers.values().iterator(); 11600 while (it.hasNext()) { 11601 ReceiverList r = (ReceiverList)it.next(); 11602 if (dumpPackage != null && (r.app == null || 11603 !dumpPackage.equals(r.app.info.packageName))) { 11604 continue; 11605 } 11606 if (!printed) { 11607 pw.println(" Registered Receivers:"); 11608 needSep = true; 11609 printed = true; 11610 printedAnything = true; 11611 } 11612 pw.print(" * "); pw.println(r); 11613 r.dump(pw, " "); 11614 } 11615 } 11616 11617 if (mReceiverResolver.dump(pw, needSep ? 11618 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11619 " ", dumpPackage, false)) { 11620 needSep = true; 11621 printedAnything = true; 11622 } 11623 } 11624 11625 for (BroadcastQueue q : mBroadcastQueues) { 11626 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11627 printedAnything |= needSep; 11628 } 11629 11630 needSep = true; 11631 11632 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11633 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11634 if (needSep) { 11635 pw.println(); 11636 } 11637 needSep = true; 11638 printedAnything = true; 11639 pw.print(" Sticky broadcasts for user "); 11640 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11641 StringBuilder sb = new StringBuilder(128); 11642 for (Map.Entry<String, ArrayList<Intent>> ent 11643 : mStickyBroadcasts.valueAt(user).entrySet()) { 11644 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11645 if (dumpAll) { 11646 pw.println(":"); 11647 ArrayList<Intent> intents = ent.getValue(); 11648 final int N = intents.size(); 11649 for (int i=0; i<N; i++) { 11650 sb.setLength(0); 11651 sb.append(" Intent: "); 11652 intents.get(i).toShortString(sb, false, true, false, false); 11653 pw.println(sb.toString()); 11654 Bundle bundle = intents.get(i).getExtras(); 11655 if (bundle != null) { 11656 pw.print(" "); 11657 pw.println(bundle.toString()); 11658 } 11659 } 11660 } else { 11661 pw.println(""); 11662 } 11663 } 11664 } 11665 } 11666 11667 if (!onlyHistory && dumpAll) { 11668 pw.println(); 11669 for (BroadcastQueue queue : mBroadcastQueues) { 11670 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11671 + queue.mBroadcastsScheduled); 11672 } 11673 pw.println(" mHandler:"); 11674 mHandler.dump(new PrintWriterPrinter(pw), " "); 11675 needSep = true; 11676 printedAnything = true; 11677 } 11678 11679 if (!printedAnything) { 11680 pw.println(" (nothing)"); 11681 } 11682 } 11683 11684 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11685 int opti, boolean dumpAll, String dumpPackage) { 11686 boolean needSep; 11687 boolean printedAnything = false; 11688 11689 ItemMatcher matcher = new ItemMatcher(); 11690 matcher.build(args, opti); 11691 11692 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11693 11694 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11695 printedAnything |= needSep; 11696 11697 if (mLaunchingProviders.size() > 0) { 11698 boolean printed = false; 11699 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11700 ContentProviderRecord r = mLaunchingProviders.get(i); 11701 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11702 continue; 11703 } 11704 if (!printed) { 11705 if (needSep) pw.println(); 11706 needSep = true; 11707 pw.println(" Launching content providers:"); 11708 printed = true; 11709 printedAnything = true; 11710 } 11711 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11712 pw.println(r); 11713 } 11714 } 11715 11716 if (mGrantedUriPermissions.size() > 0) { 11717 boolean printed = false; 11718 int dumpUid = -2; 11719 if (dumpPackage != null) { 11720 try { 11721 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11722 } catch (NameNotFoundException e) { 11723 dumpUid = -1; 11724 } 11725 } 11726 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11727 int uid = mGrantedUriPermissions.keyAt(i); 11728 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11729 continue; 11730 } 11731 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11732 if (!printed) { 11733 if (needSep) pw.println(); 11734 needSep = true; 11735 pw.println(" Granted Uri Permissions:"); 11736 printed = true; 11737 printedAnything = true; 11738 } 11739 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11740 for (UriPermission perm : perms.values()) { 11741 pw.print(" "); pw.println(perm); 11742 if (dumpAll) { 11743 perm.dump(pw, " "); 11744 } 11745 } 11746 } 11747 } 11748 11749 if (!printedAnything) { 11750 pw.println(" (nothing)"); 11751 } 11752 } 11753 11754 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11755 int opti, boolean dumpAll, String dumpPackage) { 11756 boolean printed = false; 11757 11758 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11759 11760 if (mIntentSenderRecords.size() > 0) { 11761 Iterator<WeakReference<PendingIntentRecord>> it 11762 = mIntentSenderRecords.values().iterator(); 11763 while (it.hasNext()) { 11764 WeakReference<PendingIntentRecord> ref = it.next(); 11765 PendingIntentRecord rec = ref != null ? ref.get(): null; 11766 if (dumpPackage != null && (rec == null 11767 || !dumpPackage.equals(rec.key.packageName))) { 11768 continue; 11769 } 11770 printed = true; 11771 if (rec != null) { 11772 pw.print(" * "); pw.println(rec); 11773 if (dumpAll) { 11774 rec.dump(pw, " "); 11775 } 11776 } else { 11777 pw.print(" * "); pw.println(ref); 11778 } 11779 } 11780 } 11781 11782 if (!printed) { 11783 pw.println(" (nothing)"); 11784 } 11785 } 11786 11787 private static final int dumpProcessList(PrintWriter pw, 11788 ActivityManagerService service, List list, 11789 String prefix, String normalLabel, String persistentLabel, 11790 String dumpPackage) { 11791 int numPers = 0; 11792 final int N = list.size()-1; 11793 for (int i=N; i>=0; i--) { 11794 ProcessRecord r = (ProcessRecord)list.get(i); 11795 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11796 continue; 11797 } 11798 pw.println(String.format("%s%s #%2d: %s", 11799 prefix, (r.persistent ? persistentLabel : normalLabel), 11800 i, r.toString())); 11801 if (r.persistent) { 11802 numPers++; 11803 } 11804 } 11805 return numPers; 11806 } 11807 11808 private static final boolean dumpProcessOomList(PrintWriter pw, 11809 ActivityManagerService service, List<ProcessRecord> origList, 11810 String prefix, String normalLabel, String persistentLabel, 11811 boolean inclDetails, String dumpPackage) { 11812 11813 ArrayList<Pair<ProcessRecord, Integer>> list 11814 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11815 for (int i=0; i<origList.size(); i++) { 11816 ProcessRecord r = origList.get(i); 11817 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11818 continue; 11819 } 11820 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11821 } 11822 11823 if (list.size() <= 0) { 11824 return false; 11825 } 11826 11827 Comparator<Pair<ProcessRecord, Integer>> comparator 11828 = new Comparator<Pair<ProcessRecord, Integer>>() { 11829 @Override 11830 public int compare(Pair<ProcessRecord, Integer> object1, 11831 Pair<ProcessRecord, Integer> object2) { 11832 if (object1.first.setAdj != object2.first.setAdj) { 11833 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11834 } 11835 if (object1.second.intValue() != object2.second.intValue()) { 11836 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11837 } 11838 return 0; 11839 } 11840 }; 11841 11842 Collections.sort(list, comparator); 11843 11844 final long curRealtime = SystemClock.elapsedRealtime(); 11845 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11846 final long curUptime = SystemClock.uptimeMillis(); 11847 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11848 11849 for (int i=list.size()-1; i>=0; i--) { 11850 ProcessRecord r = list.get(i).first; 11851 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11852 char schedGroup; 11853 switch (r.setSchedGroup) { 11854 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11855 schedGroup = 'B'; 11856 break; 11857 case Process.THREAD_GROUP_DEFAULT: 11858 schedGroup = 'F'; 11859 break; 11860 default: 11861 schedGroup = '?'; 11862 break; 11863 } 11864 char foreground; 11865 if (r.foregroundActivities) { 11866 foreground = 'A'; 11867 } else if (r.foregroundServices) { 11868 foreground = 'S'; 11869 } else { 11870 foreground = ' '; 11871 } 11872 String procState = ProcessList.makeProcStateString(r.curProcState); 11873 pw.print(prefix); 11874 pw.print(r.persistent ? persistentLabel : normalLabel); 11875 pw.print(" #"); 11876 int num = (origList.size()-1)-list.get(i).second; 11877 if (num < 10) pw.print(' '); 11878 pw.print(num); 11879 pw.print(": "); 11880 pw.print(oomAdj); 11881 pw.print(' '); 11882 pw.print(schedGroup); 11883 pw.print('/'); 11884 pw.print(foreground); 11885 pw.print('/'); 11886 pw.print(procState); 11887 pw.print(" trm:"); 11888 if (r.trimMemoryLevel < 10) pw.print(' '); 11889 pw.print(r.trimMemoryLevel); 11890 pw.print(' '); 11891 pw.print(r.toShortString()); 11892 pw.print(" ("); 11893 pw.print(r.adjType); 11894 pw.println(')'); 11895 if (r.adjSource != null || r.adjTarget != null) { 11896 pw.print(prefix); 11897 pw.print(" "); 11898 if (r.adjTarget instanceof ComponentName) { 11899 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11900 } else if (r.adjTarget != null) { 11901 pw.print(r.adjTarget.toString()); 11902 } else { 11903 pw.print("{null}"); 11904 } 11905 pw.print("<="); 11906 if (r.adjSource instanceof ProcessRecord) { 11907 pw.print("Proc{"); 11908 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11909 pw.println("}"); 11910 } else if (r.adjSource != null) { 11911 pw.println(r.adjSource.toString()); 11912 } else { 11913 pw.println("{null}"); 11914 } 11915 } 11916 if (inclDetails) { 11917 pw.print(prefix); 11918 pw.print(" "); 11919 pw.print("oom: max="); pw.print(r.maxAdj); 11920 pw.print(" curRaw="); pw.print(r.curRawAdj); 11921 pw.print(" setRaw="); pw.print(r.setRawAdj); 11922 pw.print(" cur="); pw.print(r.curAdj); 11923 pw.print(" set="); pw.println(r.setAdj); 11924 pw.print(prefix); 11925 pw.print(" "); 11926 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11927 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11928 pw.print(" lastPss="); pw.print(r.lastPss); 11929 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11930 pw.print(prefix); 11931 pw.print(" "); 11932 pw.print("keeping="); pw.print(r.keeping); 11933 pw.print(" cached="); pw.print(r.cached); 11934 pw.print(" empty="); pw.print(r.empty); 11935 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11936 11937 if (!r.keeping) { 11938 if (r.lastWakeTime != 0) { 11939 long wtime; 11940 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11941 synchronized (stats) { 11942 wtime = stats.getProcessWakeTime(r.info.uid, 11943 r.pid, curRealtime); 11944 } 11945 long timeUsed = wtime - r.lastWakeTime; 11946 pw.print(prefix); 11947 pw.print(" "); 11948 pw.print("keep awake over "); 11949 TimeUtils.formatDuration(realtimeSince, pw); 11950 pw.print(" used "); 11951 TimeUtils.formatDuration(timeUsed, pw); 11952 pw.print(" ("); 11953 pw.print((timeUsed*100)/realtimeSince); 11954 pw.println("%)"); 11955 } 11956 if (r.lastCpuTime != 0) { 11957 long timeUsed = r.curCpuTime - r.lastCpuTime; 11958 pw.print(prefix); 11959 pw.print(" "); 11960 pw.print("run cpu over "); 11961 TimeUtils.formatDuration(uptimeSince, pw); 11962 pw.print(" used "); 11963 TimeUtils.formatDuration(timeUsed, pw); 11964 pw.print(" ("); 11965 pw.print((timeUsed*100)/uptimeSince); 11966 pw.println("%)"); 11967 } 11968 } 11969 } 11970 } 11971 return true; 11972 } 11973 11974 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11975 ArrayList<ProcessRecord> procs; 11976 synchronized (this) { 11977 if (args != null && args.length > start 11978 && args[start].charAt(0) != '-') { 11979 procs = new ArrayList<ProcessRecord>(); 11980 int pid = -1; 11981 try { 11982 pid = Integer.parseInt(args[start]); 11983 } catch (NumberFormatException e) { 11984 } 11985 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11986 ProcessRecord proc = mLruProcesses.get(i); 11987 if (proc.pid == pid) { 11988 procs.add(proc); 11989 } else if (proc.processName.equals(args[start])) { 11990 procs.add(proc); 11991 } 11992 } 11993 if (procs.size() <= 0) { 11994 return null; 11995 } 11996 } else { 11997 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11998 } 11999 } 12000 return procs; 12001 } 12002 12003 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12004 PrintWriter pw, String[] args) { 12005 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12006 if (procs == null) { 12007 pw.println("No process found for: " + args[0]); 12008 return; 12009 } 12010 12011 long uptime = SystemClock.uptimeMillis(); 12012 long realtime = SystemClock.elapsedRealtime(); 12013 pw.println("Applications Graphics Acceleration Info:"); 12014 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12015 12016 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12017 ProcessRecord r = procs.get(i); 12018 if (r.thread != null) { 12019 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12020 pw.flush(); 12021 try { 12022 TransferPipe tp = new TransferPipe(); 12023 try { 12024 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12025 tp.go(fd); 12026 } finally { 12027 tp.kill(); 12028 } 12029 } catch (IOException e) { 12030 pw.println("Failure while dumping the app: " + r); 12031 pw.flush(); 12032 } catch (RemoteException e) { 12033 pw.println("Got a RemoteException while dumping the app " + r); 12034 pw.flush(); 12035 } 12036 } 12037 } 12038 } 12039 12040 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12041 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12042 if (procs == null) { 12043 pw.println("No process found for: " + args[0]); 12044 return; 12045 } 12046 12047 pw.println("Applications Database Info:"); 12048 12049 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12050 ProcessRecord r = procs.get(i); 12051 if (r.thread != null) { 12052 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12053 pw.flush(); 12054 try { 12055 TransferPipe tp = new TransferPipe(); 12056 try { 12057 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12058 tp.go(fd); 12059 } finally { 12060 tp.kill(); 12061 } 12062 } catch (IOException e) { 12063 pw.println("Failure while dumping the app: " + r); 12064 pw.flush(); 12065 } catch (RemoteException e) { 12066 pw.println("Got a RemoteException while dumping the app " + r); 12067 pw.flush(); 12068 } 12069 } 12070 } 12071 } 12072 12073 final static class MemItem { 12074 final boolean isProc; 12075 final String label; 12076 final String shortLabel; 12077 final long pss; 12078 final int id; 12079 final boolean hasActivities; 12080 ArrayList<MemItem> subitems; 12081 12082 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12083 boolean _hasActivities) { 12084 isProc = true; 12085 label = _label; 12086 shortLabel = _shortLabel; 12087 pss = _pss; 12088 id = _id; 12089 hasActivities = _hasActivities; 12090 } 12091 12092 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12093 isProc = false; 12094 label = _label; 12095 shortLabel = _shortLabel; 12096 pss = _pss; 12097 id = _id; 12098 hasActivities = false; 12099 } 12100 } 12101 12102 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12103 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12104 if (sort && !isCompact) { 12105 Collections.sort(items, new Comparator<MemItem>() { 12106 @Override 12107 public int compare(MemItem lhs, MemItem rhs) { 12108 if (lhs.pss < rhs.pss) { 12109 return 1; 12110 } else if (lhs.pss > rhs.pss) { 12111 return -1; 12112 } 12113 return 0; 12114 } 12115 }); 12116 } 12117 12118 for (int i=0; i<items.size(); i++) { 12119 MemItem mi = items.get(i); 12120 if (!isCompact) { 12121 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12122 } else if (mi.isProc) { 12123 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12124 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12125 pw.println(mi.hasActivities ? ",a" : ",e"); 12126 } else { 12127 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12128 pw.println(mi.pss); 12129 } 12130 if (mi.subitems != null) { 12131 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12132 true, isCompact); 12133 } 12134 } 12135 } 12136 12137 // These are in KB. 12138 static final long[] DUMP_MEM_BUCKETS = new long[] { 12139 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12140 120*1024, 160*1024, 200*1024, 12141 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12142 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12143 }; 12144 12145 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12146 boolean stackLike) { 12147 int start = label.lastIndexOf('.'); 12148 if (start >= 0) start++; 12149 else start = 0; 12150 int end = label.length(); 12151 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12152 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12153 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12154 out.append(bucket); 12155 out.append(stackLike ? "MB." : "MB "); 12156 out.append(label, start, end); 12157 return; 12158 } 12159 } 12160 out.append(memKB/1024); 12161 out.append(stackLike ? "MB." : "MB "); 12162 out.append(label, start, end); 12163 } 12164 12165 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12166 ProcessList.NATIVE_ADJ, 12167 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12168 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12169 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12170 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12171 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12172 }; 12173 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12174 "Native", 12175 "System", "Persistent", "Foreground", 12176 "Visible", "Perceptible", 12177 "Heavy Weight", "Backup", 12178 "A Services", "Home", 12179 "Previous", "B Services", "Cached" 12180 }; 12181 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12182 "native", 12183 "sys", "pers", "fore", 12184 "vis", "percept", 12185 "heavy", "backup", 12186 "servicea", "home", 12187 "prev", "serviceb", "cached" 12188 }; 12189 12190 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12191 long realtime, boolean isCheckinRequest, boolean isCompact) { 12192 if (isCheckinRequest || isCompact) { 12193 // short checkin version 12194 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12195 } else { 12196 pw.println("Applications Memory Usage (kB):"); 12197 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12198 } 12199 } 12200 12201 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12202 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12203 boolean dumpDetails = false; 12204 boolean dumpFullDetails = false; 12205 boolean dumpDalvik = false; 12206 boolean oomOnly = false; 12207 boolean isCompact = false; 12208 boolean localOnly = false; 12209 12210 int opti = 0; 12211 while (opti < args.length) { 12212 String opt = args[opti]; 12213 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12214 break; 12215 } 12216 opti++; 12217 if ("-a".equals(opt)) { 12218 dumpDetails = true; 12219 dumpFullDetails = true; 12220 dumpDalvik = true; 12221 } else if ("-d".equals(opt)) { 12222 dumpDalvik = true; 12223 } else if ("-c".equals(opt)) { 12224 isCompact = true; 12225 } else if ("--oom".equals(opt)) { 12226 oomOnly = true; 12227 } else if ("--local".equals(opt)) { 12228 localOnly = true; 12229 } else if ("-h".equals(opt)) { 12230 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12231 pw.println(" -a: include all available information for each process."); 12232 pw.println(" -d: include dalvik details when dumping process details."); 12233 pw.println(" -c: dump in a compact machine-parseable representation."); 12234 pw.println(" --oom: only show processes organized by oom adj."); 12235 pw.println(" --local: only collect details locally, don't call process."); 12236 pw.println("If [process] is specified it can be the name or "); 12237 pw.println("pid of a specific process to dump."); 12238 return; 12239 } else { 12240 pw.println("Unknown argument: " + opt + "; use -h for help"); 12241 } 12242 } 12243 12244 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12245 long uptime = SystemClock.uptimeMillis(); 12246 long realtime = SystemClock.elapsedRealtime(); 12247 final long[] tmpLong = new long[1]; 12248 12249 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12250 if (procs == null) { 12251 // No Java processes. Maybe they want to print a native process. 12252 if (args != null && args.length > opti 12253 && args[opti].charAt(0) != '-') { 12254 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12255 = new ArrayList<ProcessCpuTracker.Stats>(); 12256 updateCpuStatsNow(); 12257 int findPid = -1; 12258 try { 12259 findPid = Integer.parseInt(args[opti]); 12260 } catch (NumberFormatException e) { 12261 } 12262 synchronized (mProcessCpuThread) { 12263 final int N = mProcessCpuTracker.countStats(); 12264 for (int i=0; i<N; i++) { 12265 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12266 if (st.pid == findPid || (st.baseName != null 12267 && st.baseName.equals(args[opti]))) { 12268 nativeProcs.add(st); 12269 } 12270 } 12271 } 12272 if (nativeProcs.size() > 0) { 12273 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12274 isCompact); 12275 Debug.MemoryInfo mi = null; 12276 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12277 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12278 final int pid = r.pid; 12279 if (!isCheckinRequest && dumpDetails) { 12280 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12281 } 12282 if (mi == null) { 12283 mi = new Debug.MemoryInfo(); 12284 } 12285 if (dumpDetails || (!brief && !oomOnly)) { 12286 Debug.getMemoryInfo(pid, mi); 12287 } else { 12288 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12289 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12290 } 12291 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12292 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12293 if (isCheckinRequest) { 12294 pw.println(); 12295 } 12296 } 12297 return; 12298 } 12299 } 12300 pw.println("No process found for: " + args[opti]); 12301 return; 12302 } 12303 12304 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12305 dumpDetails = true; 12306 } 12307 12308 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12309 12310 String[] innerArgs = new String[args.length-opti]; 12311 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12312 12313 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12314 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12315 long nativePss=0, dalvikPss=0, otherPss=0; 12316 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12317 12318 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12319 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12320 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12321 12322 long totalPss = 0; 12323 long cachedPss = 0; 12324 12325 Debug.MemoryInfo mi = null; 12326 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12327 final ProcessRecord r = procs.get(i); 12328 final IApplicationThread thread; 12329 final int pid; 12330 final int oomAdj; 12331 final boolean hasActivities; 12332 synchronized (this) { 12333 thread = r.thread; 12334 pid = r.pid; 12335 oomAdj = r.getSetAdjWithServices(); 12336 hasActivities = r.activities.size() > 0; 12337 } 12338 if (thread != null) { 12339 if (!isCheckinRequest && dumpDetails) { 12340 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12341 } 12342 if (mi == null) { 12343 mi = new Debug.MemoryInfo(); 12344 } 12345 if (dumpDetails || (!brief && !oomOnly)) { 12346 Debug.getMemoryInfo(pid, mi); 12347 } else { 12348 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12349 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12350 } 12351 if (dumpDetails) { 12352 if (localOnly) { 12353 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12354 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12355 if (isCheckinRequest) { 12356 pw.println(); 12357 } 12358 } else { 12359 try { 12360 pw.flush(); 12361 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12362 dumpDalvik, innerArgs); 12363 } catch (RemoteException e) { 12364 if (!isCheckinRequest) { 12365 pw.println("Got RemoteException!"); 12366 pw.flush(); 12367 } 12368 } 12369 } 12370 } 12371 12372 final long myTotalPss = mi.getTotalPss(); 12373 final long myTotalUss = mi.getTotalUss(); 12374 12375 synchronized (this) { 12376 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12377 // Record this for posterity if the process has been stable. 12378 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12379 } 12380 } 12381 12382 if (!isCheckinRequest && mi != null) { 12383 totalPss += myTotalPss; 12384 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12385 (hasActivities ? " / activities)" : ")"), 12386 r.processName, myTotalPss, pid, hasActivities); 12387 procMems.add(pssItem); 12388 procMemsMap.put(pid, pssItem); 12389 12390 nativePss += mi.nativePss; 12391 dalvikPss += mi.dalvikPss; 12392 otherPss += mi.otherPss; 12393 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12394 long mem = mi.getOtherPss(j); 12395 miscPss[j] += mem; 12396 otherPss -= mem; 12397 } 12398 12399 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12400 cachedPss += myTotalPss; 12401 } 12402 12403 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12404 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12405 || oomIndex == (oomPss.length-1)) { 12406 oomPss[oomIndex] += myTotalPss; 12407 if (oomProcs[oomIndex] == null) { 12408 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12409 } 12410 oomProcs[oomIndex].add(pssItem); 12411 break; 12412 } 12413 } 12414 } 12415 } 12416 } 12417 12418 if (!isCheckinRequest && procs.size() > 1) { 12419 // If we are showing aggregations, also look for native processes to 12420 // include so that our aggregations are more accurate. 12421 updateCpuStatsNow(); 12422 synchronized (mProcessCpuThread) { 12423 final int N = mProcessCpuTracker.countStats(); 12424 for (int i=0; i<N; i++) { 12425 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12426 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12427 if (mi == null) { 12428 mi = new Debug.MemoryInfo(); 12429 } 12430 if (!brief && !oomOnly) { 12431 Debug.getMemoryInfo(st.pid, mi); 12432 } else { 12433 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12434 mi.nativePrivateDirty = (int)tmpLong[0]; 12435 } 12436 12437 final long myTotalPss = mi.getTotalPss(); 12438 totalPss += myTotalPss; 12439 12440 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12441 st.name, myTotalPss, st.pid, false); 12442 procMems.add(pssItem); 12443 12444 nativePss += mi.nativePss; 12445 dalvikPss += mi.dalvikPss; 12446 otherPss += mi.otherPss; 12447 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12448 long mem = mi.getOtherPss(j); 12449 miscPss[j] += mem; 12450 otherPss -= mem; 12451 } 12452 oomPss[0] += myTotalPss; 12453 if (oomProcs[0] == null) { 12454 oomProcs[0] = new ArrayList<MemItem>(); 12455 } 12456 oomProcs[0].add(pssItem); 12457 } 12458 } 12459 } 12460 12461 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12462 12463 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12464 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12465 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12466 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12467 String label = Debug.MemoryInfo.getOtherLabel(j); 12468 catMems.add(new MemItem(label, label, miscPss[j], j)); 12469 } 12470 12471 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12472 for (int j=0; j<oomPss.length; j++) { 12473 if (oomPss[j] != 0) { 12474 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12475 : DUMP_MEM_OOM_LABEL[j]; 12476 MemItem item = new MemItem(label, label, oomPss[j], 12477 DUMP_MEM_OOM_ADJ[j]); 12478 item.subitems = oomProcs[j]; 12479 oomMems.add(item); 12480 } 12481 } 12482 12483 if (!brief && !oomOnly && !isCompact) { 12484 pw.println(); 12485 pw.println("Total PSS by process:"); 12486 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12487 pw.println(); 12488 } 12489 if (!isCompact) { 12490 pw.println("Total PSS by OOM adjustment:"); 12491 } 12492 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12493 if (!brief && !oomOnly) { 12494 PrintWriter out = categoryPw != null ? categoryPw : pw; 12495 if (!isCompact) { 12496 out.println(); 12497 out.println("Total PSS by category:"); 12498 } 12499 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12500 } 12501 if (!isCompact) { 12502 pw.println(); 12503 } 12504 MemInfoReader memInfo = new MemInfoReader(); 12505 memInfo.readMemInfo(); 12506 if (!brief) { 12507 if (!isCompact) { 12508 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12509 pw.print(" kB (status "); 12510 switch (mLastMemoryLevel) { 12511 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12512 pw.println("normal)"); 12513 break; 12514 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12515 pw.println("moderate)"); 12516 break; 12517 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12518 pw.println("low)"); 12519 break; 12520 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12521 pw.println("critical)"); 12522 break; 12523 default: 12524 pw.print(mLastMemoryLevel); 12525 pw.println(")"); 12526 break; 12527 } 12528 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12529 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12530 pw.print(cachedPss); pw.print(" cached pss + "); 12531 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12532 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12533 } else { 12534 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12535 pw.print(cachedPss + memInfo.getCachedSizeKb() 12536 + memInfo.getFreeSizeKb()); pw.print(","); 12537 pw.println(totalPss - cachedPss); 12538 } 12539 } 12540 if (!isCompact) { 12541 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12542 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12543 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12544 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12545 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12546 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12547 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12548 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12549 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12550 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12551 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12552 } 12553 if (!brief) { 12554 if (memInfo.getZramTotalSizeKb() != 0) { 12555 if (!isCompact) { 12556 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12557 pw.print(" kB physical used for "); 12558 pw.print(memInfo.getSwapTotalSizeKb() 12559 - memInfo.getSwapFreeSizeKb()); 12560 pw.print(" kB in swap ("); 12561 pw.print(memInfo.getSwapTotalSizeKb()); 12562 pw.println(" kB total swap)"); 12563 } else { 12564 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12565 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12566 pw.println(memInfo.getSwapFreeSizeKb()); 12567 } 12568 } 12569 final int[] SINGLE_LONG_FORMAT = new int[] { 12570 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12571 }; 12572 long[] longOut = new long[1]; 12573 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12574 SINGLE_LONG_FORMAT, null, longOut, null); 12575 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12576 longOut[0] = 0; 12577 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12578 SINGLE_LONG_FORMAT, null, longOut, null); 12579 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12580 longOut[0] = 0; 12581 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12582 SINGLE_LONG_FORMAT, null, longOut, null); 12583 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12584 longOut[0] = 0; 12585 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12586 SINGLE_LONG_FORMAT, null, longOut, null); 12587 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12588 if (!isCompact) { 12589 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12590 pw.print(" KSM: "); pw.print(sharing); 12591 pw.print(" kB saved from shared "); 12592 pw.print(shared); pw.println(" kB"); 12593 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12594 pw.print(voltile); pw.println(" kB volatile"); 12595 } 12596 pw.print(" Tuning: "); 12597 pw.print(ActivityManager.staticGetMemoryClass()); 12598 pw.print(" (large "); 12599 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12600 pw.print("), oom "); 12601 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12602 pw.print(" kB"); 12603 pw.print(", restore limit "); 12604 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12605 pw.print(" kB"); 12606 if (ActivityManager.isLowRamDeviceStatic()) { 12607 pw.print(" (low-ram)"); 12608 } 12609 if (ActivityManager.isHighEndGfx()) { 12610 pw.print(" (high-end-gfx)"); 12611 } 12612 pw.println(); 12613 } else { 12614 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12615 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12616 pw.println(voltile); 12617 pw.print("tuning,"); 12618 pw.print(ActivityManager.staticGetMemoryClass()); 12619 pw.print(','); 12620 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12621 pw.print(','); 12622 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12623 if (ActivityManager.isLowRamDeviceStatic()) { 12624 pw.print(",low-ram"); 12625 } 12626 if (ActivityManager.isHighEndGfx()) { 12627 pw.print(",high-end-gfx"); 12628 } 12629 pw.println(); 12630 } 12631 } 12632 } 12633 } 12634 12635 /** 12636 * Searches array of arguments for the specified string 12637 * @param args array of argument strings 12638 * @param value value to search for 12639 * @return true if the value is contained in the array 12640 */ 12641 private static boolean scanArgs(String[] args, String value) { 12642 if (args != null) { 12643 for (String arg : args) { 12644 if (value.equals(arg)) { 12645 return true; 12646 } 12647 } 12648 } 12649 return false; 12650 } 12651 12652 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12653 ContentProviderRecord cpr, boolean always) { 12654 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12655 12656 if (!inLaunching || always) { 12657 synchronized (cpr) { 12658 cpr.launchingApp = null; 12659 cpr.notifyAll(); 12660 } 12661 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12662 String names[] = cpr.info.authority.split(";"); 12663 for (int j = 0; j < names.length; j++) { 12664 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12665 } 12666 } 12667 12668 for (int i=0; i<cpr.connections.size(); i++) { 12669 ContentProviderConnection conn = cpr.connections.get(i); 12670 if (conn.waiting) { 12671 // If this connection is waiting for the provider, then we don't 12672 // need to mess with its process unless we are always removing 12673 // or for some reason the provider is not currently launching. 12674 if (inLaunching && !always) { 12675 continue; 12676 } 12677 } 12678 ProcessRecord capp = conn.client; 12679 conn.dead = true; 12680 if (conn.stableCount > 0) { 12681 if (!capp.persistent && capp.thread != null 12682 && capp.pid != 0 12683 && capp.pid != MY_PID) { 12684 killUnneededProcessLocked(capp, "depends on provider " 12685 + cpr.name.flattenToShortString() 12686 + " in dying proc " + (proc != null ? proc.processName : "??")); 12687 } 12688 } else if (capp.thread != null && conn.provider.provider != null) { 12689 try { 12690 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12691 } catch (RemoteException e) { 12692 } 12693 // In the protocol here, we don't expect the client to correctly 12694 // clean up this connection, we'll just remove it. 12695 cpr.connections.remove(i); 12696 conn.client.conProviders.remove(conn); 12697 } 12698 } 12699 12700 if (inLaunching && always) { 12701 mLaunchingProviders.remove(cpr); 12702 } 12703 return inLaunching; 12704 } 12705 12706 /** 12707 * Main code for cleaning up a process when it has gone away. This is 12708 * called both as a result of the process dying, or directly when stopping 12709 * a process when running in single process mode. 12710 */ 12711 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12712 boolean restarting, boolean allowRestart, int index) { 12713 if (index >= 0) { 12714 removeLruProcessLocked(app); 12715 ProcessList.remove(app.pid); 12716 } 12717 12718 mProcessesToGc.remove(app); 12719 mPendingPssProcesses.remove(app); 12720 12721 // Dismiss any open dialogs. 12722 if (app.crashDialog != null && !app.forceCrashReport) { 12723 app.crashDialog.dismiss(); 12724 app.crashDialog = null; 12725 } 12726 if (app.anrDialog != null) { 12727 app.anrDialog.dismiss(); 12728 app.anrDialog = null; 12729 } 12730 if (app.waitDialog != null) { 12731 app.waitDialog.dismiss(); 12732 app.waitDialog = null; 12733 } 12734 12735 app.crashing = false; 12736 app.notResponding = false; 12737 12738 app.resetPackageList(mProcessStats); 12739 app.unlinkDeathRecipient(); 12740 app.makeInactive(mProcessStats); 12741 app.forcingToForeground = null; 12742 updateProcessForegroundLocked(app, false, false); 12743 app.foregroundActivities = false; 12744 app.hasShownUi = false; 12745 app.treatLikeActivity = false; 12746 app.hasAboveClient = false; 12747 app.hasClientActivities = false; 12748 12749 mServices.killServicesLocked(app, allowRestart); 12750 12751 boolean restart = false; 12752 12753 // Remove published content providers. 12754 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12755 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12756 final boolean always = app.bad || !allowRestart; 12757 if (removeDyingProviderLocked(app, cpr, always) || always) { 12758 // We left the provider in the launching list, need to 12759 // restart it. 12760 restart = true; 12761 } 12762 12763 cpr.provider = null; 12764 cpr.proc = null; 12765 } 12766 app.pubProviders.clear(); 12767 12768 // Take care of any launching providers waiting for this process. 12769 if (checkAppInLaunchingProvidersLocked(app, false)) { 12770 restart = true; 12771 } 12772 12773 // Unregister from connected content providers. 12774 if (!app.conProviders.isEmpty()) { 12775 for (int i=0; i<app.conProviders.size(); i++) { 12776 ContentProviderConnection conn = app.conProviders.get(i); 12777 conn.provider.connections.remove(conn); 12778 } 12779 app.conProviders.clear(); 12780 } 12781 12782 // At this point there may be remaining entries in mLaunchingProviders 12783 // where we were the only one waiting, so they are no longer of use. 12784 // Look for these and clean up if found. 12785 // XXX Commented out for now. Trying to figure out a way to reproduce 12786 // the actual situation to identify what is actually going on. 12787 if (false) { 12788 for (int i=0; i<mLaunchingProviders.size(); i++) { 12789 ContentProviderRecord cpr = (ContentProviderRecord) 12790 mLaunchingProviders.get(i); 12791 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12792 synchronized (cpr) { 12793 cpr.launchingApp = null; 12794 cpr.notifyAll(); 12795 } 12796 } 12797 } 12798 } 12799 12800 skipCurrentReceiverLocked(app); 12801 12802 // Unregister any receivers. 12803 for (int i=app.receivers.size()-1; i>=0; i--) { 12804 removeReceiverLocked(app.receivers.valueAt(i)); 12805 } 12806 app.receivers.clear(); 12807 12808 // If the app is undergoing backup, tell the backup manager about it 12809 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12810 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12811 + mBackupTarget.appInfo + " died during backup"); 12812 try { 12813 IBackupManager bm = IBackupManager.Stub.asInterface( 12814 ServiceManager.getService(Context.BACKUP_SERVICE)); 12815 bm.agentDisconnected(app.info.packageName); 12816 } catch (RemoteException e) { 12817 // can't happen; backup manager is local 12818 } 12819 } 12820 12821 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12822 ProcessChangeItem item = mPendingProcessChanges.get(i); 12823 if (item.pid == app.pid) { 12824 mPendingProcessChanges.remove(i); 12825 mAvailProcessChanges.add(item); 12826 } 12827 } 12828 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12829 12830 // If the caller is restarting this app, then leave it in its 12831 // current lists and let the caller take care of it. 12832 if (restarting) { 12833 return; 12834 } 12835 12836 if (!app.persistent || app.isolated) { 12837 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12838 "Removing non-persistent process during cleanup: " + app); 12839 mProcessNames.remove(app.processName, app.uid); 12840 mIsolatedProcesses.remove(app.uid); 12841 if (mHeavyWeightProcess == app) { 12842 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12843 mHeavyWeightProcess.userId, 0)); 12844 mHeavyWeightProcess = null; 12845 } 12846 } else if (!app.removed) { 12847 // This app is persistent, so we need to keep its record around. 12848 // If it is not already on the pending app list, add it there 12849 // and start a new process for it. 12850 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12851 mPersistentStartingProcesses.add(app); 12852 restart = true; 12853 } 12854 } 12855 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12856 "Clean-up removing on hold: " + app); 12857 mProcessesOnHold.remove(app); 12858 12859 if (app == mHomeProcess) { 12860 mHomeProcess = null; 12861 } 12862 if (app == mPreviousProcess) { 12863 mPreviousProcess = null; 12864 } 12865 12866 if (restart && !app.isolated) { 12867 // We have components that still need to be running in the 12868 // process, so re-launch it. 12869 mProcessNames.put(app.processName, app.uid, app); 12870 startProcessLocked(app, "restart", app.processName); 12871 } else if (app.pid > 0 && app.pid != MY_PID) { 12872 // Goodbye! 12873 boolean removed; 12874 synchronized (mPidsSelfLocked) { 12875 mPidsSelfLocked.remove(app.pid); 12876 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12877 } 12878 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12879 app.processName, app.info.uid); 12880 if (app.isolated) { 12881 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12882 } 12883 app.setPid(0); 12884 } 12885 } 12886 12887 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12888 // Look through the content providers we are waiting to have launched, 12889 // and if any run in this process then either schedule a restart of 12890 // the process or kill the client waiting for it if this process has 12891 // gone bad. 12892 int NL = mLaunchingProviders.size(); 12893 boolean restart = false; 12894 for (int i=0; i<NL; i++) { 12895 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12896 if (cpr.launchingApp == app) { 12897 if (!alwaysBad && !app.bad) { 12898 restart = true; 12899 } else { 12900 removeDyingProviderLocked(app, cpr, true); 12901 // cpr should have been removed from mLaunchingProviders 12902 NL = mLaunchingProviders.size(); 12903 i--; 12904 } 12905 } 12906 } 12907 return restart; 12908 } 12909 12910 // ========================================================= 12911 // SERVICES 12912 // ========================================================= 12913 12914 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12915 int flags) { 12916 enforceNotIsolatedCaller("getServices"); 12917 synchronized (this) { 12918 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12919 } 12920 } 12921 12922 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12923 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12924 synchronized (this) { 12925 return mServices.getRunningServiceControlPanelLocked(name); 12926 } 12927 } 12928 12929 public ComponentName startService(IApplicationThread caller, Intent service, 12930 String resolvedType, int userId) { 12931 enforceNotIsolatedCaller("startService"); 12932 // Refuse possible leaked file descriptors 12933 if (service != null && service.hasFileDescriptors() == true) { 12934 throw new IllegalArgumentException("File descriptors passed in Intent"); 12935 } 12936 12937 if (DEBUG_SERVICE) 12938 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12939 synchronized(this) { 12940 final int callingPid = Binder.getCallingPid(); 12941 final int callingUid = Binder.getCallingUid(); 12942 final long origId = Binder.clearCallingIdentity(); 12943 ComponentName res = mServices.startServiceLocked(caller, service, 12944 resolvedType, callingPid, callingUid, userId); 12945 Binder.restoreCallingIdentity(origId); 12946 return res; 12947 } 12948 } 12949 12950 ComponentName startServiceInPackage(int uid, 12951 Intent service, String resolvedType, int userId) { 12952 synchronized(this) { 12953 if (DEBUG_SERVICE) 12954 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12955 final long origId = Binder.clearCallingIdentity(); 12956 ComponentName res = mServices.startServiceLocked(null, service, 12957 resolvedType, -1, uid, userId); 12958 Binder.restoreCallingIdentity(origId); 12959 return res; 12960 } 12961 } 12962 12963 public int stopService(IApplicationThread caller, Intent service, 12964 String resolvedType, int userId) { 12965 enforceNotIsolatedCaller("stopService"); 12966 // Refuse possible leaked file descriptors 12967 if (service != null && service.hasFileDescriptors() == true) { 12968 throw new IllegalArgumentException("File descriptors passed in Intent"); 12969 } 12970 12971 synchronized(this) { 12972 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12973 } 12974 } 12975 12976 public IBinder peekService(Intent service, String resolvedType) { 12977 enforceNotIsolatedCaller("peekService"); 12978 // Refuse possible leaked file descriptors 12979 if (service != null && service.hasFileDescriptors() == true) { 12980 throw new IllegalArgumentException("File descriptors passed in Intent"); 12981 } 12982 synchronized(this) { 12983 return mServices.peekServiceLocked(service, resolvedType); 12984 } 12985 } 12986 12987 public boolean stopServiceToken(ComponentName className, IBinder token, 12988 int startId) { 12989 synchronized(this) { 12990 return mServices.stopServiceTokenLocked(className, token, startId); 12991 } 12992 } 12993 12994 public void setServiceForeground(ComponentName className, IBinder token, 12995 int id, Notification notification, boolean removeNotification) { 12996 synchronized(this) { 12997 mServices.setServiceForegroundLocked(className, token, id, notification, 12998 removeNotification); 12999 } 13000 } 13001 13002 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13003 boolean requireFull, String name, String callerPackage) { 13004 final int callingUserId = UserHandle.getUserId(callingUid); 13005 if (callingUserId != userId) { 13006 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13007 if ((requireFull || checkComponentPermission( 13008 android.Manifest.permission.INTERACT_ACROSS_USERS, 13009 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 13010 && checkComponentPermission( 13011 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 13012 callingPid, callingUid, -1, true) 13013 != PackageManager.PERMISSION_GRANTED) { 13014 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13015 // In this case, they would like to just execute as their 13016 // owner user instead of failing. 13017 userId = callingUserId; 13018 } else { 13019 StringBuilder builder = new StringBuilder(128); 13020 builder.append("Permission Denial: "); 13021 builder.append(name); 13022 if (callerPackage != null) { 13023 builder.append(" from "); 13024 builder.append(callerPackage); 13025 } 13026 builder.append(" asks to run as user "); 13027 builder.append(userId); 13028 builder.append(" but is calling from user "); 13029 builder.append(UserHandle.getUserId(callingUid)); 13030 builder.append("; this requires "); 13031 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 13032 if (!requireFull) { 13033 builder.append(" or "); 13034 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13035 } 13036 String msg = builder.toString(); 13037 Slog.w(TAG, msg); 13038 throw new SecurityException(msg); 13039 } 13040 } 13041 } 13042 if (userId == UserHandle.USER_CURRENT 13043 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13044 // Note that we may be accessing this outside of a lock... 13045 // shouldn't be a big deal, if this is being called outside 13046 // of a locked context there is intrinsically a race with 13047 // the value the caller will receive and someone else changing it. 13048 userId = mCurrentUserId; 13049 } 13050 if (!allowAll && userId < 0) { 13051 throw new IllegalArgumentException( 13052 "Call does not support special user #" + userId); 13053 } 13054 } 13055 return userId; 13056 } 13057 13058 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13059 String className, int flags) { 13060 boolean result = false; 13061 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13062 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 13063 if (ActivityManager.checkUidPermission( 13064 android.Manifest.permission.INTERACT_ACROSS_USERS, 13065 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13066 ComponentName comp = new ComponentName(aInfo.packageName, className); 13067 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13068 + " requests FLAG_SINGLE_USER, but app does not hold " 13069 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13070 Slog.w(TAG, msg); 13071 throw new SecurityException(msg); 13072 } 13073 result = true; 13074 } 13075 } else if (componentProcessName == aInfo.packageName) { 13076 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13077 } else if ("system".equals(componentProcessName)) { 13078 result = true; 13079 } 13080 if (DEBUG_MU) { 13081 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13082 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13083 } 13084 return result; 13085 } 13086 13087 public int bindService(IApplicationThread caller, IBinder token, 13088 Intent service, String resolvedType, 13089 IServiceConnection connection, int flags, int userId) { 13090 enforceNotIsolatedCaller("bindService"); 13091 // Refuse possible leaked file descriptors 13092 if (service != null && service.hasFileDescriptors() == true) { 13093 throw new IllegalArgumentException("File descriptors passed in Intent"); 13094 } 13095 13096 synchronized(this) { 13097 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13098 connection, flags, userId); 13099 } 13100 } 13101 13102 public boolean unbindService(IServiceConnection connection) { 13103 synchronized (this) { 13104 return mServices.unbindServiceLocked(connection); 13105 } 13106 } 13107 13108 public void publishService(IBinder token, Intent intent, IBinder service) { 13109 // Refuse possible leaked file descriptors 13110 if (intent != null && intent.hasFileDescriptors() == true) { 13111 throw new IllegalArgumentException("File descriptors passed in Intent"); 13112 } 13113 13114 synchronized(this) { 13115 if (!(token instanceof ServiceRecord)) { 13116 throw new IllegalArgumentException("Invalid service token"); 13117 } 13118 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13119 } 13120 } 13121 13122 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13123 // Refuse possible leaked file descriptors 13124 if (intent != null && intent.hasFileDescriptors() == true) { 13125 throw new IllegalArgumentException("File descriptors passed in Intent"); 13126 } 13127 13128 synchronized(this) { 13129 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13130 } 13131 } 13132 13133 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13134 synchronized(this) { 13135 if (!(token instanceof ServiceRecord)) { 13136 throw new IllegalArgumentException("Invalid service token"); 13137 } 13138 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13139 } 13140 } 13141 13142 // ========================================================= 13143 // BACKUP AND RESTORE 13144 // ========================================================= 13145 13146 // Cause the target app to be launched if necessary and its backup agent 13147 // instantiated. The backup agent will invoke backupAgentCreated() on the 13148 // activity manager to announce its creation. 13149 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13150 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13151 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13152 13153 synchronized(this) { 13154 // !!! TODO: currently no check here that we're already bound 13155 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13156 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13157 synchronized (stats) { 13158 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13159 } 13160 13161 // Backup agent is now in use, its package can't be stopped. 13162 try { 13163 AppGlobals.getPackageManager().setPackageStoppedState( 13164 app.packageName, false, UserHandle.getUserId(app.uid)); 13165 } catch (RemoteException e) { 13166 } catch (IllegalArgumentException e) { 13167 Slog.w(TAG, "Failed trying to unstop package " 13168 + app.packageName + ": " + e); 13169 } 13170 13171 BackupRecord r = new BackupRecord(ss, app, backupMode); 13172 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13173 ? new ComponentName(app.packageName, app.backupAgentName) 13174 : new ComponentName("android", "FullBackupAgent"); 13175 // startProcessLocked() returns existing proc's record if it's already running 13176 ProcessRecord proc = startProcessLocked(app.processName, app, 13177 false, 0, "backup", hostingName, false, false, false); 13178 if (proc == null) { 13179 Slog.e(TAG, "Unable to start backup agent process " + r); 13180 return false; 13181 } 13182 13183 r.app = proc; 13184 mBackupTarget = r; 13185 mBackupAppName = app.packageName; 13186 13187 // Try not to kill the process during backup 13188 updateOomAdjLocked(proc); 13189 13190 // If the process is already attached, schedule the creation of the backup agent now. 13191 // If it is not yet live, this will be done when it attaches to the framework. 13192 if (proc.thread != null) { 13193 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13194 try { 13195 proc.thread.scheduleCreateBackupAgent(app, 13196 compatibilityInfoForPackageLocked(app), backupMode); 13197 } catch (RemoteException e) { 13198 // Will time out on the backup manager side 13199 } 13200 } else { 13201 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13202 } 13203 // Invariants: at this point, the target app process exists and the application 13204 // is either already running or in the process of coming up. mBackupTarget and 13205 // mBackupAppName describe the app, so that when it binds back to the AM we 13206 // know that it's scheduled for a backup-agent operation. 13207 } 13208 13209 return true; 13210 } 13211 13212 @Override 13213 public void clearPendingBackup() { 13214 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13215 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13216 13217 synchronized (this) { 13218 mBackupTarget = null; 13219 mBackupAppName = null; 13220 } 13221 } 13222 13223 // A backup agent has just come up 13224 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13225 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13226 + " = " + agent); 13227 13228 synchronized(this) { 13229 if (!agentPackageName.equals(mBackupAppName)) { 13230 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13231 return; 13232 } 13233 } 13234 13235 long oldIdent = Binder.clearCallingIdentity(); 13236 try { 13237 IBackupManager bm = IBackupManager.Stub.asInterface( 13238 ServiceManager.getService(Context.BACKUP_SERVICE)); 13239 bm.agentConnected(agentPackageName, agent); 13240 } catch (RemoteException e) { 13241 // can't happen; the backup manager service is local 13242 } catch (Exception e) { 13243 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13244 e.printStackTrace(); 13245 } finally { 13246 Binder.restoreCallingIdentity(oldIdent); 13247 } 13248 } 13249 13250 // done with this agent 13251 public void unbindBackupAgent(ApplicationInfo appInfo) { 13252 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13253 if (appInfo == null) { 13254 Slog.w(TAG, "unbind backup agent for null app"); 13255 return; 13256 } 13257 13258 synchronized(this) { 13259 try { 13260 if (mBackupAppName == null) { 13261 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13262 return; 13263 } 13264 13265 if (!mBackupAppName.equals(appInfo.packageName)) { 13266 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13267 return; 13268 } 13269 13270 // Not backing this app up any more; reset its OOM adjustment 13271 final ProcessRecord proc = mBackupTarget.app; 13272 updateOomAdjLocked(proc); 13273 13274 // If the app crashed during backup, 'thread' will be null here 13275 if (proc.thread != null) { 13276 try { 13277 proc.thread.scheduleDestroyBackupAgent(appInfo, 13278 compatibilityInfoForPackageLocked(appInfo)); 13279 } catch (Exception e) { 13280 Slog.e(TAG, "Exception when unbinding backup agent:"); 13281 e.printStackTrace(); 13282 } 13283 } 13284 } finally { 13285 mBackupTarget = null; 13286 mBackupAppName = null; 13287 } 13288 } 13289 } 13290 // ========================================================= 13291 // BROADCASTS 13292 // ========================================================= 13293 13294 private final List getStickiesLocked(String action, IntentFilter filter, 13295 List cur, int userId) { 13296 final ContentResolver resolver = mContext.getContentResolver(); 13297 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13298 if (stickies == null) { 13299 return cur; 13300 } 13301 final ArrayList<Intent> list = stickies.get(action); 13302 if (list == null) { 13303 return cur; 13304 } 13305 int N = list.size(); 13306 for (int i=0; i<N; i++) { 13307 Intent intent = list.get(i); 13308 if (filter.match(resolver, intent, true, TAG) >= 0) { 13309 if (cur == null) { 13310 cur = new ArrayList<Intent>(); 13311 } 13312 cur.add(intent); 13313 } 13314 } 13315 return cur; 13316 } 13317 13318 boolean isPendingBroadcastProcessLocked(int pid) { 13319 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13320 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13321 } 13322 13323 void skipPendingBroadcastLocked(int pid) { 13324 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13325 for (BroadcastQueue queue : mBroadcastQueues) { 13326 queue.skipPendingBroadcastLocked(pid); 13327 } 13328 } 13329 13330 // The app just attached; send any pending broadcasts that it should receive 13331 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13332 boolean didSomething = false; 13333 for (BroadcastQueue queue : mBroadcastQueues) { 13334 didSomething |= queue.sendPendingBroadcastsLocked(app); 13335 } 13336 return didSomething; 13337 } 13338 13339 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13340 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13341 enforceNotIsolatedCaller("registerReceiver"); 13342 int callingUid; 13343 int callingPid; 13344 synchronized(this) { 13345 ProcessRecord callerApp = null; 13346 if (caller != null) { 13347 callerApp = getRecordForAppLocked(caller); 13348 if (callerApp == null) { 13349 throw new SecurityException( 13350 "Unable to find app for caller " + caller 13351 + " (pid=" + Binder.getCallingPid() 13352 + ") when registering receiver " + receiver); 13353 } 13354 if (callerApp.info.uid != Process.SYSTEM_UID && 13355 !callerApp.pkgList.containsKey(callerPackage) && 13356 !"android".equals(callerPackage)) { 13357 throw new SecurityException("Given caller package " + callerPackage 13358 + " is not running in process " + callerApp); 13359 } 13360 callingUid = callerApp.info.uid; 13361 callingPid = callerApp.pid; 13362 } else { 13363 callerPackage = null; 13364 callingUid = Binder.getCallingUid(); 13365 callingPid = Binder.getCallingPid(); 13366 } 13367 13368 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13369 true, true, "registerReceiver", callerPackage); 13370 13371 List allSticky = null; 13372 13373 // Look for any matching sticky broadcasts... 13374 Iterator actions = filter.actionsIterator(); 13375 if (actions != null) { 13376 while (actions.hasNext()) { 13377 String action = (String)actions.next(); 13378 allSticky = getStickiesLocked(action, filter, allSticky, 13379 UserHandle.USER_ALL); 13380 allSticky = getStickiesLocked(action, filter, allSticky, 13381 UserHandle.getUserId(callingUid)); 13382 } 13383 } else { 13384 allSticky = getStickiesLocked(null, filter, allSticky, 13385 UserHandle.USER_ALL); 13386 allSticky = getStickiesLocked(null, filter, allSticky, 13387 UserHandle.getUserId(callingUid)); 13388 } 13389 13390 // The first sticky in the list is returned directly back to 13391 // the client. 13392 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13393 13394 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13395 + ": " + sticky); 13396 13397 if (receiver == null) { 13398 return sticky; 13399 } 13400 13401 ReceiverList rl 13402 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13403 if (rl == null) { 13404 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13405 userId, receiver); 13406 if (rl.app != null) { 13407 rl.app.receivers.add(rl); 13408 } else { 13409 try { 13410 receiver.asBinder().linkToDeath(rl, 0); 13411 } catch (RemoteException e) { 13412 return sticky; 13413 } 13414 rl.linkedToDeath = true; 13415 } 13416 mRegisteredReceivers.put(receiver.asBinder(), rl); 13417 } else if (rl.uid != callingUid) { 13418 throw new IllegalArgumentException( 13419 "Receiver requested to register for uid " + callingUid 13420 + " was previously registered for uid " + rl.uid); 13421 } else if (rl.pid != callingPid) { 13422 throw new IllegalArgumentException( 13423 "Receiver requested to register for pid " + callingPid 13424 + " was previously registered for pid " + rl.pid); 13425 } else if (rl.userId != userId) { 13426 throw new IllegalArgumentException( 13427 "Receiver requested to register for user " + userId 13428 + " was previously registered for user " + rl.userId); 13429 } 13430 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13431 permission, callingUid, userId); 13432 rl.add(bf); 13433 if (!bf.debugCheck()) { 13434 Slog.w(TAG, "==> For Dynamic broadast"); 13435 } 13436 mReceiverResolver.addFilter(bf); 13437 13438 // Enqueue broadcasts for all existing stickies that match 13439 // this filter. 13440 if (allSticky != null) { 13441 ArrayList receivers = new ArrayList(); 13442 receivers.add(bf); 13443 13444 int N = allSticky.size(); 13445 for (int i=0; i<N; i++) { 13446 Intent intent = (Intent)allSticky.get(i); 13447 BroadcastQueue queue = broadcastQueueForIntent(intent); 13448 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13449 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13450 null, null, false, true, true, -1); 13451 queue.enqueueParallelBroadcastLocked(r); 13452 queue.scheduleBroadcastsLocked(); 13453 } 13454 } 13455 13456 return sticky; 13457 } 13458 } 13459 13460 public void unregisterReceiver(IIntentReceiver receiver) { 13461 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13462 13463 final long origId = Binder.clearCallingIdentity(); 13464 try { 13465 boolean doTrim = false; 13466 13467 synchronized(this) { 13468 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13469 if (rl != null) { 13470 if (rl.curBroadcast != null) { 13471 BroadcastRecord r = rl.curBroadcast; 13472 final boolean doNext = finishReceiverLocked( 13473 receiver.asBinder(), r.resultCode, r.resultData, 13474 r.resultExtras, r.resultAbort); 13475 if (doNext) { 13476 doTrim = true; 13477 r.queue.processNextBroadcast(false); 13478 } 13479 } 13480 13481 if (rl.app != null) { 13482 rl.app.receivers.remove(rl); 13483 } 13484 removeReceiverLocked(rl); 13485 if (rl.linkedToDeath) { 13486 rl.linkedToDeath = false; 13487 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13488 } 13489 } 13490 } 13491 13492 // If we actually concluded any broadcasts, we might now be able 13493 // to trim the recipients' apps from our working set 13494 if (doTrim) { 13495 trimApplications(); 13496 return; 13497 } 13498 13499 } finally { 13500 Binder.restoreCallingIdentity(origId); 13501 } 13502 } 13503 13504 void removeReceiverLocked(ReceiverList rl) { 13505 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13506 int N = rl.size(); 13507 for (int i=0; i<N; i++) { 13508 mReceiverResolver.removeFilter(rl.get(i)); 13509 } 13510 } 13511 13512 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13513 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13514 ProcessRecord r = mLruProcesses.get(i); 13515 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13516 try { 13517 r.thread.dispatchPackageBroadcast(cmd, packages); 13518 } catch (RemoteException ex) { 13519 } 13520 } 13521 } 13522 } 13523 13524 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13525 int[] users) { 13526 List<ResolveInfo> receivers = null; 13527 try { 13528 HashSet<ComponentName> singleUserReceivers = null; 13529 boolean scannedFirstReceivers = false; 13530 for (int user : users) { 13531 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13532 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13533 if (user != 0 && newReceivers != null) { 13534 // If this is not the primary user, we need to check for 13535 // any receivers that should be filtered out. 13536 for (int i=0; i<newReceivers.size(); i++) { 13537 ResolveInfo ri = newReceivers.get(i); 13538 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13539 newReceivers.remove(i); 13540 i--; 13541 } 13542 } 13543 } 13544 if (newReceivers != null && newReceivers.size() == 0) { 13545 newReceivers = null; 13546 } 13547 if (receivers == null) { 13548 receivers = newReceivers; 13549 } else if (newReceivers != null) { 13550 // We need to concatenate the additional receivers 13551 // found with what we have do far. This would be easy, 13552 // but we also need to de-dup any receivers that are 13553 // singleUser. 13554 if (!scannedFirstReceivers) { 13555 // Collect any single user receivers we had already retrieved. 13556 scannedFirstReceivers = true; 13557 for (int i=0; i<receivers.size(); i++) { 13558 ResolveInfo ri = receivers.get(i); 13559 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13560 ComponentName cn = new ComponentName( 13561 ri.activityInfo.packageName, ri.activityInfo.name); 13562 if (singleUserReceivers == null) { 13563 singleUserReceivers = new HashSet<ComponentName>(); 13564 } 13565 singleUserReceivers.add(cn); 13566 } 13567 } 13568 } 13569 // Add the new results to the existing results, tracking 13570 // and de-dupping single user receivers. 13571 for (int i=0; i<newReceivers.size(); i++) { 13572 ResolveInfo ri = newReceivers.get(i); 13573 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13574 ComponentName cn = new ComponentName( 13575 ri.activityInfo.packageName, ri.activityInfo.name); 13576 if (singleUserReceivers == null) { 13577 singleUserReceivers = new HashSet<ComponentName>(); 13578 } 13579 if (!singleUserReceivers.contains(cn)) { 13580 singleUserReceivers.add(cn); 13581 receivers.add(ri); 13582 } 13583 } else { 13584 receivers.add(ri); 13585 } 13586 } 13587 } 13588 } 13589 } catch (RemoteException ex) { 13590 // pm is in same process, this will never happen. 13591 } 13592 return receivers; 13593 } 13594 13595 private final int broadcastIntentLocked(ProcessRecord callerApp, 13596 String callerPackage, Intent intent, String resolvedType, 13597 IIntentReceiver resultTo, int resultCode, String resultData, 13598 Bundle map, String requiredPermission, int appOp, 13599 boolean ordered, boolean sticky, int callingPid, int callingUid, 13600 int userId) { 13601 intent = new Intent(intent); 13602 13603 // By default broadcasts do not go to stopped apps. 13604 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13605 13606 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13607 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13608 + " ordered=" + ordered + " userid=" + userId); 13609 if ((resultTo != null) && !ordered) { 13610 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13611 } 13612 13613 userId = handleIncomingUser(callingPid, callingUid, userId, 13614 true, false, "broadcast", callerPackage); 13615 13616 // Make sure that the user who is receiving this broadcast is started. 13617 // If not, we will just skip it. 13618 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13619 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13620 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13621 Slog.w(TAG, "Skipping broadcast of " + intent 13622 + ": user " + userId + " is stopped"); 13623 return ActivityManager.BROADCAST_SUCCESS; 13624 } 13625 } 13626 13627 /* 13628 * Prevent non-system code (defined here to be non-persistent 13629 * processes) from sending protected broadcasts. 13630 */ 13631 int callingAppId = UserHandle.getAppId(callingUid); 13632 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13633 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13634 callingUid == 0) { 13635 // Always okay. 13636 } else if (callerApp == null || !callerApp.persistent) { 13637 try { 13638 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13639 intent.getAction())) { 13640 String msg = "Permission Denial: not allowed to send broadcast " 13641 + intent.getAction() + " from pid=" 13642 + callingPid + ", uid=" + callingUid; 13643 Slog.w(TAG, msg); 13644 throw new SecurityException(msg); 13645 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13646 // Special case for compatibility: we don't want apps to send this, 13647 // but historically it has not been protected and apps may be using it 13648 // to poke their own app widget. So, instead of making it protected, 13649 // just limit it to the caller. 13650 if (callerApp == null) { 13651 String msg = "Permission Denial: not allowed to send broadcast " 13652 + intent.getAction() + " from unknown caller."; 13653 Slog.w(TAG, msg); 13654 throw new SecurityException(msg); 13655 } else if (intent.getComponent() != null) { 13656 // They are good enough to send to an explicit component... verify 13657 // it is being sent to the calling app. 13658 if (!intent.getComponent().getPackageName().equals( 13659 callerApp.info.packageName)) { 13660 String msg = "Permission Denial: not allowed to send broadcast " 13661 + intent.getAction() + " to " 13662 + intent.getComponent().getPackageName() + " from " 13663 + callerApp.info.packageName; 13664 Slog.w(TAG, msg); 13665 throw new SecurityException(msg); 13666 } 13667 } else { 13668 // Limit broadcast to their own package. 13669 intent.setPackage(callerApp.info.packageName); 13670 } 13671 } 13672 } catch (RemoteException e) { 13673 Slog.w(TAG, "Remote exception", e); 13674 return ActivityManager.BROADCAST_SUCCESS; 13675 } 13676 } 13677 13678 // Handle special intents: if this broadcast is from the package 13679 // manager about a package being removed, we need to remove all of 13680 // its activities from the history stack. 13681 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13682 intent.getAction()); 13683 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13684 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13685 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13686 || uidRemoved) { 13687 if (checkComponentPermission( 13688 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13689 callingPid, callingUid, -1, true) 13690 == PackageManager.PERMISSION_GRANTED) { 13691 if (uidRemoved) { 13692 final Bundle intentExtras = intent.getExtras(); 13693 final int uid = intentExtras != null 13694 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13695 if (uid >= 0) { 13696 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13697 synchronized (bs) { 13698 bs.removeUidStatsLocked(uid); 13699 } 13700 mAppOpsService.uidRemoved(uid); 13701 } 13702 } else { 13703 // If resources are unavailable just force stop all 13704 // those packages and flush the attribute cache as well. 13705 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13706 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13707 if (list != null && (list.length > 0)) { 13708 for (String pkg : list) { 13709 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13710 "storage unmount"); 13711 } 13712 sendPackageBroadcastLocked( 13713 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13714 } 13715 } else { 13716 Uri data = intent.getData(); 13717 String ssp; 13718 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13719 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13720 intent.getAction()); 13721 boolean fullUninstall = removed && 13722 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13723 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13724 forceStopPackageLocked(ssp, UserHandle.getAppId( 13725 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13726 false, fullUninstall, userId, 13727 removed ? "pkg removed" : "pkg changed"); 13728 } 13729 if (removed) { 13730 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13731 new String[] {ssp}, userId); 13732 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13733 mAppOpsService.packageRemoved( 13734 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13735 13736 // Remove all permissions granted from/to this package 13737 removeUriPermissionsForPackageLocked(ssp, userId, true); 13738 } 13739 } 13740 } 13741 } 13742 } 13743 } else { 13744 String msg = "Permission Denial: " + intent.getAction() 13745 + " broadcast from " + callerPackage + " (pid=" + callingPid 13746 + ", uid=" + callingUid + ")" 13747 + " requires " 13748 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13749 Slog.w(TAG, msg); 13750 throw new SecurityException(msg); 13751 } 13752 13753 // Special case for adding a package: by default turn on compatibility 13754 // mode. 13755 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13756 Uri data = intent.getData(); 13757 String ssp; 13758 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13759 mCompatModePackages.handlePackageAddedLocked(ssp, 13760 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13761 } 13762 } 13763 13764 /* 13765 * If this is the time zone changed action, queue up a message that will reset the timezone 13766 * of all currently running processes. This message will get queued up before the broadcast 13767 * happens. 13768 */ 13769 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13770 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13771 } 13772 13773 /* 13774 * If the user set the time, let all running processes know. 13775 */ 13776 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13777 final int is24Hour = intent.getBooleanExtra( 13778 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13779 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13780 } 13781 13782 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13783 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13784 } 13785 13786 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13787 ProxyInfo proxy = intent.getParcelableExtra("proxy"); 13788 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13789 } 13790 13791 // Add to the sticky list if requested. 13792 if (sticky) { 13793 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13794 callingPid, callingUid) 13795 != PackageManager.PERMISSION_GRANTED) { 13796 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13797 + callingPid + ", uid=" + callingUid 13798 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13799 Slog.w(TAG, msg); 13800 throw new SecurityException(msg); 13801 } 13802 if (requiredPermission != null) { 13803 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13804 + " and enforce permission " + requiredPermission); 13805 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13806 } 13807 if (intent.getComponent() != null) { 13808 throw new SecurityException( 13809 "Sticky broadcasts can't target a specific component"); 13810 } 13811 // We use userId directly here, since the "all" target is maintained 13812 // as a separate set of sticky broadcasts. 13813 if (userId != UserHandle.USER_ALL) { 13814 // But first, if this is not a broadcast to all users, then 13815 // make sure it doesn't conflict with an existing broadcast to 13816 // all users. 13817 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13818 UserHandle.USER_ALL); 13819 if (stickies != null) { 13820 ArrayList<Intent> list = stickies.get(intent.getAction()); 13821 if (list != null) { 13822 int N = list.size(); 13823 int i; 13824 for (i=0; i<N; i++) { 13825 if (intent.filterEquals(list.get(i))) { 13826 throw new IllegalArgumentException( 13827 "Sticky broadcast " + intent + " for user " 13828 + userId + " conflicts with existing global broadcast"); 13829 } 13830 } 13831 } 13832 } 13833 } 13834 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13835 if (stickies == null) { 13836 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13837 mStickyBroadcasts.put(userId, stickies); 13838 } 13839 ArrayList<Intent> list = stickies.get(intent.getAction()); 13840 if (list == null) { 13841 list = new ArrayList<Intent>(); 13842 stickies.put(intent.getAction(), list); 13843 } 13844 int N = list.size(); 13845 int i; 13846 for (i=0; i<N; i++) { 13847 if (intent.filterEquals(list.get(i))) { 13848 // This sticky already exists, replace it. 13849 list.set(i, new Intent(intent)); 13850 break; 13851 } 13852 } 13853 if (i >= N) { 13854 list.add(new Intent(intent)); 13855 } 13856 } 13857 13858 int[] users; 13859 if (userId == UserHandle.USER_ALL) { 13860 // Caller wants broadcast to go to all started users. 13861 users = mStartedUserArray; 13862 } else { 13863 // Caller wants broadcast to go to one specific user. 13864 users = new int[] {userId}; 13865 } 13866 13867 // Figure out who all will receive this broadcast. 13868 List receivers = null; 13869 List<BroadcastFilter> registeredReceivers = null; 13870 // Need to resolve the intent to interested receivers... 13871 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13872 == 0) { 13873 receivers = collectReceiverComponents(intent, resolvedType, users); 13874 } 13875 if (intent.getComponent() == null) { 13876 registeredReceivers = mReceiverResolver.queryIntent(intent, 13877 resolvedType, false, userId); 13878 } 13879 13880 final boolean replacePending = 13881 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13882 13883 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13884 + " replacePending=" + replacePending); 13885 13886 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13887 if (!ordered && NR > 0) { 13888 // If we are not serializing this broadcast, then send the 13889 // registered receivers separately so they don't wait for the 13890 // components to be launched. 13891 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13892 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13893 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13894 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13895 ordered, sticky, false, userId); 13896 if (DEBUG_BROADCAST) Slog.v( 13897 TAG, "Enqueueing parallel broadcast " + r); 13898 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13899 if (!replaced) { 13900 queue.enqueueParallelBroadcastLocked(r); 13901 queue.scheduleBroadcastsLocked(); 13902 } 13903 registeredReceivers = null; 13904 NR = 0; 13905 } 13906 13907 // Merge into one list. 13908 int ir = 0; 13909 if (receivers != null) { 13910 // A special case for PACKAGE_ADDED: do not allow the package 13911 // being added to see this broadcast. This prevents them from 13912 // using this as a back door to get run as soon as they are 13913 // installed. Maybe in the future we want to have a special install 13914 // broadcast or such for apps, but we'd like to deliberately make 13915 // this decision. 13916 String skipPackages[] = null; 13917 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13918 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13919 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13920 Uri data = intent.getData(); 13921 if (data != null) { 13922 String pkgName = data.getSchemeSpecificPart(); 13923 if (pkgName != null) { 13924 skipPackages = new String[] { pkgName }; 13925 } 13926 } 13927 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13928 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13929 } 13930 if (skipPackages != null && (skipPackages.length > 0)) { 13931 for (String skipPackage : skipPackages) { 13932 if (skipPackage != null) { 13933 int NT = receivers.size(); 13934 for (int it=0; it<NT; it++) { 13935 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13936 if (curt.activityInfo.packageName.equals(skipPackage)) { 13937 receivers.remove(it); 13938 it--; 13939 NT--; 13940 } 13941 } 13942 } 13943 } 13944 } 13945 13946 int NT = receivers != null ? receivers.size() : 0; 13947 int it = 0; 13948 ResolveInfo curt = null; 13949 BroadcastFilter curr = null; 13950 while (it < NT && ir < NR) { 13951 if (curt == null) { 13952 curt = (ResolveInfo)receivers.get(it); 13953 } 13954 if (curr == null) { 13955 curr = registeredReceivers.get(ir); 13956 } 13957 if (curr.getPriority() >= curt.priority) { 13958 // Insert this broadcast record into the final list. 13959 receivers.add(it, curr); 13960 ir++; 13961 curr = null; 13962 it++; 13963 NT++; 13964 } else { 13965 // Skip to the next ResolveInfo in the final list. 13966 it++; 13967 curt = null; 13968 } 13969 } 13970 } 13971 while (ir < NR) { 13972 if (receivers == null) { 13973 receivers = new ArrayList(); 13974 } 13975 receivers.add(registeredReceivers.get(ir)); 13976 ir++; 13977 } 13978 13979 if ((receivers != null && receivers.size() > 0) 13980 || resultTo != null) { 13981 BroadcastQueue queue = broadcastQueueForIntent(intent); 13982 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13983 callerPackage, callingPid, callingUid, resolvedType, 13984 requiredPermission, appOp, receivers, resultTo, resultCode, 13985 resultData, map, ordered, sticky, false, userId); 13986 if (DEBUG_BROADCAST) Slog.v( 13987 TAG, "Enqueueing ordered broadcast " + r 13988 + ": prev had " + queue.mOrderedBroadcasts.size()); 13989 if (DEBUG_BROADCAST) { 13990 int seq = r.intent.getIntExtra("seq", -1); 13991 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13992 } 13993 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13994 if (!replaced) { 13995 queue.enqueueOrderedBroadcastLocked(r); 13996 queue.scheduleBroadcastsLocked(); 13997 } 13998 } 13999 14000 return ActivityManager.BROADCAST_SUCCESS; 14001 } 14002 14003 final Intent verifyBroadcastLocked(Intent intent) { 14004 // Refuse possible leaked file descriptors 14005 if (intent != null && intent.hasFileDescriptors() == true) { 14006 throw new IllegalArgumentException("File descriptors passed in Intent"); 14007 } 14008 14009 int flags = intent.getFlags(); 14010 14011 if (!mProcessesReady) { 14012 // if the caller really truly claims to know what they're doing, go 14013 // ahead and allow the broadcast without launching any receivers 14014 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14015 intent = new Intent(intent); 14016 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14017 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14018 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14019 + " before boot completion"); 14020 throw new IllegalStateException("Cannot broadcast before boot completed"); 14021 } 14022 } 14023 14024 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14025 throw new IllegalArgumentException( 14026 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14027 } 14028 14029 return intent; 14030 } 14031 14032 public final int broadcastIntent(IApplicationThread caller, 14033 Intent intent, String resolvedType, IIntentReceiver resultTo, 14034 int resultCode, String resultData, Bundle map, 14035 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14036 enforceNotIsolatedCaller("broadcastIntent"); 14037 synchronized(this) { 14038 intent = verifyBroadcastLocked(intent); 14039 14040 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14041 final int callingPid = Binder.getCallingPid(); 14042 final int callingUid = Binder.getCallingUid(); 14043 final long origId = Binder.clearCallingIdentity(); 14044 int res = broadcastIntentLocked(callerApp, 14045 callerApp != null ? callerApp.info.packageName : null, 14046 intent, resolvedType, resultTo, 14047 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14048 callingPid, callingUid, userId); 14049 Binder.restoreCallingIdentity(origId); 14050 return res; 14051 } 14052 } 14053 14054 int broadcastIntentInPackage(String packageName, int uid, 14055 Intent intent, String resolvedType, IIntentReceiver resultTo, 14056 int resultCode, String resultData, Bundle map, 14057 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14058 synchronized(this) { 14059 intent = verifyBroadcastLocked(intent); 14060 14061 final long origId = Binder.clearCallingIdentity(); 14062 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14063 resultTo, resultCode, resultData, map, requiredPermission, 14064 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14065 Binder.restoreCallingIdentity(origId); 14066 return res; 14067 } 14068 } 14069 14070 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14071 // Refuse possible leaked file descriptors 14072 if (intent != null && intent.hasFileDescriptors() == true) { 14073 throw new IllegalArgumentException("File descriptors passed in Intent"); 14074 } 14075 14076 userId = handleIncomingUser(Binder.getCallingPid(), 14077 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14078 14079 synchronized(this) { 14080 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14081 != PackageManager.PERMISSION_GRANTED) { 14082 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14083 + Binder.getCallingPid() 14084 + ", uid=" + Binder.getCallingUid() 14085 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14086 Slog.w(TAG, msg); 14087 throw new SecurityException(msg); 14088 } 14089 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14090 if (stickies != null) { 14091 ArrayList<Intent> list = stickies.get(intent.getAction()); 14092 if (list != null) { 14093 int N = list.size(); 14094 int i; 14095 for (i=0; i<N; i++) { 14096 if (intent.filterEquals(list.get(i))) { 14097 list.remove(i); 14098 break; 14099 } 14100 } 14101 if (list.size() <= 0) { 14102 stickies.remove(intent.getAction()); 14103 } 14104 } 14105 if (stickies.size() <= 0) { 14106 mStickyBroadcasts.remove(userId); 14107 } 14108 } 14109 } 14110 } 14111 14112 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14113 String resultData, Bundle resultExtras, boolean resultAbort) { 14114 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14115 if (r == null) { 14116 Slog.w(TAG, "finishReceiver called but not found on queue"); 14117 return false; 14118 } 14119 14120 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14121 } 14122 14123 void backgroundServicesFinishedLocked(int userId) { 14124 for (BroadcastQueue queue : mBroadcastQueues) { 14125 queue.backgroundServicesFinishedLocked(userId); 14126 } 14127 } 14128 14129 public void finishReceiver(IBinder who, int resultCode, String resultData, 14130 Bundle resultExtras, boolean resultAbort) { 14131 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14132 14133 // Refuse possible leaked file descriptors 14134 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14135 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14136 } 14137 14138 final long origId = Binder.clearCallingIdentity(); 14139 try { 14140 boolean doNext = false; 14141 BroadcastRecord r; 14142 14143 synchronized(this) { 14144 r = broadcastRecordForReceiverLocked(who); 14145 if (r != null) { 14146 doNext = r.queue.finishReceiverLocked(r, resultCode, 14147 resultData, resultExtras, resultAbort, true); 14148 } 14149 } 14150 14151 if (doNext) { 14152 r.queue.processNextBroadcast(false); 14153 } 14154 trimApplications(); 14155 } finally { 14156 Binder.restoreCallingIdentity(origId); 14157 } 14158 } 14159 14160 // ========================================================= 14161 // INSTRUMENTATION 14162 // ========================================================= 14163 14164 public boolean startInstrumentation(ComponentName className, 14165 String profileFile, int flags, Bundle arguments, 14166 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14167 int userId) { 14168 enforceNotIsolatedCaller("startInstrumentation"); 14169 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14170 userId, false, true, "startInstrumentation", null); 14171 // Refuse possible leaked file descriptors 14172 if (arguments != null && arguments.hasFileDescriptors()) { 14173 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14174 } 14175 14176 synchronized(this) { 14177 InstrumentationInfo ii = null; 14178 ApplicationInfo ai = null; 14179 try { 14180 ii = mContext.getPackageManager().getInstrumentationInfo( 14181 className, STOCK_PM_FLAGS); 14182 ai = AppGlobals.getPackageManager().getApplicationInfo( 14183 ii.targetPackage, STOCK_PM_FLAGS, userId); 14184 } catch (PackageManager.NameNotFoundException e) { 14185 } catch (RemoteException e) { 14186 } 14187 if (ii == null) { 14188 reportStartInstrumentationFailure(watcher, className, 14189 "Unable to find instrumentation info for: " + className); 14190 return false; 14191 } 14192 if (ai == null) { 14193 reportStartInstrumentationFailure(watcher, className, 14194 "Unable to find instrumentation target package: " + ii.targetPackage); 14195 return false; 14196 } 14197 14198 int match = mContext.getPackageManager().checkSignatures( 14199 ii.targetPackage, ii.packageName); 14200 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14201 String msg = "Permission Denial: starting instrumentation " 14202 + className + " from pid=" 14203 + Binder.getCallingPid() 14204 + ", uid=" + Binder.getCallingPid() 14205 + " not allowed because package " + ii.packageName 14206 + " does not have a signature matching the target " 14207 + ii.targetPackage; 14208 reportStartInstrumentationFailure(watcher, className, msg); 14209 throw new SecurityException(msg); 14210 } 14211 14212 final long origId = Binder.clearCallingIdentity(); 14213 // Instrumentation can kill and relaunch even persistent processes 14214 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14215 "start instr"); 14216 ProcessRecord app = addAppLocked(ai, false); 14217 app.instrumentationClass = className; 14218 app.instrumentationInfo = ai; 14219 app.instrumentationProfileFile = profileFile; 14220 app.instrumentationArguments = arguments; 14221 app.instrumentationWatcher = watcher; 14222 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14223 app.instrumentationResultClass = className; 14224 Binder.restoreCallingIdentity(origId); 14225 } 14226 14227 return true; 14228 } 14229 14230 /** 14231 * Report errors that occur while attempting to start Instrumentation. Always writes the 14232 * error to the logs, but if somebody is watching, send the report there too. This enables 14233 * the "am" command to report errors with more information. 14234 * 14235 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14236 * @param cn The component name of the instrumentation. 14237 * @param report The error report. 14238 */ 14239 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14240 ComponentName cn, String report) { 14241 Slog.w(TAG, report); 14242 try { 14243 if (watcher != null) { 14244 Bundle results = new Bundle(); 14245 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14246 results.putString("Error", report); 14247 watcher.instrumentationStatus(cn, -1, results); 14248 } 14249 } catch (RemoteException e) { 14250 Slog.w(TAG, e); 14251 } 14252 } 14253 14254 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14255 if (app.instrumentationWatcher != null) { 14256 try { 14257 // NOTE: IInstrumentationWatcher *must* be oneway here 14258 app.instrumentationWatcher.instrumentationFinished( 14259 app.instrumentationClass, 14260 resultCode, 14261 results); 14262 } catch (RemoteException e) { 14263 } 14264 } 14265 if (app.instrumentationUiAutomationConnection != null) { 14266 try { 14267 app.instrumentationUiAutomationConnection.shutdown(); 14268 } catch (RemoteException re) { 14269 /* ignore */ 14270 } 14271 // Only a UiAutomation can set this flag and now that 14272 // it is finished we make sure it is reset to its default. 14273 mUserIsMonkey = false; 14274 } 14275 app.instrumentationWatcher = null; 14276 app.instrumentationUiAutomationConnection = null; 14277 app.instrumentationClass = null; 14278 app.instrumentationInfo = null; 14279 app.instrumentationProfileFile = null; 14280 app.instrumentationArguments = null; 14281 14282 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14283 "finished inst"); 14284 } 14285 14286 public void finishInstrumentation(IApplicationThread target, 14287 int resultCode, Bundle results) { 14288 int userId = UserHandle.getCallingUserId(); 14289 // Refuse possible leaked file descriptors 14290 if (results != null && results.hasFileDescriptors()) { 14291 throw new IllegalArgumentException("File descriptors passed in Intent"); 14292 } 14293 14294 synchronized(this) { 14295 ProcessRecord app = getRecordForAppLocked(target); 14296 if (app == null) { 14297 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14298 return; 14299 } 14300 final long origId = Binder.clearCallingIdentity(); 14301 finishInstrumentationLocked(app, resultCode, results); 14302 Binder.restoreCallingIdentity(origId); 14303 } 14304 } 14305 14306 // ========================================================= 14307 // CONFIGURATION 14308 // ========================================================= 14309 14310 public ConfigurationInfo getDeviceConfigurationInfo() { 14311 ConfigurationInfo config = new ConfigurationInfo(); 14312 synchronized (this) { 14313 config.reqTouchScreen = mConfiguration.touchscreen; 14314 config.reqKeyboardType = mConfiguration.keyboard; 14315 config.reqNavigation = mConfiguration.navigation; 14316 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14317 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14318 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14319 } 14320 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14321 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14322 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14323 } 14324 config.reqGlEsVersion = GL_ES_VERSION; 14325 } 14326 return config; 14327 } 14328 14329 ActivityStack getFocusedStack() { 14330 return mStackSupervisor.getFocusedStack(); 14331 } 14332 14333 public Configuration getConfiguration() { 14334 Configuration ci; 14335 synchronized(this) { 14336 ci = new Configuration(mConfiguration); 14337 } 14338 return ci; 14339 } 14340 14341 public void updatePersistentConfiguration(Configuration values) { 14342 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14343 "updateConfiguration()"); 14344 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14345 "updateConfiguration()"); 14346 if (values == null) { 14347 throw new NullPointerException("Configuration must not be null"); 14348 } 14349 14350 synchronized(this) { 14351 final long origId = Binder.clearCallingIdentity(); 14352 updateConfigurationLocked(values, null, true, false); 14353 Binder.restoreCallingIdentity(origId); 14354 } 14355 } 14356 14357 public void updateConfiguration(Configuration values) { 14358 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14359 "updateConfiguration()"); 14360 14361 synchronized(this) { 14362 if (values == null && mWindowManager != null) { 14363 // sentinel: fetch the current configuration from the window manager 14364 values = mWindowManager.computeNewConfiguration(); 14365 } 14366 14367 if (mWindowManager != null) { 14368 mProcessList.applyDisplaySize(mWindowManager); 14369 } 14370 14371 final long origId = Binder.clearCallingIdentity(); 14372 if (values != null) { 14373 Settings.System.clearConfiguration(values); 14374 } 14375 updateConfigurationLocked(values, null, false, false); 14376 Binder.restoreCallingIdentity(origId); 14377 } 14378 } 14379 14380 /** 14381 * Do either or both things: (1) change the current configuration, and (2) 14382 * make sure the given activity is running with the (now) current 14383 * configuration. Returns true if the activity has been left running, or 14384 * false if <var>starting</var> is being destroyed to match the new 14385 * configuration. 14386 * @param persistent TODO 14387 */ 14388 boolean updateConfigurationLocked(Configuration values, 14389 ActivityRecord starting, boolean persistent, boolean initLocale) { 14390 int changes = 0; 14391 14392 if (values != null) { 14393 Configuration newConfig = new Configuration(mConfiguration); 14394 changes = newConfig.updateFrom(values); 14395 if (changes != 0) { 14396 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14397 Slog.i(TAG, "Updating configuration to: " + values); 14398 } 14399 14400 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14401 14402 if (values.locale != null && !initLocale) { 14403 saveLocaleLocked(values.locale, 14404 !values.locale.equals(mConfiguration.locale), 14405 values.userSetLocale); 14406 } 14407 14408 mConfigurationSeq++; 14409 if (mConfigurationSeq <= 0) { 14410 mConfigurationSeq = 1; 14411 } 14412 newConfig.seq = mConfigurationSeq; 14413 mConfiguration = newConfig; 14414 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14415 mUsageStatsService.noteStartConfig(newConfig); 14416 14417 final Configuration configCopy = new Configuration(mConfiguration); 14418 14419 // TODO: If our config changes, should we auto dismiss any currently 14420 // showing dialogs? 14421 mShowDialogs = shouldShowDialogs(newConfig); 14422 14423 AttributeCache ac = AttributeCache.instance(); 14424 if (ac != null) { 14425 ac.updateConfiguration(configCopy); 14426 } 14427 14428 // Make sure all resources in our process are updated 14429 // right now, so that anyone who is going to retrieve 14430 // resource values after we return will be sure to get 14431 // the new ones. This is especially important during 14432 // boot, where the first config change needs to guarantee 14433 // all resources have that config before following boot 14434 // code is executed. 14435 mSystemThread.applyConfigurationToResources(configCopy); 14436 14437 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14438 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14439 msg.obj = new Configuration(configCopy); 14440 mHandler.sendMessage(msg); 14441 } 14442 14443 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14444 ProcessRecord app = mLruProcesses.get(i); 14445 try { 14446 if (app.thread != null) { 14447 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14448 + app.processName + " new config " + mConfiguration); 14449 app.thread.scheduleConfigurationChanged(configCopy); 14450 } 14451 } catch (Exception e) { 14452 } 14453 } 14454 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14455 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14456 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14457 | Intent.FLAG_RECEIVER_FOREGROUND); 14458 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14459 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14460 Process.SYSTEM_UID, UserHandle.USER_ALL); 14461 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14462 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14463 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14464 broadcastIntentLocked(null, null, intent, 14465 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14466 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14467 } 14468 } 14469 } 14470 14471 boolean kept = true; 14472 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14473 // mainStack is null during startup. 14474 if (mainStack != null) { 14475 if (changes != 0 && starting == null) { 14476 // If the configuration changed, and the caller is not already 14477 // in the process of starting an activity, then find the top 14478 // activity to check if its configuration needs to change. 14479 starting = mainStack.topRunningActivityLocked(null); 14480 } 14481 14482 if (starting != null) { 14483 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14484 // And we need to make sure at this point that all other activities 14485 // are made visible with the correct configuration. 14486 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14487 } 14488 } 14489 14490 if (values != null && mWindowManager != null) { 14491 mWindowManager.setNewConfiguration(mConfiguration); 14492 } 14493 14494 return kept; 14495 } 14496 14497 /** 14498 * Decide based on the configuration whether we should shouw the ANR, 14499 * crash, etc dialogs. The idea is that if there is no affordnace to 14500 * press the on-screen buttons, we shouldn't show the dialog. 14501 * 14502 * A thought: SystemUI might also want to get told about this, the Power 14503 * dialog / global actions also might want different behaviors. 14504 */ 14505 private static final boolean shouldShowDialogs(Configuration config) { 14506 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14507 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14508 } 14509 14510 /** 14511 * Save the locale. You must be inside a synchronized (this) block. 14512 */ 14513 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14514 if(isDiff) { 14515 SystemProperties.set("user.language", l.getLanguage()); 14516 SystemProperties.set("user.region", l.getCountry()); 14517 } 14518 14519 if(isPersist) { 14520 SystemProperties.set("persist.sys.language", l.getLanguage()); 14521 SystemProperties.set("persist.sys.country", l.getCountry()); 14522 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14523 } 14524 } 14525 14526 @Override 14527 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14528 ActivityRecord srec = ActivityRecord.forToken(token); 14529 return srec != null && srec.task.affinity != null && 14530 srec.task.affinity.equals(destAffinity); 14531 } 14532 14533 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14534 Intent resultData) { 14535 14536 synchronized (this) { 14537 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14538 if (stack != null) { 14539 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14540 } 14541 return false; 14542 } 14543 } 14544 14545 public int getLaunchedFromUid(IBinder activityToken) { 14546 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14547 if (srec == null) { 14548 return -1; 14549 } 14550 return srec.launchedFromUid; 14551 } 14552 14553 public String getLaunchedFromPackage(IBinder activityToken) { 14554 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14555 if (srec == null) { 14556 return null; 14557 } 14558 return srec.launchedFromPackage; 14559 } 14560 14561 // ========================================================= 14562 // LIFETIME MANAGEMENT 14563 // ========================================================= 14564 14565 // Returns which broadcast queue the app is the current [or imminent] receiver 14566 // on, or 'null' if the app is not an active broadcast recipient. 14567 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14568 BroadcastRecord r = app.curReceiver; 14569 if (r != null) { 14570 return r.queue; 14571 } 14572 14573 // It's not the current receiver, but it might be starting up to become one 14574 synchronized (this) { 14575 for (BroadcastQueue queue : mBroadcastQueues) { 14576 r = queue.mPendingBroadcast; 14577 if (r != null && r.curApp == app) { 14578 // found it; report which queue it's in 14579 return queue; 14580 } 14581 } 14582 } 14583 14584 return null; 14585 } 14586 14587 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14588 boolean doingAll, long now) { 14589 if (mAdjSeq == app.adjSeq) { 14590 // This adjustment has already been computed. 14591 return app.curRawAdj; 14592 } 14593 14594 if (app.thread == null) { 14595 app.adjSeq = mAdjSeq; 14596 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14597 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14598 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14599 } 14600 14601 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14602 app.adjSource = null; 14603 app.adjTarget = null; 14604 app.empty = false; 14605 app.cached = false; 14606 14607 final int activitiesSize = app.activities.size(); 14608 14609 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14610 // The max adjustment doesn't allow this app to be anything 14611 // below foreground, so it is not worth doing work for it. 14612 app.adjType = "fixed"; 14613 app.adjSeq = mAdjSeq; 14614 app.curRawAdj = app.maxAdj; 14615 app.foregroundActivities = false; 14616 app.keeping = true; 14617 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14618 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14619 // System processes can do UI, and when they do we want to have 14620 // them trim their memory after the user leaves the UI. To 14621 // facilitate this, here we need to determine whether or not it 14622 // is currently showing UI. 14623 app.systemNoUi = true; 14624 if (app == TOP_APP) { 14625 app.systemNoUi = false; 14626 } else if (activitiesSize > 0) { 14627 for (int j = 0; j < activitiesSize; j++) { 14628 final ActivityRecord r = app.activities.get(j); 14629 if (r.visible) { 14630 app.systemNoUi = false; 14631 } 14632 } 14633 } 14634 if (!app.systemNoUi) { 14635 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14636 } 14637 return (app.curAdj=app.maxAdj); 14638 } 14639 14640 app.keeping = false; 14641 app.systemNoUi = false; 14642 14643 // Determine the importance of the process, starting with most 14644 // important to least, and assign an appropriate OOM adjustment. 14645 int adj; 14646 int schedGroup; 14647 int procState; 14648 boolean foregroundActivities = false; 14649 boolean interesting = false; 14650 BroadcastQueue queue; 14651 if (app == TOP_APP) { 14652 // The last app on the list is the foreground app. 14653 adj = ProcessList.FOREGROUND_APP_ADJ; 14654 schedGroup = Process.THREAD_GROUP_DEFAULT; 14655 app.adjType = "top-activity"; 14656 foregroundActivities = true; 14657 interesting = true; 14658 procState = ActivityManager.PROCESS_STATE_TOP; 14659 } else if (app.instrumentationClass != null) { 14660 // Don't want to kill running instrumentation. 14661 adj = ProcessList.FOREGROUND_APP_ADJ; 14662 schedGroup = Process.THREAD_GROUP_DEFAULT; 14663 app.adjType = "instrumentation"; 14664 interesting = true; 14665 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14666 } else if ((queue = isReceivingBroadcast(app)) != null) { 14667 // An app that is currently receiving a broadcast also 14668 // counts as being in the foreground for OOM killer purposes. 14669 // It's placed in a sched group based on the nature of the 14670 // broadcast as reflected by which queue it's active in. 14671 adj = ProcessList.FOREGROUND_APP_ADJ; 14672 schedGroup = (queue == mFgBroadcastQueue) 14673 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14674 app.adjType = "broadcast"; 14675 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14676 } else if (app.executingServices.size() > 0) { 14677 // An app that is currently executing a service callback also 14678 // counts as being in the foreground. 14679 adj = ProcessList.FOREGROUND_APP_ADJ; 14680 schedGroup = app.execServicesFg ? 14681 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14682 app.adjType = "exec-service"; 14683 procState = ActivityManager.PROCESS_STATE_SERVICE; 14684 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14685 } else { 14686 // As far as we know the process is empty. We may change our mind later. 14687 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14688 // At this point we don't actually know the adjustment. Use the cached adj 14689 // value that the caller wants us to. 14690 adj = cachedAdj; 14691 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14692 app.cached = true; 14693 app.empty = true; 14694 app.adjType = "cch-empty"; 14695 } 14696 14697 // Examine all activities if not already foreground. 14698 if (!foregroundActivities && activitiesSize > 0) { 14699 for (int j = 0; j < activitiesSize; j++) { 14700 final ActivityRecord r = app.activities.get(j); 14701 if (r.app != app) { 14702 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14703 + app + "?!?"); 14704 continue; 14705 } 14706 if (r.visible) { 14707 // App has a visible activity; only upgrade adjustment. 14708 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14709 adj = ProcessList.VISIBLE_APP_ADJ; 14710 app.adjType = "visible"; 14711 } 14712 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14713 procState = ActivityManager.PROCESS_STATE_TOP; 14714 } 14715 schedGroup = Process.THREAD_GROUP_DEFAULT; 14716 app.cached = false; 14717 app.empty = false; 14718 foregroundActivities = true; 14719 break; 14720 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14721 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14722 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14723 app.adjType = "pausing"; 14724 } 14725 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14726 procState = ActivityManager.PROCESS_STATE_TOP; 14727 } 14728 schedGroup = Process.THREAD_GROUP_DEFAULT; 14729 app.cached = false; 14730 app.empty = false; 14731 foregroundActivities = true; 14732 } else if (r.state == ActivityState.STOPPING) { 14733 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14734 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14735 app.adjType = "stopping"; 14736 } 14737 // For the process state, we will at this point consider the 14738 // process to be cached. It will be cached either as an activity 14739 // or empty depending on whether the activity is finishing. We do 14740 // this so that we can treat the process as cached for purposes of 14741 // memory trimming (determing current memory level, trim command to 14742 // send to process) since there can be an arbitrary number of stopping 14743 // processes and they should soon all go into the cached state. 14744 if (!r.finishing) { 14745 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14746 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14747 } 14748 } 14749 app.cached = false; 14750 app.empty = false; 14751 foregroundActivities = true; 14752 } else { 14753 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14754 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14755 app.adjType = "cch-act"; 14756 } 14757 } 14758 } 14759 } 14760 14761 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14762 if (app.foregroundServices) { 14763 // The user is aware of this app, so make it visible. 14764 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14765 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14766 app.cached = false; 14767 app.adjType = "fg-service"; 14768 schedGroup = Process.THREAD_GROUP_DEFAULT; 14769 } else if (app.forcingToForeground != null) { 14770 // The user is aware of this app, so make it visible. 14771 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14772 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14773 app.cached = false; 14774 app.adjType = "force-fg"; 14775 app.adjSource = app.forcingToForeground; 14776 schedGroup = Process.THREAD_GROUP_DEFAULT; 14777 } 14778 } 14779 14780 if (app.foregroundServices) { 14781 interesting = true; 14782 } 14783 14784 if (app == mHeavyWeightProcess) { 14785 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14786 // We don't want to kill the current heavy-weight process. 14787 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14788 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14789 app.cached = false; 14790 app.adjType = "heavy"; 14791 } 14792 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14793 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14794 } 14795 } 14796 14797 if (app == mHomeProcess) { 14798 if (adj > ProcessList.HOME_APP_ADJ) { 14799 // This process is hosting what we currently consider to be the 14800 // home app, so we don't want to let it go into the background. 14801 adj = ProcessList.HOME_APP_ADJ; 14802 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14803 app.cached = false; 14804 app.adjType = "home"; 14805 } 14806 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14807 procState = ActivityManager.PROCESS_STATE_HOME; 14808 } 14809 } 14810 14811 if (app == mPreviousProcess && app.activities.size() > 0) { 14812 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14813 // This was the previous process that showed UI to the user. 14814 // We want to try to keep it around more aggressively, to give 14815 // a good experience around switching between two apps. 14816 adj = ProcessList.PREVIOUS_APP_ADJ; 14817 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14818 app.cached = false; 14819 app.adjType = "previous"; 14820 } 14821 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14822 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14823 } 14824 } 14825 14826 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14827 + " reason=" + app.adjType); 14828 14829 // By default, we use the computed adjustment. It may be changed if 14830 // there are applications dependent on our services or providers, but 14831 // this gives us a baseline and makes sure we don't get into an 14832 // infinite recursion. 14833 app.adjSeq = mAdjSeq; 14834 app.curRawAdj = adj; 14835 app.hasStartedServices = false; 14836 14837 if (mBackupTarget != null && app == mBackupTarget.app) { 14838 // If possible we want to avoid killing apps while they're being backed up 14839 if (adj > ProcessList.BACKUP_APP_ADJ) { 14840 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14841 adj = ProcessList.BACKUP_APP_ADJ; 14842 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14843 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14844 } 14845 app.adjType = "backup"; 14846 app.cached = false; 14847 } 14848 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14849 procState = ActivityManager.PROCESS_STATE_BACKUP; 14850 } 14851 } 14852 14853 boolean mayBeTop = false; 14854 14855 for (int is = app.services.size()-1; 14856 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14857 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14858 || procState > ActivityManager.PROCESS_STATE_TOP); 14859 is--) { 14860 ServiceRecord s = app.services.valueAt(is); 14861 if (s.startRequested) { 14862 app.hasStartedServices = true; 14863 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14864 procState = ActivityManager.PROCESS_STATE_SERVICE; 14865 } 14866 if (app.hasShownUi && app != mHomeProcess) { 14867 // If this process has shown some UI, let it immediately 14868 // go to the LRU list because it may be pretty heavy with 14869 // UI stuff. We'll tag it with a label just to help 14870 // debug and understand what is going on. 14871 if (adj > ProcessList.SERVICE_ADJ) { 14872 app.adjType = "cch-started-ui-services"; 14873 } 14874 } else { 14875 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14876 // This service has seen some activity within 14877 // recent memory, so we will keep its process ahead 14878 // of the background processes. 14879 if (adj > ProcessList.SERVICE_ADJ) { 14880 adj = ProcessList.SERVICE_ADJ; 14881 app.adjType = "started-services"; 14882 app.cached = false; 14883 } 14884 } 14885 // If we have let the service slide into the background 14886 // state, still have some text describing what it is doing 14887 // even though the service no longer has an impact. 14888 if (adj > ProcessList.SERVICE_ADJ) { 14889 app.adjType = "cch-started-services"; 14890 } 14891 } 14892 // Don't kill this process because it is doing work; it 14893 // has said it is doing work. 14894 app.keeping = true; 14895 } 14896 for (int conni = s.connections.size()-1; 14897 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14898 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14899 || procState > ActivityManager.PROCESS_STATE_TOP); 14900 conni--) { 14901 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14902 for (int i = 0; 14903 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14904 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14905 || procState > ActivityManager.PROCESS_STATE_TOP); 14906 i++) { 14907 // XXX should compute this based on the max of 14908 // all connected clients. 14909 ConnectionRecord cr = clist.get(i); 14910 if (cr.binding.client == app) { 14911 // Binding to ourself is not interesting. 14912 continue; 14913 } 14914 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14915 ProcessRecord client = cr.binding.client; 14916 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14917 TOP_APP, doingAll, now); 14918 int clientProcState = client.curProcState; 14919 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14920 // If the other app is cached for any reason, for purposes here 14921 // we are going to consider it empty. The specific cached state 14922 // doesn't propagate except under certain conditions. 14923 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14924 } 14925 String adjType = null; 14926 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14927 // Not doing bind OOM management, so treat 14928 // this guy more like a started service. 14929 if (app.hasShownUi && app != mHomeProcess) { 14930 // If this process has shown some UI, let it immediately 14931 // go to the LRU list because it may be pretty heavy with 14932 // UI stuff. We'll tag it with a label just to help 14933 // debug and understand what is going on. 14934 if (adj > clientAdj) { 14935 adjType = "cch-bound-ui-services"; 14936 } 14937 app.cached = false; 14938 clientAdj = adj; 14939 clientProcState = procState; 14940 } else { 14941 if (now >= (s.lastActivity 14942 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14943 // This service has not seen activity within 14944 // recent memory, so allow it to drop to the 14945 // LRU list if there is no other reason to keep 14946 // it around. We'll also tag it with a label just 14947 // to help debug and undertand what is going on. 14948 if (adj > clientAdj) { 14949 adjType = "cch-bound-services"; 14950 } 14951 clientAdj = adj; 14952 } 14953 } 14954 } 14955 if (adj > clientAdj) { 14956 // If this process has recently shown UI, and 14957 // the process that is binding to it is less 14958 // important than being visible, then we don't 14959 // care about the binding as much as we care 14960 // about letting this process get into the LRU 14961 // list to be killed and restarted if needed for 14962 // memory. 14963 if (app.hasShownUi && app != mHomeProcess 14964 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14965 adjType = "cch-bound-ui-services"; 14966 } else { 14967 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14968 |Context.BIND_IMPORTANT)) != 0) { 14969 adj = clientAdj; 14970 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14971 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14972 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14973 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14974 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14975 adj = clientAdj; 14976 } else { 14977 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14978 adj = ProcessList.VISIBLE_APP_ADJ; 14979 } 14980 } 14981 if (!client.cached) { 14982 app.cached = false; 14983 } 14984 if (client.keeping) { 14985 app.keeping = true; 14986 } 14987 adjType = "service"; 14988 } 14989 } 14990 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14991 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14992 schedGroup = Process.THREAD_GROUP_DEFAULT; 14993 } 14994 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14995 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14996 // Special handling of clients who are in the top state. 14997 // We *may* want to consider this process to be in the 14998 // top state as well, but only if there is not another 14999 // reason for it to be running. Being on the top is a 15000 // special state, meaning you are specifically running 15001 // for the current top app. If the process is already 15002 // running in the background for some other reason, it 15003 // is more important to continue considering it to be 15004 // in the background state. 15005 mayBeTop = true; 15006 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15007 } else { 15008 // Special handling for above-top states (persistent 15009 // processes). These should not bring the current process 15010 // into the top state, since they are not on top. Instead 15011 // give them the best state after that. 15012 clientProcState = 15013 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15014 } 15015 } 15016 } else { 15017 if (clientProcState < 15018 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15019 clientProcState = 15020 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15021 } 15022 } 15023 if (procState > clientProcState) { 15024 procState = clientProcState; 15025 } 15026 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15027 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15028 app.pendingUiClean = true; 15029 } 15030 if (adjType != null) { 15031 app.adjType = adjType; 15032 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15033 .REASON_SERVICE_IN_USE; 15034 app.adjSource = cr.binding.client; 15035 app.adjSourceOom = clientAdj; 15036 app.adjTarget = s.name; 15037 } 15038 } 15039 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15040 app.treatLikeActivity = true; 15041 } 15042 final ActivityRecord a = cr.activity; 15043 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15044 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15045 (a.visible || a.state == ActivityState.RESUMED 15046 || a.state == ActivityState.PAUSING)) { 15047 adj = ProcessList.FOREGROUND_APP_ADJ; 15048 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15049 schedGroup = Process.THREAD_GROUP_DEFAULT; 15050 } 15051 app.cached = false; 15052 app.adjType = "service"; 15053 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15054 .REASON_SERVICE_IN_USE; 15055 app.adjSource = a; 15056 app.adjSourceOom = adj; 15057 app.adjTarget = s.name; 15058 } 15059 } 15060 } 15061 } 15062 } 15063 15064 for (int provi = app.pubProviders.size()-1; 15065 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15066 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15067 || procState > ActivityManager.PROCESS_STATE_TOP); 15068 provi--) { 15069 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15070 for (int i = cpr.connections.size()-1; 15071 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15072 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15073 || procState > ActivityManager.PROCESS_STATE_TOP); 15074 i--) { 15075 ContentProviderConnection conn = cpr.connections.get(i); 15076 ProcessRecord client = conn.client; 15077 if (client == app) { 15078 // Being our own client is not interesting. 15079 continue; 15080 } 15081 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15082 int clientProcState = client.curProcState; 15083 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15084 // If the other app is cached for any reason, for purposes here 15085 // we are going to consider it empty. 15086 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15087 } 15088 if (adj > clientAdj) { 15089 if (app.hasShownUi && app != mHomeProcess 15090 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15091 app.adjType = "cch-ui-provider"; 15092 } else { 15093 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15094 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15095 app.adjType = "provider"; 15096 } 15097 app.cached &= client.cached; 15098 app.keeping |= client.keeping; 15099 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15100 .REASON_PROVIDER_IN_USE; 15101 app.adjSource = client; 15102 app.adjSourceOom = clientAdj; 15103 app.adjTarget = cpr.name; 15104 } 15105 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15106 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15107 // Special handling of clients who are in the top state. 15108 // We *may* want to consider this process to be in the 15109 // top state as well, but only if there is not another 15110 // reason for it to be running. Being on the top is a 15111 // special state, meaning you are specifically running 15112 // for the current top app. If the process is already 15113 // running in the background for some other reason, it 15114 // is more important to continue considering it to be 15115 // in the background state. 15116 mayBeTop = true; 15117 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15118 } else { 15119 // Special handling for above-top states (persistent 15120 // processes). These should not bring the current process 15121 // into the top state, since they are not on top. Instead 15122 // give them the best state after that. 15123 clientProcState = 15124 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15125 } 15126 } 15127 if (procState > clientProcState) { 15128 procState = clientProcState; 15129 } 15130 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15131 schedGroup = Process.THREAD_GROUP_DEFAULT; 15132 } 15133 } 15134 // If the provider has external (non-framework) process 15135 // dependencies, ensure that its adjustment is at least 15136 // FOREGROUND_APP_ADJ. 15137 if (cpr.hasExternalProcessHandles()) { 15138 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15139 adj = ProcessList.FOREGROUND_APP_ADJ; 15140 schedGroup = Process.THREAD_GROUP_DEFAULT; 15141 app.cached = false; 15142 app.keeping = true; 15143 app.adjType = "provider"; 15144 app.adjTarget = cpr.name; 15145 } 15146 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15147 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15148 } 15149 } 15150 } 15151 15152 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15153 // A client of one of our services or providers is in the top state. We 15154 // *may* want to be in the top state, but not if we are already running in 15155 // the background for some other reason. For the decision here, we are going 15156 // to pick out a few specific states that we want to remain in when a client 15157 // is top (states that tend to be longer-term) and otherwise allow it to go 15158 // to the top state. 15159 switch (procState) { 15160 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15161 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15162 case ActivityManager.PROCESS_STATE_SERVICE: 15163 // These all are longer-term states, so pull them up to the top 15164 // of the background states, but not all the way to the top state. 15165 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15166 break; 15167 default: 15168 // Otherwise, top is a better choice, so take it. 15169 procState = ActivityManager.PROCESS_STATE_TOP; 15170 break; 15171 } 15172 } 15173 15174 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15175 if (app.hasClientActivities) { 15176 // This is a cached process, but with client activities. Mark it so. 15177 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15178 app.adjType = "cch-client-act"; 15179 } else if (app.treatLikeActivity) { 15180 // This is a cached process, but somebody wants us to treat it like it has 15181 // an activity, okay! 15182 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15183 app.adjType = "cch-as-act"; 15184 } 15185 } 15186 15187 if (adj == ProcessList.SERVICE_ADJ) { 15188 if (doingAll) { 15189 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15190 mNewNumServiceProcs++; 15191 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15192 if (!app.serviceb) { 15193 // This service isn't far enough down on the LRU list to 15194 // normally be a B service, but if we are low on RAM and it 15195 // is large we want to force it down since we would prefer to 15196 // keep launcher over it. 15197 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15198 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15199 app.serviceHighRam = true; 15200 app.serviceb = true; 15201 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15202 } else { 15203 mNewNumAServiceProcs++; 15204 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15205 } 15206 } else { 15207 app.serviceHighRam = false; 15208 } 15209 } 15210 if (app.serviceb) { 15211 adj = ProcessList.SERVICE_B_ADJ; 15212 } 15213 } 15214 15215 app.curRawAdj = adj; 15216 15217 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15218 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15219 if (adj > app.maxAdj) { 15220 adj = app.maxAdj; 15221 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15222 schedGroup = Process.THREAD_GROUP_DEFAULT; 15223 } 15224 } 15225 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15226 app.keeping = true; 15227 } 15228 15229 // Do final modification to adj. Everything we do between here and applying 15230 // the final setAdj must be done in this function, because we will also use 15231 // it when computing the final cached adj later. Note that we don't need to 15232 // worry about this for max adj above, since max adj will always be used to 15233 // keep it out of the cached vaues. 15234 app.curAdj = app.modifyRawOomAdj(adj); 15235 app.curSchedGroup = schedGroup; 15236 app.curProcState = procState; 15237 app.foregroundActivities = foregroundActivities; 15238 15239 return app.curRawAdj; 15240 } 15241 15242 /** 15243 * Schedule PSS collection of a process. 15244 */ 15245 void requestPssLocked(ProcessRecord proc, int procState) { 15246 if (mPendingPssProcesses.contains(proc)) { 15247 return; 15248 } 15249 if (mPendingPssProcesses.size() == 0) { 15250 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15251 } 15252 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15253 proc.pssProcState = procState; 15254 mPendingPssProcesses.add(proc); 15255 } 15256 15257 /** 15258 * Schedule PSS collection of all processes. 15259 */ 15260 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15261 if (!always) { 15262 if (now < (mLastFullPssTime + 15263 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15264 return; 15265 } 15266 } 15267 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15268 mLastFullPssTime = now; 15269 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15270 mPendingPssProcesses.clear(); 15271 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15272 ProcessRecord app = mLruProcesses.get(i); 15273 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15274 app.pssProcState = app.setProcState; 15275 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15276 isSleeping(), now); 15277 mPendingPssProcesses.add(app); 15278 } 15279 } 15280 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15281 } 15282 15283 /** 15284 * Ask a given process to GC right now. 15285 */ 15286 final void performAppGcLocked(ProcessRecord app) { 15287 try { 15288 app.lastRequestedGc = SystemClock.uptimeMillis(); 15289 if (app.thread != null) { 15290 if (app.reportLowMemory) { 15291 app.reportLowMemory = false; 15292 app.thread.scheduleLowMemory(); 15293 } else { 15294 app.thread.processInBackground(); 15295 } 15296 } 15297 } catch (Exception e) { 15298 // whatever. 15299 } 15300 } 15301 15302 /** 15303 * Returns true if things are idle enough to perform GCs. 15304 */ 15305 private final boolean canGcNowLocked() { 15306 boolean processingBroadcasts = false; 15307 for (BroadcastQueue q : mBroadcastQueues) { 15308 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15309 processingBroadcasts = true; 15310 } 15311 } 15312 return !processingBroadcasts 15313 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15314 } 15315 15316 /** 15317 * Perform GCs on all processes that are waiting for it, but only 15318 * if things are idle. 15319 */ 15320 final void performAppGcsLocked() { 15321 final int N = mProcessesToGc.size(); 15322 if (N <= 0) { 15323 return; 15324 } 15325 if (canGcNowLocked()) { 15326 while (mProcessesToGc.size() > 0) { 15327 ProcessRecord proc = mProcessesToGc.remove(0); 15328 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15329 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15330 <= SystemClock.uptimeMillis()) { 15331 // To avoid spamming the system, we will GC processes one 15332 // at a time, waiting a few seconds between each. 15333 performAppGcLocked(proc); 15334 scheduleAppGcsLocked(); 15335 return; 15336 } else { 15337 // It hasn't been long enough since we last GCed this 15338 // process... put it in the list to wait for its time. 15339 addProcessToGcListLocked(proc); 15340 break; 15341 } 15342 } 15343 } 15344 15345 scheduleAppGcsLocked(); 15346 } 15347 } 15348 15349 /** 15350 * If all looks good, perform GCs on all processes waiting for them. 15351 */ 15352 final void performAppGcsIfAppropriateLocked() { 15353 if (canGcNowLocked()) { 15354 performAppGcsLocked(); 15355 return; 15356 } 15357 // Still not idle, wait some more. 15358 scheduleAppGcsLocked(); 15359 } 15360 15361 /** 15362 * Schedule the execution of all pending app GCs. 15363 */ 15364 final void scheduleAppGcsLocked() { 15365 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15366 15367 if (mProcessesToGc.size() > 0) { 15368 // Schedule a GC for the time to the next process. 15369 ProcessRecord proc = mProcessesToGc.get(0); 15370 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15371 15372 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15373 long now = SystemClock.uptimeMillis(); 15374 if (when < (now+GC_TIMEOUT)) { 15375 when = now + GC_TIMEOUT; 15376 } 15377 mHandler.sendMessageAtTime(msg, when); 15378 } 15379 } 15380 15381 /** 15382 * Add a process to the array of processes waiting to be GCed. Keeps the 15383 * list in sorted order by the last GC time. The process can't already be 15384 * on the list. 15385 */ 15386 final void addProcessToGcListLocked(ProcessRecord proc) { 15387 boolean added = false; 15388 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15389 if (mProcessesToGc.get(i).lastRequestedGc < 15390 proc.lastRequestedGc) { 15391 added = true; 15392 mProcessesToGc.add(i+1, proc); 15393 break; 15394 } 15395 } 15396 if (!added) { 15397 mProcessesToGc.add(0, proc); 15398 } 15399 } 15400 15401 /** 15402 * Set up to ask a process to GC itself. This will either do it 15403 * immediately, or put it on the list of processes to gc the next 15404 * time things are idle. 15405 */ 15406 final void scheduleAppGcLocked(ProcessRecord app) { 15407 long now = SystemClock.uptimeMillis(); 15408 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15409 return; 15410 } 15411 if (!mProcessesToGc.contains(app)) { 15412 addProcessToGcListLocked(app); 15413 scheduleAppGcsLocked(); 15414 } 15415 } 15416 15417 final void checkExcessivePowerUsageLocked(boolean doKills) { 15418 updateCpuStatsNow(); 15419 15420 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15421 boolean doWakeKills = doKills; 15422 boolean doCpuKills = doKills; 15423 if (mLastPowerCheckRealtime == 0) { 15424 doWakeKills = false; 15425 } 15426 if (mLastPowerCheckUptime == 0) { 15427 doCpuKills = false; 15428 } 15429 if (stats.isScreenOn()) { 15430 doWakeKills = false; 15431 } 15432 final long curRealtime = SystemClock.elapsedRealtime(); 15433 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15434 final long curUptime = SystemClock.uptimeMillis(); 15435 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15436 mLastPowerCheckRealtime = curRealtime; 15437 mLastPowerCheckUptime = curUptime; 15438 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15439 doWakeKills = false; 15440 } 15441 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15442 doCpuKills = false; 15443 } 15444 int i = mLruProcesses.size(); 15445 while (i > 0) { 15446 i--; 15447 ProcessRecord app = mLruProcesses.get(i); 15448 if (!app.keeping) { 15449 long wtime; 15450 synchronized (stats) { 15451 wtime = stats.getProcessWakeTime(app.info.uid, 15452 app.pid, curRealtime); 15453 } 15454 long wtimeUsed = wtime - app.lastWakeTime; 15455 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15456 if (DEBUG_POWER) { 15457 StringBuilder sb = new StringBuilder(128); 15458 sb.append("Wake for "); 15459 app.toShortString(sb); 15460 sb.append(": over "); 15461 TimeUtils.formatDuration(realtimeSince, sb); 15462 sb.append(" used "); 15463 TimeUtils.formatDuration(wtimeUsed, sb); 15464 sb.append(" ("); 15465 sb.append((wtimeUsed*100)/realtimeSince); 15466 sb.append("%)"); 15467 Slog.i(TAG, sb.toString()); 15468 sb.setLength(0); 15469 sb.append("CPU for "); 15470 app.toShortString(sb); 15471 sb.append(": over "); 15472 TimeUtils.formatDuration(uptimeSince, sb); 15473 sb.append(" used "); 15474 TimeUtils.formatDuration(cputimeUsed, sb); 15475 sb.append(" ("); 15476 sb.append((cputimeUsed*100)/uptimeSince); 15477 sb.append("%)"); 15478 Slog.i(TAG, sb.toString()); 15479 } 15480 // If a process has held a wake lock for more 15481 // than 50% of the time during this period, 15482 // that sounds bad. Kill! 15483 if (doWakeKills && realtimeSince > 0 15484 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15485 synchronized (stats) { 15486 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15487 realtimeSince, wtimeUsed); 15488 } 15489 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15490 + " during " + realtimeSince); 15491 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15492 } else if (doCpuKills && uptimeSince > 0 15493 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15494 synchronized (stats) { 15495 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15496 uptimeSince, cputimeUsed); 15497 } 15498 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15499 + " during " + uptimeSince); 15500 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15501 } else { 15502 app.lastWakeTime = wtime; 15503 app.lastCpuTime = app.curCpuTime; 15504 } 15505 } 15506 } 15507 } 15508 15509 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15510 ProcessRecord TOP_APP, boolean doingAll, long now) { 15511 boolean success = true; 15512 15513 if (app.curRawAdj != app.setRawAdj) { 15514 if (wasKeeping && !app.keeping) { 15515 // This app is no longer something we want to keep. Note 15516 // its current wake lock time to later know to kill it if 15517 // it is not behaving well. 15518 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15519 synchronized (stats) { 15520 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15521 app.pid, SystemClock.elapsedRealtime()); 15522 } 15523 app.lastCpuTime = app.curCpuTime; 15524 } 15525 15526 app.setRawAdj = app.curRawAdj; 15527 } 15528 15529 int changes = 0; 15530 15531 if (app.curAdj != app.setAdj) { 15532 ProcessList.setOomAdj(app.pid, app.curAdj); 15533 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15534 TAG, "Set " + app.pid + " " + app.processName + 15535 " adj " + app.curAdj + ": " + app.adjType); 15536 app.setAdj = app.curAdj; 15537 } 15538 15539 if (app.setSchedGroup != app.curSchedGroup) { 15540 app.setSchedGroup = app.curSchedGroup; 15541 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15542 "Setting process group of " + app.processName 15543 + " to " + app.curSchedGroup); 15544 if (app.waitingToKill != null && 15545 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15546 killUnneededProcessLocked(app, app.waitingToKill); 15547 success = false; 15548 } else { 15549 if (true) { 15550 long oldId = Binder.clearCallingIdentity(); 15551 try { 15552 Process.setProcessGroup(app.pid, app.curSchedGroup); 15553 } catch (Exception e) { 15554 Slog.w(TAG, "Failed setting process group of " + app.pid 15555 + " to " + app.curSchedGroup); 15556 e.printStackTrace(); 15557 } finally { 15558 Binder.restoreCallingIdentity(oldId); 15559 } 15560 } else { 15561 if (app.thread != null) { 15562 try { 15563 app.thread.setSchedulingGroup(app.curSchedGroup); 15564 } catch (RemoteException e) { 15565 } 15566 } 15567 } 15568 Process.setSwappiness(app.pid, 15569 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15570 } 15571 } 15572 if (app.repForegroundActivities != app.foregroundActivities) { 15573 app.repForegroundActivities = app.foregroundActivities; 15574 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15575 } 15576 if (app.repProcState != app.curProcState) { 15577 app.repProcState = app.curProcState; 15578 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15579 if (app.thread != null) { 15580 try { 15581 if (false) { 15582 //RuntimeException h = new RuntimeException("here"); 15583 Slog.i(TAG, "Sending new process state " + app.repProcState 15584 + " to " + app /*, h*/); 15585 } 15586 app.thread.setProcessState(app.repProcState); 15587 } catch (RemoteException e) { 15588 } 15589 } 15590 } 15591 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15592 app.setProcState)) { 15593 app.lastStateTime = now; 15594 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15595 isSleeping(), now); 15596 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15597 + ProcessList.makeProcStateString(app.setProcState) + " to " 15598 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15599 + (app.nextPssTime-now) + ": " + app); 15600 } else { 15601 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15602 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15603 requestPssLocked(app, app.setProcState); 15604 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15605 isSleeping(), now); 15606 } else if (false && DEBUG_PSS) { 15607 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15608 } 15609 } 15610 if (app.setProcState != app.curProcState) { 15611 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15612 "Proc state change of " + app.processName 15613 + " to " + app.curProcState); 15614 app.setProcState = app.curProcState; 15615 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15616 app.notCachedSinceIdle = false; 15617 } 15618 if (!doingAll) { 15619 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15620 } else { 15621 app.procStateChanged = true; 15622 } 15623 } 15624 15625 if (changes != 0) { 15626 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15627 int i = mPendingProcessChanges.size()-1; 15628 ProcessChangeItem item = null; 15629 while (i >= 0) { 15630 item = mPendingProcessChanges.get(i); 15631 if (item.pid == app.pid) { 15632 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15633 break; 15634 } 15635 i--; 15636 } 15637 if (i < 0) { 15638 // No existing item in pending changes; need a new one. 15639 final int NA = mAvailProcessChanges.size(); 15640 if (NA > 0) { 15641 item = mAvailProcessChanges.remove(NA-1); 15642 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15643 } else { 15644 item = new ProcessChangeItem(); 15645 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15646 } 15647 item.changes = 0; 15648 item.pid = app.pid; 15649 item.uid = app.info.uid; 15650 if (mPendingProcessChanges.size() == 0) { 15651 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15652 "*** Enqueueing dispatch processes changed!"); 15653 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15654 } 15655 mPendingProcessChanges.add(item); 15656 } 15657 item.changes |= changes; 15658 item.processState = app.repProcState; 15659 item.foregroundActivities = app.repForegroundActivities; 15660 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15661 + Integer.toHexString(System.identityHashCode(item)) 15662 + " " + app.toShortString() + ": changes=" + item.changes 15663 + " procState=" + item.processState 15664 + " foreground=" + item.foregroundActivities 15665 + " type=" + app.adjType + " source=" + app.adjSource 15666 + " target=" + app.adjTarget); 15667 } 15668 15669 return success; 15670 } 15671 15672 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15673 if (proc.thread != null && proc.baseProcessTracker != null) { 15674 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15675 } 15676 } 15677 15678 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15679 ProcessRecord TOP_APP, boolean doingAll, long now) { 15680 if (app.thread == null) { 15681 return false; 15682 } 15683 15684 final boolean wasKeeping = app.keeping; 15685 15686 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15687 15688 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 15689 } 15690 15691 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15692 boolean oomAdj) { 15693 if (isForeground != proc.foregroundServices) { 15694 proc.foregroundServices = isForeground; 15695 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15696 proc.info.uid); 15697 if (isForeground) { 15698 if (curProcs == null) { 15699 curProcs = new ArrayList<ProcessRecord>(); 15700 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15701 } 15702 if (!curProcs.contains(proc)) { 15703 curProcs.add(proc); 15704 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15705 proc.info.packageName, proc.info.uid); 15706 } 15707 } else { 15708 if (curProcs != null) { 15709 if (curProcs.remove(proc)) { 15710 mBatteryStatsService.noteEvent( 15711 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15712 proc.info.packageName, proc.info.uid); 15713 if (curProcs.size() <= 0) { 15714 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15715 } 15716 } 15717 } 15718 } 15719 if (oomAdj) { 15720 updateOomAdjLocked(); 15721 } 15722 } 15723 } 15724 15725 private final ActivityRecord resumedAppLocked() { 15726 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15727 String pkg; 15728 int uid; 15729 if (act != null && !act.sleeping) { 15730 pkg = act.packageName; 15731 uid = act.info.applicationInfo.uid; 15732 } else { 15733 pkg = null; 15734 uid = -1; 15735 } 15736 // Has the UID or resumed package name changed? 15737 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15738 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15739 if (mCurResumedPackage != null) { 15740 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15741 mCurResumedPackage, mCurResumedUid); 15742 } 15743 mCurResumedPackage = pkg; 15744 mCurResumedUid = uid; 15745 if (mCurResumedPackage != null) { 15746 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15747 mCurResumedPackage, mCurResumedUid); 15748 } 15749 } 15750 return act; 15751 } 15752 15753 final boolean updateOomAdjLocked(ProcessRecord app) { 15754 final ActivityRecord TOP_ACT = resumedAppLocked(); 15755 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15756 final boolean wasCached = app.cached; 15757 15758 mAdjSeq++; 15759 15760 // This is the desired cached adjusment we want to tell it to use. 15761 // If our app is currently cached, we know it, and that is it. Otherwise, 15762 // we don't know it yet, and it needs to now be cached we will then 15763 // need to do a complete oom adj. 15764 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15765 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15766 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 15767 SystemClock.uptimeMillis()); 15768 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15769 // Changed to/from cached state, so apps after it in the LRU 15770 // list may also be changed. 15771 updateOomAdjLocked(); 15772 } 15773 return success; 15774 } 15775 15776 final void updateOomAdjLocked() { 15777 final ActivityRecord TOP_ACT = resumedAppLocked(); 15778 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15779 final long now = SystemClock.uptimeMillis(); 15780 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15781 final int N = mLruProcesses.size(); 15782 15783 if (false) { 15784 RuntimeException e = new RuntimeException(); 15785 e.fillInStackTrace(); 15786 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15787 } 15788 15789 mAdjSeq++; 15790 mNewNumServiceProcs = 0; 15791 mNewNumAServiceProcs = 0; 15792 15793 final int emptyProcessLimit; 15794 final int cachedProcessLimit; 15795 if (mProcessLimit <= 0) { 15796 emptyProcessLimit = cachedProcessLimit = 0; 15797 } else if (mProcessLimit == 1) { 15798 emptyProcessLimit = 1; 15799 cachedProcessLimit = 0; 15800 } else { 15801 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15802 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15803 } 15804 15805 // Let's determine how many processes we have running vs. 15806 // how many slots we have for background processes; we may want 15807 // to put multiple processes in a slot of there are enough of 15808 // them. 15809 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15810 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15811 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15812 if (numEmptyProcs > cachedProcessLimit) { 15813 // If there are more empty processes than our limit on cached 15814 // processes, then use the cached process limit for the factor. 15815 // This ensures that the really old empty processes get pushed 15816 // down to the bottom, so if we are running low on memory we will 15817 // have a better chance at keeping around more cached processes 15818 // instead of a gazillion empty processes. 15819 numEmptyProcs = cachedProcessLimit; 15820 } 15821 int emptyFactor = numEmptyProcs/numSlots; 15822 if (emptyFactor < 1) emptyFactor = 1; 15823 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15824 if (cachedFactor < 1) cachedFactor = 1; 15825 int stepCached = 0; 15826 int stepEmpty = 0; 15827 int numCached = 0; 15828 int numEmpty = 0; 15829 int numTrimming = 0; 15830 15831 mNumNonCachedProcs = 0; 15832 mNumCachedHiddenProcs = 0; 15833 15834 // First update the OOM adjustment for each of the 15835 // application processes based on their current state. 15836 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15837 int nextCachedAdj = curCachedAdj+1; 15838 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15839 int nextEmptyAdj = curEmptyAdj+2; 15840 for (int i=N-1; i>=0; i--) { 15841 ProcessRecord app = mLruProcesses.get(i); 15842 if (!app.killedByAm && app.thread != null) { 15843 app.procStateChanged = false; 15844 final boolean wasKeeping = app.keeping; 15845 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15846 15847 // If we haven't yet assigned the final cached adj 15848 // to the process, do that now. 15849 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15850 switch (app.curProcState) { 15851 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15852 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15853 // This process is a cached process holding activities... 15854 // assign it the next cached value for that type, and then 15855 // step that cached level. 15856 app.curRawAdj = curCachedAdj; 15857 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15858 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15859 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15860 + ")"); 15861 if (curCachedAdj != nextCachedAdj) { 15862 stepCached++; 15863 if (stepCached >= cachedFactor) { 15864 stepCached = 0; 15865 curCachedAdj = nextCachedAdj; 15866 nextCachedAdj += 2; 15867 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15868 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15869 } 15870 } 15871 } 15872 break; 15873 default: 15874 // For everything else, assign next empty cached process 15875 // level and bump that up. Note that this means that 15876 // long-running services that have dropped down to the 15877 // cached level will be treated as empty (since their process 15878 // state is still as a service), which is what we want. 15879 app.curRawAdj = curEmptyAdj; 15880 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15881 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15882 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15883 + ")"); 15884 if (curEmptyAdj != nextEmptyAdj) { 15885 stepEmpty++; 15886 if (stepEmpty >= emptyFactor) { 15887 stepEmpty = 0; 15888 curEmptyAdj = nextEmptyAdj; 15889 nextEmptyAdj += 2; 15890 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15891 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15892 } 15893 } 15894 } 15895 break; 15896 } 15897 } 15898 15899 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 15900 15901 // Count the number of process types. 15902 switch (app.curProcState) { 15903 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15904 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15905 mNumCachedHiddenProcs++; 15906 numCached++; 15907 if (numCached > cachedProcessLimit) { 15908 killUnneededProcessLocked(app, "cached #" + numCached); 15909 } 15910 break; 15911 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15912 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15913 && app.lastActivityTime < oldTime) { 15914 killUnneededProcessLocked(app, "empty for " 15915 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15916 / 1000) + "s"); 15917 } else { 15918 numEmpty++; 15919 if (numEmpty > emptyProcessLimit) { 15920 killUnneededProcessLocked(app, "empty #" + numEmpty); 15921 } 15922 } 15923 break; 15924 default: 15925 mNumNonCachedProcs++; 15926 break; 15927 } 15928 15929 if (app.isolated && app.services.size() <= 0) { 15930 // If this is an isolated process, and there are no 15931 // services running in it, then the process is no longer 15932 // needed. We agressively kill these because we can by 15933 // definition not re-use the same process again, and it is 15934 // good to avoid having whatever code was running in them 15935 // left sitting around after no longer needed. 15936 killUnneededProcessLocked(app, "isolated not needed"); 15937 } 15938 15939 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15940 && !app.killedByAm) { 15941 numTrimming++; 15942 } 15943 } 15944 } 15945 15946 mNumServiceProcs = mNewNumServiceProcs; 15947 15948 // Now determine the memory trimming level of background processes. 15949 // Unfortunately we need to start at the back of the list to do this 15950 // properly. We only do this if the number of background apps we 15951 // are managing to keep around is less than half the maximum we desire; 15952 // if we are keeping a good number around, we'll let them use whatever 15953 // memory they want. 15954 final int numCachedAndEmpty = numCached + numEmpty; 15955 int memFactor; 15956 if (numCached <= ProcessList.TRIM_CACHED_APPS 15957 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15958 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15959 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15960 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15961 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15962 } else { 15963 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15964 } 15965 } else { 15966 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15967 } 15968 // We always allow the memory level to go up (better). We only allow it to go 15969 // down if we are in a state where that is allowed, *and* the total number of processes 15970 // has gone down since last time. 15971 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15972 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15973 + " last=" + mLastNumProcesses); 15974 if (memFactor > mLastMemoryLevel) { 15975 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15976 memFactor = mLastMemoryLevel; 15977 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15978 } 15979 } 15980 mLastMemoryLevel = memFactor; 15981 mLastNumProcesses = mLruProcesses.size(); 15982 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 15983 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15984 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15985 if (mLowRamStartTime == 0) { 15986 mLowRamStartTime = now; 15987 } 15988 int step = 0; 15989 int fgTrimLevel; 15990 switch (memFactor) { 15991 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15992 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15993 break; 15994 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15995 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15996 break; 15997 default: 15998 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15999 break; 16000 } 16001 int factor = numTrimming/3; 16002 int minFactor = 2; 16003 if (mHomeProcess != null) minFactor++; 16004 if (mPreviousProcess != null) minFactor++; 16005 if (factor < minFactor) factor = minFactor; 16006 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16007 for (int i=N-1; i>=0; i--) { 16008 ProcessRecord app = mLruProcesses.get(i); 16009 if (allChanged || app.procStateChanged) { 16010 setProcessTrackerState(app, trackerMemFactor, now); 16011 app.procStateChanged = false; 16012 } 16013 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16014 && !app.killedByAm) { 16015 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16016 try { 16017 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16018 "Trimming memory of " + app.processName 16019 + " to " + curLevel); 16020 app.thread.scheduleTrimMemory(curLevel); 16021 } catch (RemoteException e) { 16022 } 16023 if (false) { 16024 // For now we won't do this; our memory trimming seems 16025 // to be good enough at this point that destroying 16026 // activities causes more harm than good. 16027 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16028 && app != mHomeProcess && app != mPreviousProcess) { 16029 // Need to do this on its own message because the stack may not 16030 // be in a consistent state at this point. 16031 // For these apps we will also finish their activities 16032 // to help them free memory. 16033 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16034 } 16035 } 16036 } 16037 app.trimMemoryLevel = curLevel; 16038 step++; 16039 if (step >= factor) { 16040 step = 0; 16041 switch (curLevel) { 16042 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16043 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16044 break; 16045 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16046 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16047 break; 16048 } 16049 } 16050 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16051 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16052 && app.thread != null) { 16053 try { 16054 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16055 "Trimming memory of heavy-weight " + app.processName 16056 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16057 app.thread.scheduleTrimMemory( 16058 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16059 } catch (RemoteException e) { 16060 } 16061 } 16062 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16063 } else { 16064 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16065 || app.systemNoUi) && app.pendingUiClean) { 16066 // If this application is now in the background and it 16067 // had done UI, then give it the special trim level to 16068 // have it free UI resources. 16069 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16070 if (app.trimMemoryLevel < level && app.thread != null) { 16071 try { 16072 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16073 "Trimming memory of bg-ui " + app.processName 16074 + " to " + level); 16075 app.thread.scheduleTrimMemory(level); 16076 } catch (RemoteException e) { 16077 } 16078 } 16079 app.pendingUiClean = false; 16080 } 16081 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16082 try { 16083 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16084 "Trimming memory of fg " + app.processName 16085 + " to " + fgTrimLevel); 16086 app.thread.scheduleTrimMemory(fgTrimLevel); 16087 } catch (RemoteException e) { 16088 } 16089 } 16090 app.trimMemoryLevel = fgTrimLevel; 16091 } 16092 } 16093 } else { 16094 if (mLowRamStartTime != 0) { 16095 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16096 mLowRamStartTime = 0; 16097 } 16098 for (int i=N-1; i>=0; i--) { 16099 ProcessRecord app = mLruProcesses.get(i); 16100 if (allChanged || app.procStateChanged) { 16101 setProcessTrackerState(app, trackerMemFactor, now); 16102 app.procStateChanged = false; 16103 } 16104 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16105 || app.systemNoUi) && app.pendingUiClean) { 16106 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16107 && app.thread != null) { 16108 try { 16109 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16110 "Trimming memory of ui hidden " + app.processName 16111 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16112 app.thread.scheduleTrimMemory( 16113 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16114 } catch (RemoteException e) { 16115 } 16116 } 16117 app.pendingUiClean = false; 16118 } 16119 app.trimMemoryLevel = 0; 16120 } 16121 } 16122 16123 if (mAlwaysFinishActivities) { 16124 // Need to do this on its own message because the stack may not 16125 // be in a consistent state at this point. 16126 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16127 } 16128 16129 if (allChanged) { 16130 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16131 } 16132 16133 if (mProcessStats.shouldWriteNowLocked(now)) { 16134 mHandler.post(new Runnable() { 16135 @Override public void run() { 16136 synchronized (ActivityManagerService.this) { 16137 mProcessStats.writeStateAsyncLocked(); 16138 } 16139 } 16140 }); 16141 } 16142 16143 if (DEBUG_OOM_ADJ) { 16144 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16145 } 16146 } 16147 16148 final void trimApplications() { 16149 synchronized (this) { 16150 int i; 16151 16152 // First remove any unused application processes whose package 16153 // has been removed. 16154 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16155 final ProcessRecord app = mRemovedProcesses.get(i); 16156 if (app.activities.size() == 0 16157 && app.curReceiver == null && app.services.size() == 0) { 16158 Slog.i( 16159 TAG, "Exiting empty application process " 16160 + app.processName + " (" 16161 + (app.thread != null ? app.thread.asBinder() : null) 16162 + ")\n"); 16163 if (app.pid > 0 && app.pid != MY_PID) { 16164 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16165 app.processName, app.setAdj, "empty"); 16166 app.killedByAm = true; 16167 Process.killProcessQuiet(app.pid); 16168 } else { 16169 try { 16170 app.thread.scheduleExit(); 16171 } catch (Exception e) { 16172 // Ignore exceptions. 16173 } 16174 } 16175 cleanUpApplicationRecordLocked(app, false, true, -1); 16176 mRemovedProcesses.remove(i); 16177 16178 if (app.persistent) { 16179 if (app.persistent) { 16180 addAppLocked(app.info, false); 16181 } 16182 } 16183 } 16184 } 16185 16186 // Now update the oom adj for all processes. 16187 updateOomAdjLocked(); 16188 } 16189 } 16190 16191 /** This method sends the specified signal to each of the persistent apps */ 16192 public void signalPersistentProcesses(int sig) throws RemoteException { 16193 if (sig != Process.SIGNAL_USR1) { 16194 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16195 } 16196 16197 synchronized (this) { 16198 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16199 != PackageManager.PERMISSION_GRANTED) { 16200 throw new SecurityException("Requires permission " 16201 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16202 } 16203 16204 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16205 ProcessRecord r = mLruProcesses.get(i); 16206 if (r.thread != null && r.persistent) { 16207 Process.sendSignal(r.pid, sig); 16208 } 16209 } 16210 } 16211 } 16212 16213 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16214 if (proc == null || proc == mProfileProc) { 16215 proc = mProfileProc; 16216 path = mProfileFile; 16217 profileType = mProfileType; 16218 clearProfilerLocked(); 16219 } 16220 if (proc == null) { 16221 return; 16222 } 16223 try { 16224 proc.thread.profilerControl(false, path, null, profileType); 16225 } catch (RemoteException e) { 16226 throw new IllegalStateException("Process disappeared"); 16227 } 16228 } 16229 16230 private void clearProfilerLocked() { 16231 if (mProfileFd != null) { 16232 try { 16233 mProfileFd.close(); 16234 } catch (IOException e) { 16235 } 16236 } 16237 mProfileApp = null; 16238 mProfileProc = null; 16239 mProfileFile = null; 16240 mProfileType = 0; 16241 mAutoStopProfiler = false; 16242 } 16243 16244 public boolean profileControl(String process, int userId, boolean start, 16245 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16246 16247 try { 16248 synchronized (this) { 16249 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16250 // its own permission. 16251 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16252 != PackageManager.PERMISSION_GRANTED) { 16253 throw new SecurityException("Requires permission " 16254 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16255 } 16256 16257 if (start && fd == null) { 16258 throw new IllegalArgumentException("null fd"); 16259 } 16260 16261 ProcessRecord proc = null; 16262 if (process != null) { 16263 proc = findProcessLocked(process, userId, "profileControl"); 16264 } 16265 16266 if (start && (proc == null || proc.thread == null)) { 16267 throw new IllegalArgumentException("Unknown process: " + process); 16268 } 16269 16270 if (start) { 16271 stopProfilerLocked(null, null, 0); 16272 setProfileApp(proc.info, proc.processName, path, fd, false); 16273 mProfileProc = proc; 16274 mProfileType = profileType; 16275 try { 16276 fd = fd.dup(); 16277 } catch (IOException e) { 16278 fd = null; 16279 } 16280 proc.thread.profilerControl(start, path, fd, profileType); 16281 fd = null; 16282 mProfileFd = null; 16283 } else { 16284 stopProfilerLocked(proc, path, profileType); 16285 if (fd != null) { 16286 try { 16287 fd.close(); 16288 } catch (IOException e) { 16289 } 16290 } 16291 } 16292 16293 return true; 16294 } 16295 } catch (RemoteException e) { 16296 throw new IllegalStateException("Process disappeared"); 16297 } finally { 16298 if (fd != null) { 16299 try { 16300 fd.close(); 16301 } catch (IOException e) { 16302 } 16303 } 16304 } 16305 } 16306 16307 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16308 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16309 userId, true, true, callName, null); 16310 ProcessRecord proc = null; 16311 try { 16312 int pid = Integer.parseInt(process); 16313 synchronized (mPidsSelfLocked) { 16314 proc = mPidsSelfLocked.get(pid); 16315 } 16316 } catch (NumberFormatException e) { 16317 } 16318 16319 if (proc == null) { 16320 ArrayMap<String, SparseArray<ProcessRecord>> all 16321 = mProcessNames.getMap(); 16322 SparseArray<ProcessRecord> procs = all.get(process); 16323 if (procs != null && procs.size() > 0) { 16324 proc = procs.valueAt(0); 16325 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16326 for (int i=1; i<procs.size(); i++) { 16327 ProcessRecord thisProc = procs.valueAt(i); 16328 if (thisProc.userId == userId) { 16329 proc = thisProc; 16330 break; 16331 } 16332 } 16333 } 16334 } 16335 } 16336 16337 return proc; 16338 } 16339 16340 public boolean dumpHeap(String process, int userId, boolean managed, 16341 String path, ParcelFileDescriptor fd) throws RemoteException { 16342 16343 try { 16344 synchronized (this) { 16345 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16346 // its own permission (same as profileControl). 16347 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16348 != PackageManager.PERMISSION_GRANTED) { 16349 throw new SecurityException("Requires permission " 16350 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16351 } 16352 16353 if (fd == null) { 16354 throw new IllegalArgumentException("null fd"); 16355 } 16356 16357 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16358 if (proc == null || proc.thread == null) { 16359 throw new IllegalArgumentException("Unknown process: " + process); 16360 } 16361 16362 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16363 if (!isDebuggable) { 16364 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16365 throw new SecurityException("Process not debuggable: " + proc); 16366 } 16367 } 16368 16369 proc.thread.dumpHeap(managed, path, fd); 16370 fd = null; 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 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16386 public void monitor() { 16387 synchronized (this) { } 16388 } 16389 16390 void onCoreSettingsChange(Bundle settings) { 16391 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16392 ProcessRecord processRecord = mLruProcesses.get(i); 16393 try { 16394 if (processRecord.thread != null) { 16395 processRecord.thread.setCoreSettings(settings); 16396 } 16397 } catch (RemoteException re) { 16398 /* ignore */ 16399 } 16400 } 16401 } 16402 16403 // Multi-user methods 16404 16405 /** 16406 * Start user, if its not already running, but don't bring it to foreground. 16407 */ 16408 @Override 16409 public boolean startUserInBackground(final int userId) { 16410 return startUser(userId, /* foreground */ false); 16411 } 16412 16413 /** 16414 * Refreshes the list of users related to the current user when either a 16415 * user switch happens or when a new related user is started in the 16416 * background. 16417 */ 16418 private void updateCurrentProfileIdsLocked() { 16419 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16420 mCurrentUserId, false /* enabledOnly */); 16421 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16422 for (int i = 0; i < currentProfileIds.length; i++) { 16423 currentProfileIds[i] = profiles.get(i).id; 16424 } 16425 mCurrentProfileIds = currentProfileIds; 16426 } 16427 16428 private Set getProfileIdsLocked(int userId) { 16429 Set userIds = new HashSet<Integer>(); 16430 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16431 userId, false /* enabledOnly */); 16432 for (UserInfo user : profiles) { 16433 userIds.add(Integer.valueOf(user.id)); 16434 } 16435 return userIds; 16436 } 16437 16438 @Override 16439 public boolean switchUser(final int userId) { 16440 return startUser(userId, /* foregound */ true); 16441 } 16442 16443 private boolean startUser(final int userId, boolean foreground) { 16444 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16445 != PackageManager.PERMISSION_GRANTED) { 16446 String msg = "Permission Denial: switchUser() from pid=" 16447 + Binder.getCallingPid() 16448 + ", uid=" + Binder.getCallingUid() 16449 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16450 Slog.w(TAG, msg); 16451 throw new SecurityException(msg); 16452 } 16453 16454 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16455 16456 final long ident = Binder.clearCallingIdentity(); 16457 try { 16458 synchronized (this) { 16459 final int oldUserId = mCurrentUserId; 16460 if (oldUserId == userId) { 16461 return true; 16462 } 16463 16464 mStackSupervisor.setLockTaskModeLocked(null); 16465 16466 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16467 if (userInfo == null) { 16468 Slog.w(TAG, "No user info for user #" + userId); 16469 return false; 16470 } 16471 16472 if (foreground) { 16473 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16474 R.anim.screen_user_enter); 16475 } 16476 16477 boolean needStart = false; 16478 16479 // If the user we are switching to is not currently started, then 16480 // we need to start it now. 16481 if (mStartedUsers.get(userId) == null) { 16482 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16483 updateStartedUserArrayLocked(); 16484 needStart = true; 16485 } 16486 16487 final Integer userIdInt = Integer.valueOf(userId); 16488 mUserLru.remove(userIdInt); 16489 mUserLru.add(userIdInt); 16490 16491 if (foreground) { 16492 mCurrentUserId = userId; 16493 updateCurrentProfileIdsLocked(); 16494 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16495 // Once the internal notion of the active user has switched, we lock the device 16496 // with the option to show the user switcher on the keyguard. 16497 mWindowManager.lockNow(null); 16498 } else { 16499 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16500 updateCurrentProfileIdsLocked(); 16501 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16502 mUserLru.remove(currentUserIdInt); 16503 mUserLru.add(currentUserIdInt); 16504 } 16505 16506 final UserStartedState uss = mStartedUsers.get(userId); 16507 16508 // Make sure user is in the started state. If it is currently 16509 // stopping, we need to knock that off. 16510 if (uss.mState == UserStartedState.STATE_STOPPING) { 16511 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16512 // so we can just fairly silently bring the user back from 16513 // the almost-dead. 16514 uss.mState = UserStartedState.STATE_RUNNING; 16515 updateStartedUserArrayLocked(); 16516 needStart = true; 16517 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16518 // This means ACTION_SHUTDOWN has been sent, so we will 16519 // need to treat this as a new boot of the user. 16520 uss.mState = UserStartedState.STATE_BOOTING; 16521 updateStartedUserArrayLocked(); 16522 needStart = true; 16523 } 16524 16525 if (uss.mState == UserStartedState.STATE_BOOTING) { 16526 // Booting up a new user, need to tell system services about it. 16527 // Note that this is on the same handler as scheduling of broadcasts, 16528 // which is important because it needs to go first. 16529 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16530 } 16531 16532 if (foreground) { 16533 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16534 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16535 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16536 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16537 oldUserId, userId, uss)); 16538 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16539 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16540 } 16541 16542 if (needStart) { 16543 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16544 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16545 | Intent.FLAG_RECEIVER_FOREGROUND); 16546 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16547 broadcastIntentLocked(null, null, intent, 16548 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16549 false, false, MY_PID, Process.SYSTEM_UID, userId); 16550 } 16551 16552 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16553 if (userId != UserHandle.USER_OWNER) { 16554 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16555 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16556 broadcastIntentLocked(null, null, intent, null, 16557 new IIntentReceiver.Stub() { 16558 public void performReceive(Intent intent, int resultCode, 16559 String data, Bundle extras, boolean ordered, 16560 boolean sticky, int sendingUser) { 16561 userInitialized(uss, userId); 16562 } 16563 }, 0, null, null, null, AppOpsManager.OP_NONE, 16564 true, false, MY_PID, Process.SYSTEM_UID, 16565 userId); 16566 uss.initializing = true; 16567 } else { 16568 getUserManagerLocked().makeInitialized(userInfo.id); 16569 } 16570 } 16571 16572 if (foreground) { 16573 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16574 if (homeInFront) { 16575 startHomeActivityLocked(userId); 16576 } else { 16577 mStackSupervisor.resumeTopActivitiesLocked(); 16578 } 16579 EventLogTags.writeAmSwitchUser(userId); 16580 getUserManagerLocked().userForeground(userId); 16581 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16582 } else { 16583 mStackSupervisor.startBackgroundUserLocked(userId, uss); 16584 } 16585 16586 if (needStart) { 16587 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16588 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16589 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16590 broadcastIntentLocked(null, null, intent, 16591 null, new IIntentReceiver.Stub() { 16592 @Override 16593 public void performReceive(Intent intent, int resultCode, String data, 16594 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16595 throws RemoteException { 16596 } 16597 }, 0, null, null, 16598 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16599 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16600 } 16601 } 16602 } finally { 16603 Binder.restoreCallingIdentity(ident); 16604 } 16605 16606 return true; 16607 } 16608 16609 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16610 long ident = Binder.clearCallingIdentity(); 16611 try { 16612 Intent intent; 16613 if (oldUserId >= 0) { 16614 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16615 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16616 | Intent.FLAG_RECEIVER_FOREGROUND); 16617 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16618 broadcastIntentLocked(null, null, intent, 16619 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16620 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16621 } 16622 if (newUserId >= 0) { 16623 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16624 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16625 | Intent.FLAG_RECEIVER_FOREGROUND); 16626 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16627 broadcastIntentLocked(null, null, intent, 16628 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16629 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16630 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16631 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16632 | Intent.FLAG_RECEIVER_FOREGROUND); 16633 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16634 broadcastIntentLocked(null, null, intent, 16635 null, null, 0, null, null, 16636 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16637 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16638 } 16639 } finally { 16640 Binder.restoreCallingIdentity(ident); 16641 } 16642 } 16643 16644 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16645 final int newUserId) { 16646 final int N = mUserSwitchObservers.beginBroadcast(); 16647 if (N > 0) { 16648 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16649 int mCount = 0; 16650 @Override 16651 public void sendResult(Bundle data) throws RemoteException { 16652 synchronized (ActivityManagerService.this) { 16653 if (mCurUserSwitchCallback == this) { 16654 mCount++; 16655 if (mCount == N) { 16656 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16657 } 16658 } 16659 } 16660 } 16661 }; 16662 synchronized (this) { 16663 uss.switching = true; 16664 mCurUserSwitchCallback = callback; 16665 } 16666 for (int i=0; i<N; i++) { 16667 try { 16668 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16669 newUserId, callback); 16670 } catch (RemoteException e) { 16671 } 16672 } 16673 } else { 16674 synchronized (this) { 16675 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16676 } 16677 } 16678 mUserSwitchObservers.finishBroadcast(); 16679 } 16680 16681 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16682 synchronized (this) { 16683 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16684 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16685 } 16686 } 16687 16688 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16689 mCurUserSwitchCallback = null; 16690 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16691 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16692 oldUserId, newUserId, uss)); 16693 } 16694 16695 void userInitialized(UserStartedState uss, int newUserId) { 16696 completeSwitchAndInitalize(uss, newUserId, true, false); 16697 } 16698 16699 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16700 completeSwitchAndInitalize(uss, newUserId, false, true); 16701 } 16702 16703 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16704 boolean clearInitializing, boolean clearSwitching) { 16705 boolean unfrozen = false; 16706 synchronized (this) { 16707 if (clearInitializing) { 16708 uss.initializing = false; 16709 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16710 } 16711 if (clearSwitching) { 16712 uss.switching = false; 16713 } 16714 if (!uss.switching && !uss.initializing) { 16715 mWindowManager.stopFreezingScreen(); 16716 unfrozen = true; 16717 } 16718 } 16719 if (unfrozen) { 16720 final int N = mUserSwitchObservers.beginBroadcast(); 16721 for (int i=0; i<N; i++) { 16722 try { 16723 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16724 } catch (RemoteException e) { 16725 } 16726 } 16727 mUserSwitchObservers.finishBroadcast(); 16728 } 16729 } 16730 16731 void scheduleStartProfilesLocked() { 16732 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16733 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16734 DateUtils.SECOND_IN_MILLIS); 16735 } 16736 } 16737 16738 void startProfilesLocked() { 16739 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16740 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16741 mCurrentUserId, false /* enabledOnly */); 16742 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16743 for (UserInfo user : profiles) { 16744 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16745 && user.id != mCurrentUserId) { 16746 toStart.add(user); 16747 } 16748 } 16749 final int n = toStart.size(); 16750 int i = 0; 16751 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16752 startUserInBackground(toStart.get(i).id); 16753 } 16754 if (i < n) { 16755 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16756 } 16757 } 16758 16759 void finishUserBoot(UserStartedState uss) { 16760 synchronized (this) { 16761 if (uss.mState == UserStartedState.STATE_BOOTING 16762 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16763 uss.mState = UserStartedState.STATE_RUNNING; 16764 final int userId = uss.mHandle.getIdentifier(); 16765 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16766 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16767 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16768 broadcastIntentLocked(null, null, intent, 16769 null, null, 0, null, null, 16770 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16771 true, false, MY_PID, Process.SYSTEM_UID, userId); 16772 } 16773 } 16774 } 16775 16776 void finishUserSwitch(UserStartedState uss) { 16777 synchronized (this) { 16778 finishUserBoot(uss); 16779 16780 startProfilesLocked(); 16781 16782 int num = mUserLru.size(); 16783 int i = 0; 16784 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16785 Integer oldUserId = mUserLru.get(i); 16786 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16787 if (oldUss == null) { 16788 // Shouldn't happen, but be sane if it does. 16789 mUserLru.remove(i); 16790 num--; 16791 continue; 16792 } 16793 if (oldUss.mState == UserStartedState.STATE_STOPPING 16794 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16795 // This user is already stopping, doesn't count. 16796 num--; 16797 i++; 16798 continue; 16799 } 16800 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16801 // Owner and current can't be stopped, but count as running. 16802 i++; 16803 continue; 16804 } 16805 // This is a user to be stopped. 16806 stopUserLocked(oldUserId, null); 16807 num--; 16808 i++; 16809 } 16810 } 16811 } 16812 16813 @Override 16814 public int stopUser(final int userId, final IStopUserCallback callback) { 16815 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16816 != PackageManager.PERMISSION_GRANTED) { 16817 String msg = "Permission Denial: switchUser() from pid=" 16818 + Binder.getCallingPid() 16819 + ", uid=" + Binder.getCallingUid() 16820 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16821 Slog.w(TAG, msg); 16822 throw new SecurityException(msg); 16823 } 16824 if (userId <= 0) { 16825 throw new IllegalArgumentException("Can't stop primary user " + userId); 16826 } 16827 synchronized (this) { 16828 return stopUserLocked(userId, callback); 16829 } 16830 } 16831 16832 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16833 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16834 if (mCurrentUserId == userId) { 16835 return ActivityManager.USER_OP_IS_CURRENT; 16836 } 16837 16838 final UserStartedState uss = mStartedUsers.get(userId); 16839 if (uss == null) { 16840 // User is not started, nothing to do... but we do need to 16841 // callback if requested. 16842 if (callback != null) { 16843 mHandler.post(new Runnable() { 16844 @Override 16845 public void run() { 16846 try { 16847 callback.userStopped(userId); 16848 } catch (RemoteException e) { 16849 } 16850 } 16851 }); 16852 } 16853 return ActivityManager.USER_OP_SUCCESS; 16854 } 16855 16856 if (callback != null) { 16857 uss.mStopCallbacks.add(callback); 16858 } 16859 16860 if (uss.mState != UserStartedState.STATE_STOPPING 16861 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16862 uss.mState = UserStartedState.STATE_STOPPING; 16863 updateStartedUserArrayLocked(); 16864 16865 long ident = Binder.clearCallingIdentity(); 16866 try { 16867 // We are going to broadcast ACTION_USER_STOPPING and then 16868 // once that is done send a final ACTION_SHUTDOWN and then 16869 // stop the user. 16870 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16871 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16872 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16873 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16874 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16875 // This is the result receiver for the final shutdown broadcast. 16876 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16877 @Override 16878 public void performReceive(Intent intent, int resultCode, String data, 16879 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16880 finishUserStop(uss); 16881 } 16882 }; 16883 // This is the result receiver for the initial stopping broadcast. 16884 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16885 @Override 16886 public void performReceive(Intent intent, int resultCode, String data, 16887 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16888 // On to the next. 16889 synchronized (ActivityManagerService.this) { 16890 if (uss.mState != UserStartedState.STATE_STOPPING) { 16891 // Whoops, we are being started back up. Abort, abort! 16892 return; 16893 } 16894 uss.mState = UserStartedState.STATE_SHUTDOWN; 16895 } 16896 mSystemServiceManager.stopUser(userId); 16897 broadcastIntentLocked(null, null, shutdownIntent, 16898 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16899 true, false, MY_PID, Process.SYSTEM_UID, userId); 16900 } 16901 }; 16902 // Kick things off. 16903 broadcastIntentLocked(null, null, stoppingIntent, 16904 null, stoppingReceiver, 0, null, null, 16905 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16906 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16907 } finally { 16908 Binder.restoreCallingIdentity(ident); 16909 } 16910 } 16911 16912 return ActivityManager.USER_OP_SUCCESS; 16913 } 16914 16915 void finishUserStop(UserStartedState uss) { 16916 final int userId = uss.mHandle.getIdentifier(); 16917 boolean stopped; 16918 ArrayList<IStopUserCallback> callbacks; 16919 synchronized (this) { 16920 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16921 if (mStartedUsers.get(userId) != uss) { 16922 stopped = false; 16923 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16924 stopped = false; 16925 } else { 16926 stopped = true; 16927 // User can no longer run. 16928 mStartedUsers.remove(userId); 16929 mUserLru.remove(Integer.valueOf(userId)); 16930 updateStartedUserArrayLocked(); 16931 16932 // Clean up all state and processes associated with the user. 16933 // Kill all the processes for the user. 16934 forceStopUserLocked(userId, "finish user"); 16935 } 16936 } 16937 16938 for (int i=0; i<callbacks.size(); i++) { 16939 try { 16940 if (stopped) callbacks.get(i).userStopped(userId); 16941 else callbacks.get(i).userStopAborted(userId); 16942 } catch (RemoteException e) { 16943 } 16944 } 16945 16946 if (stopped) { 16947 mSystemServiceManager.cleanupUser(userId); 16948 synchronized (this) { 16949 mStackSupervisor.removeUserLocked(userId); 16950 } 16951 } 16952 } 16953 16954 @Override 16955 public UserInfo getCurrentUser() { 16956 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16957 != PackageManager.PERMISSION_GRANTED) && ( 16958 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16959 != PackageManager.PERMISSION_GRANTED)) { 16960 String msg = "Permission Denial: getCurrentUser() from pid=" 16961 + Binder.getCallingPid() 16962 + ", uid=" + Binder.getCallingUid() 16963 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16964 Slog.w(TAG, msg); 16965 throw new SecurityException(msg); 16966 } 16967 synchronized (this) { 16968 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16969 } 16970 } 16971 16972 int getCurrentUserIdLocked() { 16973 return mCurrentUserId; 16974 } 16975 16976 @Override 16977 public boolean isUserRunning(int userId, boolean orStopped) { 16978 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16979 != PackageManager.PERMISSION_GRANTED) { 16980 String msg = "Permission Denial: isUserRunning() from pid=" 16981 + Binder.getCallingPid() 16982 + ", uid=" + Binder.getCallingUid() 16983 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16984 Slog.w(TAG, msg); 16985 throw new SecurityException(msg); 16986 } 16987 synchronized (this) { 16988 return isUserRunningLocked(userId, orStopped); 16989 } 16990 } 16991 16992 boolean isUserRunningLocked(int userId, boolean orStopped) { 16993 UserStartedState state = mStartedUsers.get(userId); 16994 if (state == null) { 16995 return false; 16996 } 16997 if (orStopped) { 16998 return true; 16999 } 17000 return state.mState != UserStartedState.STATE_STOPPING 17001 && state.mState != UserStartedState.STATE_SHUTDOWN; 17002 } 17003 17004 @Override 17005 public int[] getRunningUserIds() { 17006 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17007 != PackageManager.PERMISSION_GRANTED) { 17008 String msg = "Permission Denial: isUserRunning() from pid=" 17009 + Binder.getCallingPid() 17010 + ", uid=" + Binder.getCallingUid() 17011 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17012 Slog.w(TAG, msg); 17013 throw new SecurityException(msg); 17014 } 17015 synchronized (this) { 17016 return mStartedUserArray; 17017 } 17018 } 17019 17020 private void updateStartedUserArrayLocked() { 17021 int num = 0; 17022 for (int i=0; i<mStartedUsers.size(); i++) { 17023 UserStartedState uss = mStartedUsers.valueAt(i); 17024 // This list does not include stopping users. 17025 if (uss.mState != UserStartedState.STATE_STOPPING 17026 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17027 num++; 17028 } 17029 } 17030 mStartedUserArray = new int[num]; 17031 num = 0; 17032 for (int i=0; i<mStartedUsers.size(); i++) { 17033 UserStartedState uss = mStartedUsers.valueAt(i); 17034 if (uss.mState != UserStartedState.STATE_STOPPING 17035 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17036 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17037 num++; 17038 } 17039 } 17040 } 17041 17042 @Override 17043 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17044 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17045 != PackageManager.PERMISSION_GRANTED) { 17046 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17047 + Binder.getCallingPid() 17048 + ", uid=" + Binder.getCallingUid() 17049 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 17050 Slog.w(TAG, msg); 17051 throw new SecurityException(msg); 17052 } 17053 17054 mUserSwitchObservers.register(observer); 17055 } 17056 17057 @Override 17058 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17059 mUserSwitchObservers.unregister(observer); 17060 } 17061 17062 private boolean userExists(int userId) { 17063 if (userId == 0) { 17064 return true; 17065 } 17066 UserManagerService ums = getUserManagerLocked(); 17067 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17068 } 17069 17070 int[] getUsersLocked() { 17071 UserManagerService ums = getUserManagerLocked(); 17072 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17073 } 17074 17075 UserManagerService getUserManagerLocked() { 17076 if (mUserManager == null) { 17077 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17078 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17079 } 17080 return mUserManager; 17081 } 17082 17083 private int applyUserId(int uid, int userId) { 17084 return UserHandle.getUid(userId, uid); 17085 } 17086 17087 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17088 if (info == null) return null; 17089 ApplicationInfo newInfo = new ApplicationInfo(info); 17090 newInfo.uid = applyUserId(info.uid, userId); 17091 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17092 + info.packageName; 17093 return newInfo; 17094 } 17095 17096 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17097 if (aInfo == null 17098 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17099 return aInfo; 17100 } 17101 17102 ActivityInfo info = new ActivityInfo(aInfo); 17103 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17104 return info; 17105 } 17106 17107 private final class LocalService extends ActivityManagerInternal { 17108 @Override 17109 public void goingToSleep() { 17110 ActivityManagerService.this.goingToSleep(); 17111 } 17112 17113 @Override 17114 public void wakingUp() { 17115 ActivityManagerService.this.wakingUp(); 17116 } 17117 } 17118} 17119