ActivityManagerService.java revision e22b3b143240f0f18e3d6d3c06686ad3c23b131b
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.service.voice.IVoiceInteractionSession; 39import android.util.ArrayMap; 40 41import com.android.internal.R; 42import com.android.internal.annotations.GuardedBy; 43import com.android.internal.app.IAppOpsService; 44import com.android.internal.app.IVoiceInteractor; 45import com.android.internal.app.ProcessMap; 46import com.android.internal.app.ProcessStats; 47import com.android.internal.content.PackageMonitor; 48import com.android.internal.os.BackgroundThread; 49import com.android.internal.os.BatteryStatsImpl; 50import com.android.internal.os.ProcessCpuTracker; 51import com.android.internal.os.TransferPipe; 52import com.android.internal.os.Zygote; 53import com.android.internal.util.FastPrintWriter; 54import com.android.internal.util.FastXmlSerializer; 55import com.android.internal.util.MemInfoReader; 56import com.android.internal.util.Preconditions; 57import com.android.server.AppOpsService; 58import com.android.server.AttributeCache; 59import com.android.server.IntentResolver; 60import com.android.server.LocalServices; 61import com.android.server.ServiceThread; 62import com.android.server.SystemService; 63import com.android.server.SystemServiceManager; 64import com.android.server.Watchdog; 65import com.android.server.am.ActivityStack.ActivityState; 66import com.android.server.firewall.IntentFirewall; 67import com.android.server.pm.UserManagerService; 68import com.android.server.wm.AppTransition; 69import com.android.server.wm.WindowManagerService; 70import com.google.android.collect.Lists; 71import com.google.android.collect.Maps; 72 73import libcore.io.IoUtils; 74 75import org.xmlpull.v1.XmlPullParser; 76import org.xmlpull.v1.XmlPullParserException; 77import org.xmlpull.v1.XmlSerializer; 78 79import android.app.Activity; 80import android.app.ActivityManager; 81import android.app.ActivityManager.RunningTaskInfo; 82import android.app.ActivityManager.StackInfo; 83import android.app.ActivityManagerInternal; 84import android.app.ActivityManagerNative; 85import android.app.ActivityOptions; 86import android.app.ActivityThread; 87import android.app.AlertDialog; 88import android.app.AppGlobals; 89import android.app.ApplicationErrorReport; 90import android.app.Dialog; 91import android.app.IActivityController; 92import android.app.IApplicationThread; 93import android.app.IInstrumentationWatcher; 94import android.app.INotificationManager; 95import android.app.IProcessObserver; 96import android.app.IServiceConnection; 97import android.app.IStopUserCallback; 98import android.app.IUiAutomationConnection; 99import android.app.IUserSwitchObserver; 100import android.app.Instrumentation; 101import android.app.Notification; 102import android.app.NotificationManager; 103import android.app.PendingIntent; 104import android.app.backup.IBackupManager; 105import android.content.ActivityNotFoundException; 106import android.content.BroadcastReceiver; 107import android.content.ClipData; 108import android.content.ComponentCallbacks2; 109import android.content.ComponentName; 110import android.content.ContentProvider; 111import android.content.ContentResolver; 112import android.content.Context; 113import android.content.DialogInterface; 114import android.content.IContentProvider; 115import android.content.IIntentReceiver; 116import android.content.IIntentSender; 117import android.content.Intent; 118import android.content.IntentFilter; 119import android.content.IntentSender; 120import android.content.pm.ActivityInfo; 121import android.content.pm.ApplicationInfo; 122import android.content.pm.ConfigurationInfo; 123import android.content.pm.IPackageDataObserver; 124import android.content.pm.IPackageManager; 125import android.content.pm.InstrumentationInfo; 126import android.content.pm.PackageInfo; 127import android.content.pm.PackageManager; 128import android.content.pm.ParceledListSlice; 129import android.content.pm.UserInfo; 130import android.content.pm.PackageManager.NameNotFoundException; 131import android.content.pm.PathPermission; 132import android.content.pm.ProviderInfo; 133import android.content.pm.ResolveInfo; 134import android.content.pm.ServiceInfo; 135import android.content.res.CompatibilityInfo; 136import android.content.res.Configuration; 137import android.graphics.Bitmap; 138import android.net.Proxy; 139import android.net.ProxyInfo; 140import android.net.Uri; 141import android.os.Binder; 142import android.os.Build; 143import android.os.Bundle; 144import android.os.Debug; 145import android.os.DropBoxManager; 146import android.os.Environment; 147import android.os.FactoryTest; 148import android.os.FileObserver; 149import android.os.FileUtils; 150import android.os.Handler; 151import android.os.IBinder; 152import android.os.IPermissionController; 153import android.os.IRemoteCallback; 154import android.os.IUserManager; 155import android.os.Looper; 156import android.os.Message; 157import android.os.Parcel; 158import android.os.ParcelFileDescriptor; 159import android.os.Process; 160import android.os.RemoteCallbackList; 161import android.os.RemoteException; 162import android.os.SELinux; 163import android.os.ServiceManager; 164import android.os.StrictMode; 165import android.os.SystemClock; 166import android.os.SystemProperties; 167import android.os.UpdateLock; 168import android.os.UserHandle; 169import android.provider.Settings; 170import android.text.format.DateUtils; 171import android.text.format.Time; 172import android.util.AtomicFile; 173import android.util.EventLog; 174import android.util.Log; 175import android.util.Pair; 176import android.util.PrintWriterPrinter; 177import android.util.Slog; 178import android.util.SparseArray; 179import android.util.TimeUtils; 180import android.util.Xml; 181import android.view.Gravity; 182import android.view.LayoutInflater; 183import android.view.View; 184import android.view.WindowManager; 185 186import java.io.BufferedInputStream; 187import java.io.BufferedOutputStream; 188import java.io.DataInputStream; 189import java.io.DataOutputStream; 190import java.io.File; 191import java.io.FileDescriptor; 192import java.io.FileInputStream; 193import java.io.FileNotFoundException; 194import java.io.FileOutputStream; 195import java.io.IOException; 196import java.io.InputStreamReader; 197import java.io.PrintWriter; 198import java.io.StringWriter; 199import java.lang.ref.WeakReference; 200import java.util.ArrayList; 201import java.util.Arrays; 202import java.util.Collections; 203import java.util.Comparator; 204import java.util.HashMap; 205import java.util.HashSet; 206import java.util.Iterator; 207import java.util.List; 208import java.util.Locale; 209import java.util.Map; 210import java.util.Set; 211import java.util.concurrent.atomic.AtomicBoolean; 212import java.util.concurrent.atomic.AtomicLong; 213 214public final class ActivityManagerService extends ActivityManagerNative 215 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 216 private static final String USER_DATA_DIR = "/data/user/"; 217 static final String TAG = "ActivityManager"; 218 static final String TAG_MU = "ActivityManagerServiceMU"; 219 static final boolean DEBUG = false; 220 static final boolean localLOGV = DEBUG; 221 static final boolean DEBUG_BACKUP = localLOGV || false; 222 static final boolean DEBUG_BROADCAST = localLOGV || false; 223 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 224 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 225 static final boolean DEBUG_CLEANUP = localLOGV || false; 226 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 227 static final boolean DEBUG_FOCUS = false; 228 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 229 static final boolean DEBUG_MU = localLOGV || false; 230 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 231 static final boolean DEBUG_LRU = localLOGV || false; 232 static final boolean DEBUG_PAUSE = localLOGV || false; 233 static final boolean DEBUG_POWER = localLOGV || false; 234 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 235 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 236 static final boolean DEBUG_PROCESSES = localLOGV || false; 237 static final boolean DEBUG_PROVIDER = localLOGV || false; 238 static final boolean DEBUG_RESULTS = localLOGV || false; 239 static final boolean DEBUG_SERVICE = localLOGV || false; 240 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 241 static final boolean DEBUG_STACK = localLOGV || false; 242 static final boolean DEBUG_SWITCH = localLOGV || false; 243 static final boolean DEBUG_TASKS = localLOGV || false; 244 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 245 static final boolean DEBUG_TRANSITION = localLOGV || false; 246 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 247 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 248 static final boolean DEBUG_VISBILITY = localLOGV || false; 249 static final boolean DEBUG_PSS = localLOGV || false; 250 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 251 static final boolean VALIDATE_TOKENS = false; 252 static final boolean SHOW_ACTIVITY_START_TIME = true; 253 254 // Control over CPU and battery monitoring. 255 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 256 static final boolean MONITOR_CPU_USAGE = true; 257 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 258 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 259 static final boolean MONITOR_THREAD_CPU_USAGE = false; 260 261 // The flags that are set for all calls we make to the package manager. 262 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 263 264 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 265 266 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 267 268 // Maximum number of recent tasks that we can remember. 269 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 270 271 // Amount of time after a call to stopAppSwitches() during which we will 272 // prevent further untrusted switches from happening. 273 static final long APP_SWITCH_DELAY_TIME = 5*1000; 274 275 // How long we wait for a launched process to attach to the activity manager 276 // before we decide it's never going to come up for real. 277 static final int PROC_START_TIMEOUT = 10*1000; 278 279 // How long we wait for a launched process to attach to the activity manager 280 // before we decide it's never going to come up for real, when the process was 281 // started with a wrapper for instrumentation (such as Valgrind) because it 282 // could take much longer than usual. 283 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 284 285 // How long to wait after going idle before forcing apps to GC. 286 static final int GC_TIMEOUT = 5*1000; 287 288 // The minimum amount of time between successive GC requests for a process. 289 static final int GC_MIN_INTERVAL = 60*1000; 290 291 // The minimum amount of time between successive PSS requests for a process. 292 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 293 294 // The minimum amount of time between successive PSS requests for a process 295 // when the request is due to the memory state being lowered. 296 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 297 298 // The rate at which we check for apps using excessive power -- 15 mins. 299 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 300 301 // The minimum sample duration we will allow before deciding we have 302 // enough data on wake locks to start killing things. 303 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 304 305 // The minimum sample duration we will allow before deciding we have 306 // enough data on CPU usage to start killing things. 307 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 308 309 // How long we allow a receiver to run before giving up on it. 310 static final int BROADCAST_FG_TIMEOUT = 10*1000; 311 static final int BROADCAST_BG_TIMEOUT = 60*1000; 312 313 // How long we wait until we timeout on key dispatching. 314 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 315 316 // How long we wait until we timeout on key dispatching during instrumentation. 317 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 318 319 // Amount of time we wait for observers to handle a user switch before 320 // giving up on them and unfreezing the screen. 321 static final int USER_SWITCH_TIMEOUT = 2*1000; 322 323 // Maximum number of users we allow to be running at a time. 324 static final int MAX_RUNNING_USERS = 3; 325 326 // How long to wait in getAssistContextExtras for the activity and foreground services 327 // to respond with the result. 328 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 329 330 // Maximum number of persisted Uri grants a package is allowed 331 static final int MAX_PERSISTED_URI_GRANTS = 128; 332 333 static final int MY_PID = Process.myPid(); 334 335 static final String[] EMPTY_STRING_ARRAY = new String[0]; 336 337 // How many bytes to write into the dropbox log before truncating 338 static final int DROPBOX_MAX_SIZE = 256 * 1024; 339 340 /** All system services */ 341 SystemServiceManager mSystemServiceManager; 342 343 /** Run all ActivityStacks through this */ 344 ActivityStackSupervisor mStackSupervisor; 345 346 public IntentFirewall mIntentFirewall; 347 348 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 349 // default actuion automatically. Important for devices without direct input 350 // devices. 351 private boolean mShowDialogs = true; 352 353 /** 354 * Description of a request to start a new activity, which has been held 355 * due to app switches being disabled. 356 */ 357 static class PendingActivityLaunch { 358 final ActivityRecord r; 359 final ActivityRecord sourceRecord; 360 final int startFlags; 361 final ActivityStack stack; 362 363 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 364 int _startFlags, ActivityStack _stack) { 365 r = _r; 366 sourceRecord = _sourceRecord; 367 startFlags = _startFlags; 368 stack = _stack; 369 } 370 } 371 372 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 373 = new ArrayList<PendingActivityLaunch>(); 374 375 BroadcastQueue mFgBroadcastQueue; 376 BroadcastQueue mBgBroadcastQueue; 377 // Convenient for easy iteration over the queues. Foreground is first 378 // so that dispatch of foreground broadcasts gets precedence. 379 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 380 381 BroadcastQueue broadcastQueueForIntent(Intent intent) { 382 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 383 if (DEBUG_BACKGROUND_BROADCAST) { 384 Slog.i(TAG, "Broadcast intent " + intent + " on " 385 + (isFg ? "foreground" : "background") 386 + " queue"); 387 } 388 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 389 } 390 391 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 392 for (BroadcastQueue queue : mBroadcastQueues) { 393 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 394 if (r != null) { 395 return r; 396 } 397 } 398 return null; 399 } 400 401 /** 402 * Activity we have told the window manager to have key focus. 403 */ 404 ActivityRecord mFocusedActivity = null; 405 406 /** 407 * List of intents that were used to start the most recent tasks. 408 */ 409 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 410 411 public class PendingAssistExtras extends Binder implements Runnable { 412 public final ActivityRecord activity; 413 public boolean haveResult = false; 414 public Bundle result = null; 415 public PendingAssistExtras(ActivityRecord _activity) { 416 activity = _activity; 417 } 418 @Override 419 public void run() { 420 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 421 synchronized (this) { 422 haveResult = true; 423 notifyAll(); 424 } 425 } 426 } 427 428 final ArrayList<PendingAssistExtras> mPendingAssistExtras 429 = new ArrayList<PendingAssistExtras>(); 430 431 /** 432 * Process management. 433 */ 434 final ProcessList mProcessList = new ProcessList(); 435 436 /** 437 * All of the applications we currently have running organized by name. 438 * The keys are strings of the application package name (as 439 * returned by the package manager), and the keys are ApplicationRecord 440 * objects. 441 */ 442 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 443 444 /** 445 * Tracking long-term execution of processes to look for abuse and other 446 * bad app behavior. 447 */ 448 final ProcessStatsService mProcessStats; 449 450 /** 451 * The currently running isolated processes. 452 */ 453 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 454 455 /** 456 * Counter for assigning isolated process uids, to avoid frequently reusing the 457 * same ones. 458 */ 459 int mNextIsolatedProcessUid = 0; 460 461 /** 462 * The currently running heavy-weight process, if any. 463 */ 464 ProcessRecord mHeavyWeightProcess = null; 465 466 /** 467 * The last time that various processes have crashed. 468 */ 469 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 470 471 /** 472 * Information about a process that is currently marked as bad. 473 */ 474 static final class BadProcessInfo { 475 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 476 this.time = time; 477 this.shortMsg = shortMsg; 478 this.longMsg = longMsg; 479 this.stack = stack; 480 } 481 482 final long time; 483 final String shortMsg; 484 final String longMsg; 485 final String stack; 486 } 487 488 /** 489 * Set of applications that we consider to be bad, and will reject 490 * incoming broadcasts from (which the user has no control over). 491 * Processes are added to this set when they have crashed twice within 492 * a minimum amount of time; they are removed from it when they are 493 * later restarted (hopefully due to some user action). The value is the 494 * time it was added to the list. 495 */ 496 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 497 498 /** 499 * All of the processes we currently have running organized by pid. 500 * The keys are the pid running the application. 501 * 502 * <p>NOTE: This object is protected by its own lock, NOT the global 503 * activity manager lock! 504 */ 505 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 506 507 /** 508 * All of the processes that have been forced to be foreground. The key 509 * is the pid of the caller who requested it (we hold a death 510 * link on it). 511 */ 512 abstract class ForegroundToken implements IBinder.DeathRecipient { 513 int pid; 514 IBinder token; 515 } 516 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 517 518 /** 519 * List of records for processes that someone had tried to start before the 520 * system was ready. We don't start them at that point, but ensure they 521 * are started by the time booting is complete. 522 */ 523 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 524 525 /** 526 * List of persistent applications that are in the process 527 * of being started. 528 */ 529 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 530 531 /** 532 * Processes that are being forcibly torn down. 533 */ 534 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 535 536 /** 537 * List of running applications, sorted by recent usage. 538 * The first entry in the list is the least recently used. 539 */ 540 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 541 542 /** 543 * Where in mLruProcesses that the processes hosting activities start. 544 */ 545 int mLruProcessActivityStart = 0; 546 547 /** 548 * Where in mLruProcesses that the processes hosting services start. 549 * This is after (lower index) than mLruProcessesActivityStart. 550 */ 551 int mLruProcessServiceStart = 0; 552 553 /** 554 * List of processes that should gc as soon as things are idle. 555 */ 556 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 557 558 /** 559 * Processes we want to collect PSS data from. 560 */ 561 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 562 563 /** 564 * Last time we requested PSS data of all processes. 565 */ 566 long mLastFullPssTime = SystemClock.uptimeMillis(); 567 568 /** 569 * This is the process holding what we currently consider to be 570 * the "home" activity. 571 */ 572 ProcessRecord mHomeProcess; 573 574 /** 575 * This is the process holding the activity the user last visited that 576 * is in a different process from the one they are currently in. 577 */ 578 ProcessRecord mPreviousProcess; 579 580 /** 581 * The time at which the previous process was last visible. 582 */ 583 long mPreviousProcessVisibleTime; 584 585 /** 586 * Which uses have been started, so are allowed to run code. 587 */ 588 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 589 590 /** 591 * LRU list of history of current users. Most recently current is at the end. 592 */ 593 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 594 595 /** 596 * Constant array of the users that are currently started. 597 */ 598 int[] mStartedUserArray = new int[] { 0 }; 599 600 /** 601 * Registered observers of the user switching mechanics. 602 */ 603 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 604 = new RemoteCallbackList<IUserSwitchObserver>(); 605 606 /** 607 * Currently active user switch. 608 */ 609 Object mCurUserSwitchCallback; 610 611 /** 612 * Packages that the user has asked to have run in screen size 613 * compatibility mode instead of filling the screen. 614 */ 615 final CompatModePackages mCompatModePackages; 616 617 /** 618 * Set of IntentSenderRecord objects that are currently active. 619 */ 620 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 621 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 622 623 /** 624 * Fingerprints (hashCode()) of stack traces that we've 625 * already logged DropBox entries for. Guarded by itself. If 626 * something (rogue user app) forces this over 627 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 628 */ 629 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 630 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 631 632 /** 633 * Strict Mode background batched logging state. 634 * 635 * The string buffer is guarded by itself, and its lock is also 636 * used to determine if another batched write is already 637 * in-flight. 638 */ 639 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 640 641 /** 642 * Keeps track of all IIntentReceivers that have been registered for 643 * broadcasts. Hash keys are the receiver IBinder, hash value is 644 * a ReceiverList. 645 */ 646 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 647 new HashMap<IBinder, ReceiverList>(); 648 649 /** 650 * Resolver for broadcast intents to registered receivers. 651 * Holds BroadcastFilter (subclass of IntentFilter). 652 */ 653 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 654 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 655 @Override 656 protected boolean allowFilterResult( 657 BroadcastFilter filter, List<BroadcastFilter> dest) { 658 IBinder target = filter.receiverList.receiver.asBinder(); 659 for (int i=dest.size()-1; i>=0; i--) { 660 if (dest.get(i).receiverList.receiver.asBinder() == target) { 661 return false; 662 } 663 } 664 return true; 665 } 666 667 @Override 668 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 669 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 670 || userId == filter.owningUserId) { 671 return super.newResult(filter, match, userId); 672 } 673 return null; 674 } 675 676 @Override 677 protected BroadcastFilter[] newArray(int size) { 678 return new BroadcastFilter[size]; 679 } 680 681 @Override 682 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 683 return packageName.equals(filter.packageName); 684 } 685 }; 686 687 /** 688 * State of all active sticky broadcasts per user. Keys are the action of the 689 * sticky Intent, values are an ArrayList of all broadcasted intents with 690 * that action (which should usually be one). The SparseArray is keyed 691 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 692 * for stickies that are sent to all users. 693 */ 694 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 695 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 696 697 final ActiveServices mServices; 698 699 /** 700 * Backup/restore process management 701 */ 702 String mBackupAppName = null; 703 BackupRecord mBackupTarget = null; 704 705 final ProviderMap mProviderMap; 706 707 /** 708 * List of content providers who have clients waiting for them. The 709 * application is currently being launched and the provider will be 710 * removed from this list once it is published. 711 */ 712 final ArrayList<ContentProviderRecord> mLaunchingProviders 713 = new ArrayList<ContentProviderRecord>(); 714 715 /** 716 * File storing persisted {@link #mGrantedUriPermissions}. 717 */ 718 private final AtomicFile mGrantFile; 719 720 /** XML constants used in {@link #mGrantFile} */ 721 private static final String TAG_URI_GRANTS = "uri-grants"; 722 private static final String TAG_URI_GRANT = "uri-grant"; 723 private static final String ATTR_USER_HANDLE = "userHandle"; 724 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 725 private static final String ATTR_TARGET_PKG = "targetPkg"; 726 private static final String ATTR_URI = "uri"; 727 private static final String ATTR_MODE_FLAGS = "modeFlags"; 728 private static final String ATTR_CREATED_TIME = "createdTime"; 729 private static final String ATTR_PREFIX = "prefix"; 730 731 /** 732 * Global set of specific {@link Uri} permissions that have been granted. 733 * This optimized lookup structure maps from {@link UriPermission#targetUid} 734 * to {@link UriPermission#uri} to {@link UriPermission}. 735 */ 736 @GuardedBy("this") 737 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 738 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 739 740 public static class GrantUri { 741 public final Uri uri; 742 public final boolean prefix; 743 744 public GrantUri(Uri uri, boolean prefix) { 745 this.uri = uri; 746 this.prefix = prefix; 747 } 748 749 @Override 750 public int hashCode() { 751 return toString().hashCode(); 752 } 753 754 @Override 755 public boolean equals(Object o) { 756 if (o instanceof GrantUri) { 757 GrantUri other = (GrantUri) o; 758 return uri.equals(other.uri) && prefix == other.prefix; 759 } 760 return false; 761 } 762 763 @Override 764 public String toString() { 765 if (prefix) { 766 return uri.toString() + " [prefix]"; 767 } else { 768 return uri.toString(); 769 } 770 } 771 } 772 773 CoreSettingsObserver mCoreSettingsObserver; 774 775 /** 776 * Thread-local storage used to carry caller permissions over through 777 * indirect content-provider access. 778 */ 779 private class Identity { 780 public int pid; 781 public int uid; 782 783 Identity(int _pid, int _uid) { 784 pid = _pid; 785 uid = _uid; 786 } 787 } 788 789 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 790 791 /** 792 * All information we have collected about the runtime performance of 793 * any user id that can impact battery performance. 794 */ 795 final BatteryStatsService mBatteryStatsService; 796 797 /** 798 * Information about component usage 799 */ 800 final UsageStatsService mUsageStatsService; 801 802 /** 803 * Information about and control over application operations 804 */ 805 final AppOpsService mAppOpsService; 806 807 /** 808 * Current configuration information. HistoryRecord objects are given 809 * a reference to this object to indicate which configuration they are 810 * currently running in, so this object must be kept immutable. 811 */ 812 Configuration mConfiguration = new Configuration(); 813 814 /** 815 * Current sequencing integer of the configuration, for skipping old 816 * configurations. 817 */ 818 int mConfigurationSeq = 0; 819 820 /** 821 * Hardware-reported OpenGLES version. 822 */ 823 final int GL_ES_VERSION; 824 825 /** 826 * List of initialization arguments to pass to all processes when binding applications to them. 827 * For example, references to the commonly used services. 828 */ 829 HashMap<String, IBinder> mAppBindArgs; 830 831 /** 832 * Temporary to avoid allocations. Protected by main lock. 833 */ 834 final StringBuilder mStringBuilder = new StringBuilder(256); 835 836 /** 837 * Used to control how we initialize the service. 838 */ 839 ComponentName mTopComponent; 840 String mTopAction = Intent.ACTION_MAIN; 841 String mTopData; 842 boolean mProcessesReady = false; 843 boolean mSystemReady = false; 844 boolean mBooting = false; 845 boolean mWaitingUpdate = false; 846 boolean mDidUpdate = false; 847 boolean mOnBattery = false; 848 boolean mLaunchWarningShown = false; 849 850 Context mContext; 851 852 int mFactoryTest; 853 854 boolean mCheckedForSetup; 855 856 /** 857 * The time at which we will allow normal application switches again, 858 * after a call to {@link #stopAppSwitches()}. 859 */ 860 long mAppSwitchesAllowedTime; 861 862 /** 863 * This is set to true after the first switch after mAppSwitchesAllowedTime 864 * is set; any switches after that will clear the time. 865 */ 866 boolean mDidAppSwitch; 867 868 /** 869 * Last time (in realtime) at which we checked for power usage. 870 */ 871 long mLastPowerCheckRealtime; 872 873 /** 874 * Last time (in uptime) at which we checked for power usage. 875 */ 876 long mLastPowerCheckUptime; 877 878 /** 879 * Set while we are wanting to sleep, to prevent any 880 * activities from being started/resumed. 881 */ 882 private boolean mSleeping = false; 883 884 /** 885 * Set while we are running a voice interaction. This overrides 886 * sleeping while it is active. 887 */ 888 private boolean mRunningVoice = false; 889 890 /** 891 * State of external calls telling us if the device is asleep. 892 */ 893 private boolean mWentToSleep = false; 894 895 /** 896 * State of external call telling us if the lock screen is shown. 897 */ 898 private boolean mLockScreenShown = false; 899 900 /** 901 * Set if we are shutting down the system, similar to sleeping. 902 */ 903 boolean mShuttingDown = false; 904 905 /** 906 * Current sequence id for oom_adj computation traversal. 907 */ 908 int mAdjSeq = 0; 909 910 /** 911 * Current sequence id for process LRU updating. 912 */ 913 int mLruSeq = 0; 914 915 /** 916 * Keep track of the non-cached/empty process we last found, to help 917 * determine how to distribute cached/empty processes next time. 918 */ 919 int mNumNonCachedProcs = 0; 920 921 /** 922 * Keep track of the number of cached hidden procs, to balance oom adj 923 * distribution between those and empty procs. 924 */ 925 int mNumCachedHiddenProcs = 0; 926 927 /** 928 * Keep track of the number of service processes we last found, to 929 * determine on the next iteration which should be B services. 930 */ 931 int mNumServiceProcs = 0; 932 int mNewNumAServiceProcs = 0; 933 int mNewNumServiceProcs = 0; 934 935 /** 936 * Allow the current computed overall memory level of the system to go down? 937 * This is set to false when we are killing processes for reasons other than 938 * memory management, so that the now smaller process list will not be taken as 939 * an indication that memory is tighter. 940 */ 941 boolean mAllowLowerMemLevel = false; 942 943 /** 944 * The last computed memory level, for holding when we are in a state that 945 * processes are going away for other reasons. 946 */ 947 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 948 949 /** 950 * The last total number of process we have, to determine if changes actually look 951 * like a shrinking number of process due to lower RAM. 952 */ 953 int mLastNumProcesses; 954 955 /** 956 * The uptime of the last time we performed idle maintenance. 957 */ 958 long mLastIdleTime = SystemClock.uptimeMillis(); 959 960 /** 961 * Total time spent with RAM that has been added in the past since the last idle time. 962 */ 963 long mLowRamTimeSinceLastIdle = 0; 964 965 /** 966 * If RAM is currently low, when that horrible situation started. 967 */ 968 long mLowRamStartTime = 0; 969 970 /** 971 * For reporting to battery stats the current top application. 972 */ 973 private String mCurResumedPackage = null; 974 private int mCurResumedUid = -1; 975 976 /** 977 * For reporting to battery stats the apps currently running foreground 978 * service. The ProcessMap is package/uid tuples; each of these contain 979 * an array of the currently foreground processes. 980 */ 981 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 982 = new ProcessMap<ArrayList<ProcessRecord>>(); 983 984 /** 985 * This is set if we had to do a delayed dexopt of an app before launching 986 * it, to increase the ANR timeouts in that case. 987 */ 988 boolean mDidDexOpt; 989 990 /** 991 * Set if the systemServer made a call to enterSafeMode. 992 */ 993 boolean mSafeMode; 994 995 String mDebugApp = null; 996 boolean mWaitForDebugger = false; 997 boolean mDebugTransient = false; 998 String mOrigDebugApp = null; 999 boolean mOrigWaitForDebugger = false; 1000 boolean mAlwaysFinishActivities = false; 1001 IActivityController mController = null; 1002 String mProfileApp = null; 1003 ProcessRecord mProfileProc = null; 1004 String mProfileFile; 1005 ParcelFileDescriptor mProfileFd; 1006 int mProfileType = 0; 1007 boolean mAutoStopProfiler = false; 1008 String mOpenGlTraceApp = null; 1009 1010 static class ProcessChangeItem { 1011 static final int CHANGE_ACTIVITIES = 1<<0; 1012 static final int CHANGE_PROCESS_STATE = 1<<1; 1013 int changes; 1014 int uid; 1015 int pid; 1016 int processState; 1017 boolean foregroundActivities; 1018 } 1019 1020 final RemoteCallbackList<IProcessObserver> mProcessObservers 1021 = new RemoteCallbackList<IProcessObserver>(); 1022 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1023 1024 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1025 = new ArrayList<ProcessChangeItem>(); 1026 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1027 = new ArrayList<ProcessChangeItem>(); 1028 1029 /** 1030 * Runtime CPU use collection thread. This object's lock is used to 1031 * protect all related state. 1032 */ 1033 final Thread mProcessCpuThread; 1034 1035 /** 1036 * Used to collect process stats when showing not responding dialog. 1037 * Protected by mProcessCpuThread. 1038 */ 1039 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1040 MONITOR_THREAD_CPU_USAGE); 1041 final AtomicLong mLastCpuTime = new AtomicLong(0); 1042 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1043 1044 long mLastWriteTime = 0; 1045 1046 /** 1047 * Used to retain an update lock when the foreground activity is in 1048 * immersive mode. 1049 */ 1050 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1051 1052 /** 1053 * Set to true after the system has finished booting. 1054 */ 1055 boolean mBooted = false; 1056 1057 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1058 int mProcessLimitOverride = -1; 1059 1060 WindowManagerService mWindowManager; 1061 1062 final ActivityThread mSystemThread; 1063 1064 int mCurrentUserId = 0; 1065 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1066 private UserManagerService mUserManager; 1067 1068 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1069 final ProcessRecord mApp; 1070 final int mPid; 1071 final IApplicationThread mAppThread; 1072 1073 AppDeathRecipient(ProcessRecord app, int pid, 1074 IApplicationThread thread) { 1075 if (localLOGV) Slog.v( 1076 TAG, "New death recipient " + this 1077 + " for thread " + thread.asBinder()); 1078 mApp = app; 1079 mPid = pid; 1080 mAppThread = thread; 1081 } 1082 1083 @Override 1084 public void binderDied() { 1085 if (localLOGV) Slog.v( 1086 TAG, "Death received in " + this 1087 + " for thread " + mAppThread.asBinder()); 1088 synchronized(ActivityManagerService.this) { 1089 appDiedLocked(mApp, mPid, mAppThread); 1090 } 1091 } 1092 } 1093 1094 static final int SHOW_ERROR_MSG = 1; 1095 static final int SHOW_NOT_RESPONDING_MSG = 2; 1096 static final int SHOW_FACTORY_ERROR_MSG = 3; 1097 static final int UPDATE_CONFIGURATION_MSG = 4; 1098 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1099 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1100 static final int SERVICE_TIMEOUT_MSG = 12; 1101 static final int UPDATE_TIME_ZONE = 13; 1102 static final int SHOW_UID_ERROR_MSG = 14; 1103 static final int IM_FEELING_LUCKY_MSG = 15; 1104 static final int PROC_START_TIMEOUT_MSG = 20; 1105 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1106 static final int KILL_APPLICATION_MSG = 22; 1107 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1108 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1109 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1110 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1111 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1112 static final int CLEAR_DNS_CACHE_MSG = 28; 1113 static final int UPDATE_HTTP_PROXY_MSG = 29; 1114 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1115 static final int DISPATCH_PROCESSES_CHANGED = 31; 1116 static final int DISPATCH_PROCESS_DIED = 32; 1117 static final int REPORT_MEM_USAGE_MSG = 33; 1118 static final int REPORT_USER_SWITCH_MSG = 34; 1119 static final int CONTINUE_USER_SWITCH_MSG = 35; 1120 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1121 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1122 static final int PERSIST_URI_GRANTS_MSG = 38; 1123 static final int REQUEST_ALL_PSS_MSG = 39; 1124 static final int START_PROFILES_MSG = 40; 1125 static final int UPDATE_TIME = 41; 1126 static final int SYSTEM_USER_START_MSG = 42; 1127 static final int SYSTEM_USER_CURRENT_MSG = 43; 1128 1129 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1130 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1131 static final int FIRST_COMPAT_MODE_MSG = 300; 1132 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1133 1134 AlertDialog mUidAlert; 1135 CompatModeDialog mCompatModeDialog; 1136 long mLastMemUsageReportTime = 0; 1137 1138 /** 1139 * Flag whether the current user is a "monkey", i.e. whether 1140 * the UI is driven by a UI automation tool. 1141 */ 1142 private boolean mUserIsMonkey; 1143 1144 final ServiceThread mHandlerThread; 1145 final MainHandler mHandler; 1146 1147 final class MainHandler extends Handler { 1148 public MainHandler(Looper looper) { 1149 super(looper, null, true); 1150 } 1151 1152 @Override 1153 public void handleMessage(Message msg) { 1154 switch (msg.what) { 1155 case SHOW_ERROR_MSG: { 1156 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1157 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1158 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1159 synchronized (ActivityManagerService.this) { 1160 ProcessRecord proc = (ProcessRecord)data.get("app"); 1161 AppErrorResult res = (AppErrorResult) data.get("result"); 1162 if (proc != null && proc.crashDialog != null) { 1163 Slog.e(TAG, "App already has crash dialog: " + proc); 1164 if (res != null) { 1165 res.set(0); 1166 } 1167 return; 1168 } 1169 if (!showBackground && UserHandle.getAppId(proc.uid) 1170 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1171 && proc.pid != MY_PID) { 1172 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1173 if (res != null) { 1174 res.set(0); 1175 } 1176 return; 1177 } 1178 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1179 Dialog d = new AppErrorDialog(mContext, 1180 ActivityManagerService.this, res, proc); 1181 d.show(); 1182 proc.crashDialog = d; 1183 } else { 1184 // The device is asleep, so just pretend that the user 1185 // saw a crash dialog and hit "force quit". 1186 if (res != null) { 1187 res.set(0); 1188 } 1189 } 1190 } 1191 1192 ensureBootCompleted(); 1193 } break; 1194 case SHOW_NOT_RESPONDING_MSG: { 1195 synchronized (ActivityManagerService.this) { 1196 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1197 ProcessRecord proc = (ProcessRecord)data.get("app"); 1198 if (proc != null && proc.anrDialog != null) { 1199 Slog.e(TAG, "App already has anr dialog: " + proc); 1200 return; 1201 } 1202 1203 Intent intent = new Intent("android.intent.action.ANR"); 1204 if (!mProcessesReady) { 1205 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1206 | Intent.FLAG_RECEIVER_FOREGROUND); 1207 } 1208 broadcastIntentLocked(null, null, intent, 1209 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1210 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1211 1212 if (mShowDialogs) { 1213 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1214 mContext, proc, (ActivityRecord)data.get("activity"), 1215 msg.arg1 != 0); 1216 d.show(); 1217 proc.anrDialog = d; 1218 } else { 1219 // Just kill the app if there is no dialog to be shown. 1220 killAppAtUsersRequest(proc, null); 1221 } 1222 } 1223 1224 ensureBootCompleted(); 1225 } break; 1226 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1227 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1228 synchronized (ActivityManagerService.this) { 1229 ProcessRecord proc = (ProcessRecord) data.get("app"); 1230 if (proc == null) { 1231 Slog.e(TAG, "App not found when showing strict mode dialog."); 1232 break; 1233 } 1234 if (proc.crashDialog != null) { 1235 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1236 return; 1237 } 1238 AppErrorResult res = (AppErrorResult) data.get("result"); 1239 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1240 Dialog d = new StrictModeViolationDialog(mContext, 1241 ActivityManagerService.this, res, proc); 1242 d.show(); 1243 proc.crashDialog = d; 1244 } else { 1245 // The device is asleep, so just pretend that the user 1246 // saw a crash dialog and hit "force quit". 1247 res.set(0); 1248 } 1249 } 1250 ensureBootCompleted(); 1251 } break; 1252 case SHOW_FACTORY_ERROR_MSG: { 1253 Dialog d = new FactoryErrorDialog( 1254 mContext, msg.getData().getCharSequence("msg")); 1255 d.show(); 1256 ensureBootCompleted(); 1257 } break; 1258 case UPDATE_CONFIGURATION_MSG: { 1259 final ContentResolver resolver = mContext.getContentResolver(); 1260 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1261 } break; 1262 case GC_BACKGROUND_PROCESSES_MSG: { 1263 synchronized (ActivityManagerService.this) { 1264 performAppGcsIfAppropriateLocked(); 1265 } 1266 } break; 1267 case WAIT_FOR_DEBUGGER_MSG: { 1268 synchronized (ActivityManagerService.this) { 1269 ProcessRecord app = (ProcessRecord)msg.obj; 1270 if (msg.arg1 != 0) { 1271 if (!app.waitedForDebugger) { 1272 Dialog d = new AppWaitingForDebuggerDialog( 1273 ActivityManagerService.this, 1274 mContext, app); 1275 app.waitDialog = d; 1276 app.waitedForDebugger = true; 1277 d.show(); 1278 } 1279 } else { 1280 if (app.waitDialog != null) { 1281 app.waitDialog.dismiss(); 1282 app.waitDialog = null; 1283 } 1284 } 1285 } 1286 } break; 1287 case SERVICE_TIMEOUT_MSG: { 1288 if (mDidDexOpt) { 1289 mDidDexOpt = false; 1290 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1291 nmsg.obj = msg.obj; 1292 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1293 return; 1294 } 1295 mServices.serviceTimeout((ProcessRecord)msg.obj); 1296 } break; 1297 case UPDATE_TIME_ZONE: { 1298 synchronized (ActivityManagerService.this) { 1299 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1300 ProcessRecord r = mLruProcesses.get(i); 1301 if (r.thread != null) { 1302 try { 1303 r.thread.updateTimeZone(); 1304 } catch (RemoteException ex) { 1305 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1306 } 1307 } 1308 } 1309 } 1310 } break; 1311 case CLEAR_DNS_CACHE_MSG: { 1312 synchronized (ActivityManagerService.this) { 1313 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1314 ProcessRecord r = mLruProcesses.get(i); 1315 if (r.thread != null) { 1316 try { 1317 r.thread.clearDnsCache(); 1318 } catch (RemoteException ex) { 1319 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1320 } 1321 } 1322 } 1323 } 1324 } break; 1325 case UPDATE_HTTP_PROXY_MSG: { 1326 ProxyInfo proxy = (ProxyInfo)msg.obj; 1327 String host = ""; 1328 String port = ""; 1329 String exclList = ""; 1330 String pacFileUrl = null; 1331 if (proxy != null) { 1332 host = proxy.getHost(); 1333 port = Integer.toString(proxy.getPort()); 1334 exclList = proxy.getExclusionListAsString(); 1335 pacFileUrl = proxy.getPacFileUrl().toString(); 1336 } 1337 synchronized (ActivityManagerService.this) { 1338 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1339 ProcessRecord r = mLruProcesses.get(i); 1340 if (r.thread != null) { 1341 try { 1342 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1343 } catch (RemoteException ex) { 1344 Slog.w(TAG, "Failed to update http proxy for: " + 1345 r.info.processName); 1346 } 1347 } 1348 } 1349 } 1350 } break; 1351 case SHOW_UID_ERROR_MSG: { 1352 String title = "System UIDs Inconsistent"; 1353 String text = "UIDs on the system are inconsistent, you need to wipe your" 1354 + " data partition or your device will be unstable."; 1355 Log.e(TAG, title + ": " + text); 1356 if (mShowDialogs) { 1357 // XXX This is a temporary dialog, no need to localize. 1358 AlertDialog d = new BaseErrorDialog(mContext); 1359 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1360 d.setCancelable(false); 1361 d.setTitle(title); 1362 d.setMessage(text); 1363 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1364 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1365 mUidAlert = d; 1366 d.show(); 1367 } 1368 } break; 1369 case IM_FEELING_LUCKY_MSG: { 1370 if (mUidAlert != null) { 1371 mUidAlert.dismiss(); 1372 mUidAlert = null; 1373 } 1374 } break; 1375 case PROC_START_TIMEOUT_MSG: { 1376 if (mDidDexOpt) { 1377 mDidDexOpt = false; 1378 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1379 nmsg.obj = msg.obj; 1380 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1381 return; 1382 } 1383 ProcessRecord app = (ProcessRecord)msg.obj; 1384 synchronized (ActivityManagerService.this) { 1385 processStartTimedOutLocked(app); 1386 } 1387 } break; 1388 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1389 synchronized (ActivityManagerService.this) { 1390 doPendingActivityLaunchesLocked(true); 1391 } 1392 } break; 1393 case KILL_APPLICATION_MSG: { 1394 synchronized (ActivityManagerService.this) { 1395 int appid = msg.arg1; 1396 boolean restart = (msg.arg2 == 1); 1397 Bundle bundle = (Bundle)msg.obj; 1398 String pkg = bundle.getString("pkg"); 1399 String reason = bundle.getString("reason"); 1400 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1401 false, UserHandle.USER_ALL, reason); 1402 } 1403 } break; 1404 case FINALIZE_PENDING_INTENT_MSG: { 1405 ((PendingIntentRecord)msg.obj).completeFinalize(); 1406 } break; 1407 case POST_HEAVY_NOTIFICATION_MSG: { 1408 INotificationManager inm = NotificationManager.getService(); 1409 if (inm == null) { 1410 return; 1411 } 1412 1413 ActivityRecord root = (ActivityRecord)msg.obj; 1414 ProcessRecord process = root.app; 1415 if (process == null) { 1416 return; 1417 } 1418 1419 try { 1420 Context context = mContext.createPackageContext(process.info.packageName, 0); 1421 String text = mContext.getString(R.string.heavy_weight_notification, 1422 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1423 Notification notification = new Notification(); 1424 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1425 notification.when = 0; 1426 notification.flags = Notification.FLAG_ONGOING_EVENT; 1427 notification.tickerText = text; 1428 notification.defaults = 0; // please be quiet 1429 notification.sound = null; 1430 notification.vibrate = null; 1431 notification.setLatestEventInfo(context, text, 1432 mContext.getText(R.string.heavy_weight_notification_detail), 1433 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1434 PendingIntent.FLAG_CANCEL_CURRENT, null, 1435 new UserHandle(root.userId))); 1436 1437 try { 1438 int[] outId = new int[1]; 1439 inm.enqueueNotificationWithTag("android", "android", null, 1440 R.string.heavy_weight_notification, 1441 notification, outId, root.userId); 1442 } catch (RuntimeException e) { 1443 Slog.w(ActivityManagerService.TAG, 1444 "Error showing notification for heavy-weight app", e); 1445 } catch (RemoteException e) { 1446 } 1447 } catch (NameNotFoundException e) { 1448 Slog.w(TAG, "Unable to create context for heavy notification", e); 1449 } 1450 } break; 1451 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1452 INotificationManager inm = NotificationManager.getService(); 1453 if (inm == null) { 1454 return; 1455 } 1456 try { 1457 inm.cancelNotificationWithTag("android", null, 1458 R.string.heavy_weight_notification, msg.arg1); 1459 } catch (RuntimeException e) { 1460 Slog.w(ActivityManagerService.TAG, 1461 "Error canceling notification for service", e); 1462 } catch (RemoteException e) { 1463 } 1464 } break; 1465 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1466 synchronized (ActivityManagerService.this) { 1467 checkExcessivePowerUsageLocked(true); 1468 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1469 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1470 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1471 } 1472 } break; 1473 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1474 synchronized (ActivityManagerService.this) { 1475 ActivityRecord ar = (ActivityRecord)msg.obj; 1476 if (mCompatModeDialog != null) { 1477 if (mCompatModeDialog.mAppInfo.packageName.equals( 1478 ar.info.applicationInfo.packageName)) { 1479 return; 1480 } 1481 mCompatModeDialog.dismiss(); 1482 mCompatModeDialog = null; 1483 } 1484 if (ar != null && false) { 1485 if (mCompatModePackages.getPackageAskCompatModeLocked( 1486 ar.packageName)) { 1487 int mode = mCompatModePackages.computeCompatModeLocked( 1488 ar.info.applicationInfo); 1489 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1490 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1491 mCompatModeDialog = new CompatModeDialog( 1492 ActivityManagerService.this, mContext, 1493 ar.info.applicationInfo); 1494 mCompatModeDialog.show(); 1495 } 1496 } 1497 } 1498 } 1499 break; 1500 } 1501 case DISPATCH_PROCESSES_CHANGED: { 1502 dispatchProcessesChanged(); 1503 break; 1504 } 1505 case DISPATCH_PROCESS_DIED: { 1506 final int pid = msg.arg1; 1507 final int uid = msg.arg2; 1508 dispatchProcessDied(pid, uid); 1509 break; 1510 } 1511 case REPORT_MEM_USAGE_MSG: { 1512 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1513 Thread thread = new Thread() { 1514 @Override public void run() { 1515 final SparseArray<ProcessMemInfo> infoMap 1516 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1517 for (int i=0, N=memInfos.size(); i<N; i++) { 1518 ProcessMemInfo mi = memInfos.get(i); 1519 infoMap.put(mi.pid, mi); 1520 } 1521 updateCpuStatsNow(); 1522 synchronized (mProcessCpuThread) { 1523 final int N = mProcessCpuTracker.countStats(); 1524 for (int i=0; i<N; i++) { 1525 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1526 if (st.vsize > 0) { 1527 long pss = Debug.getPss(st.pid, null); 1528 if (pss > 0) { 1529 if (infoMap.indexOfKey(st.pid) < 0) { 1530 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1531 ProcessList.NATIVE_ADJ, -1, "native", null); 1532 mi.pss = pss; 1533 memInfos.add(mi); 1534 } 1535 } 1536 } 1537 } 1538 } 1539 1540 long totalPss = 0; 1541 for (int i=0, N=memInfos.size(); i<N; i++) { 1542 ProcessMemInfo mi = memInfos.get(i); 1543 if (mi.pss == 0) { 1544 mi.pss = Debug.getPss(mi.pid, null); 1545 } 1546 totalPss += mi.pss; 1547 } 1548 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1549 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1550 if (lhs.oomAdj != rhs.oomAdj) { 1551 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1552 } 1553 if (lhs.pss != rhs.pss) { 1554 return lhs.pss < rhs.pss ? 1 : -1; 1555 } 1556 return 0; 1557 } 1558 }); 1559 1560 StringBuilder tag = new StringBuilder(128); 1561 StringBuilder stack = new StringBuilder(128); 1562 tag.append("Low on memory -- "); 1563 appendMemBucket(tag, totalPss, "total", false); 1564 appendMemBucket(stack, totalPss, "total", true); 1565 1566 StringBuilder logBuilder = new StringBuilder(1024); 1567 logBuilder.append("Low on memory:\n"); 1568 1569 boolean firstLine = true; 1570 int lastOomAdj = Integer.MIN_VALUE; 1571 for (int i=0, N=memInfos.size(); i<N; i++) { 1572 ProcessMemInfo mi = memInfos.get(i); 1573 1574 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1575 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1576 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1577 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1578 if (lastOomAdj != mi.oomAdj) { 1579 lastOomAdj = mi.oomAdj; 1580 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1581 tag.append(" / "); 1582 } 1583 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1584 if (firstLine) { 1585 stack.append(":"); 1586 firstLine = false; 1587 } 1588 stack.append("\n\t at "); 1589 } else { 1590 stack.append("$"); 1591 } 1592 } else { 1593 tag.append(" "); 1594 stack.append("$"); 1595 } 1596 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1597 appendMemBucket(tag, mi.pss, mi.name, false); 1598 } 1599 appendMemBucket(stack, mi.pss, mi.name, true); 1600 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1601 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1602 stack.append("("); 1603 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1604 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1605 stack.append(DUMP_MEM_OOM_LABEL[k]); 1606 stack.append(":"); 1607 stack.append(DUMP_MEM_OOM_ADJ[k]); 1608 } 1609 } 1610 stack.append(")"); 1611 } 1612 } 1613 1614 logBuilder.append(" "); 1615 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1616 logBuilder.append(' '); 1617 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1618 logBuilder.append(' '); 1619 ProcessList.appendRamKb(logBuilder, mi.pss); 1620 logBuilder.append(" kB: "); 1621 logBuilder.append(mi.name); 1622 logBuilder.append(" ("); 1623 logBuilder.append(mi.pid); 1624 logBuilder.append(") "); 1625 logBuilder.append(mi.adjType); 1626 logBuilder.append('\n'); 1627 if (mi.adjReason != null) { 1628 logBuilder.append(" "); 1629 logBuilder.append(mi.adjReason); 1630 logBuilder.append('\n'); 1631 } 1632 } 1633 1634 logBuilder.append(" "); 1635 ProcessList.appendRamKb(logBuilder, totalPss); 1636 logBuilder.append(" kB: TOTAL\n"); 1637 1638 long[] infos = new long[Debug.MEMINFO_COUNT]; 1639 Debug.getMemInfo(infos); 1640 logBuilder.append(" MemInfo: "); 1641 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1642 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1643 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1644 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1645 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1646 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1647 logBuilder.append(" ZRAM: "); 1648 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1649 logBuilder.append(" kB RAM, "); 1650 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1651 logBuilder.append(" kB swap total, "); 1652 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1653 logBuilder.append(" kB swap free\n"); 1654 } 1655 Slog.i(TAG, logBuilder.toString()); 1656 1657 StringBuilder dropBuilder = new StringBuilder(1024); 1658 /* 1659 StringWriter oomSw = new StringWriter(); 1660 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1661 StringWriter catSw = new StringWriter(); 1662 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1663 String[] emptyArgs = new String[] { }; 1664 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1665 oomPw.flush(); 1666 String oomString = oomSw.toString(); 1667 */ 1668 dropBuilder.append(stack); 1669 dropBuilder.append('\n'); 1670 dropBuilder.append('\n'); 1671 dropBuilder.append(logBuilder); 1672 dropBuilder.append('\n'); 1673 /* 1674 dropBuilder.append(oomString); 1675 dropBuilder.append('\n'); 1676 */ 1677 StringWriter catSw = new StringWriter(); 1678 synchronized (ActivityManagerService.this) { 1679 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1680 String[] emptyArgs = new String[] { }; 1681 catPw.println(); 1682 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1683 catPw.println(); 1684 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1685 false, false, null); 1686 catPw.println(); 1687 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1688 catPw.flush(); 1689 } 1690 dropBuilder.append(catSw.toString()); 1691 addErrorToDropBox("lowmem", null, "system_server", null, 1692 null, tag.toString(), dropBuilder.toString(), null, null); 1693 //Slog.i(TAG, "Sent to dropbox:"); 1694 //Slog.i(TAG, dropBuilder.toString()); 1695 synchronized (ActivityManagerService.this) { 1696 long now = SystemClock.uptimeMillis(); 1697 if (mLastMemUsageReportTime < now) { 1698 mLastMemUsageReportTime = now; 1699 } 1700 } 1701 } 1702 }; 1703 thread.start(); 1704 break; 1705 } 1706 case REPORT_USER_SWITCH_MSG: { 1707 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1708 break; 1709 } 1710 case CONTINUE_USER_SWITCH_MSG: { 1711 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1712 break; 1713 } 1714 case USER_SWITCH_TIMEOUT_MSG: { 1715 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1716 break; 1717 } 1718 case IMMERSIVE_MODE_LOCK_MSG: { 1719 final boolean nextState = (msg.arg1 != 0); 1720 if (mUpdateLock.isHeld() != nextState) { 1721 if (DEBUG_IMMERSIVE) { 1722 final ActivityRecord r = (ActivityRecord) msg.obj; 1723 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1724 } 1725 if (nextState) { 1726 mUpdateLock.acquire(); 1727 } else { 1728 mUpdateLock.release(); 1729 } 1730 } 1731 break; 1732 } 1733 case PERSIST_URI_GRANTS_MSG: { 1734 writeGrantedUriPermissions(); 1735 break; 1736 } 1737 case REQUEST_ALL_PSS_MSG: { 1738 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1739 break; 1740 } 1741 case START_PROFILES_MSG: { 1742 synchronized (ActivityManagerService.this) { 1743 startProfilesLocked(); 1744 } 1745 break; 1746 } 1747 case UPDATE_TIME: { 1748 synchronized (ActivityManagerService.this) { 1749 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1750 ProcessRecord r = mLruProcesses.get(i); 1751 if (r.thread != null) { 1752 try { 1753 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1754 } catch (RemoteException ex) { 1755 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1756 } 1757 } 1758 } 1759 } 1760 break; 1761 } 1762 case SYSTEM_USER_START_MSG: { 1763 mSystemServiceManager.startUser(msg.arg1); 1764 break; 1765 } 1766 case SYSTEM_USER_CURRENT_MSG: { 1767 mSystemServiceManager.switchUser(msg.arg1); 1768 break; 1769 } 1770 } 1771 } 1772 }; 1773 1774 static final int COLLECT_PSS_BG_MSG = 1; 1775 1776 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1777 @Override 1778 public void handleMessage(Message msg) { 1779 switch (msg.what) { 1780 case COLLECT_PSS_BG_MSG: { 1781 int i=0, num=0; 1782 long start = SystemClock.uptimeMillis(); 1783 long[] tmp = new long[1]; 1784 do { 1785 ProcessRecord proc; 1786 int procState; 1787 int pid; 1788 synchronized (ActivityManagerService.this) { 1789 if (i >= mPendingPssProcesses.size()) { 1790 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1791 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1792 mPendingPssProcesses.clear(); 1793 return; 1794 } 1795 proc = mPendingPssProcesses.get(i); 1796 procState = proc.pssProcState; 1797 if (proc.thread != null && procState == proc.setProcState) { 1798 pid = proc.pid; 1799 } else { 1800 proc = null; 1801 pid = 0; 1802 } 1803 i++; 1804 } 1805 if (proc != null) { 1806 long pss = Debug.getPss(pid, tmp); 1807 synchronized (ActivityManagerService.this) { 1808 if (proc.thread != null && proc.setProcState == procState 1809 && proc.pid == pid) { 1810 num++; 1811 proc.lastPssTime = SystemClock.uptimeMillis(); 1812 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1813 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1814 + ": " + pss + " lastPss=" + proc.lastPss 1815 + " state=" + ProcessList.makeProcStateString(procState)); 1816 if (proc.initialIdlePss == 0) { 1817 proc.initialIdlePss = pss; 1818 } 1819 proc.lastPss = pss; 1820 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1821 proc.lastCachedPss = pss; 1822 } 1823 } 1824 } 1825 } 1826 } while (true); 1827 } 1828 } 1829 } 1830 }; 1831 1832 /** 1833 * Monitor for package changes and update our internal state. 1834 */ 1835 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1836 @Override 1837 public void onPackageRemoved(String packageName, int uid) { 1838 // Remove all tasks with activities in the specified package from the list of recent tasks 1839 synchronized (ActivityManagerService.this) { 1840 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1841 TaskRecord tr = mRecentTasks.get(i); 1842 ComponentName cn = tr.intent.getComponent(); 1843 if (cn != null && cn.getPackageName().equals(packageName)) { 1844 // If the package name matches, remove the task and kill the process 1845 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1846 } 1847 } 1848 } 1849 } 1850 1851 @Override 1852 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1853 onPackageModified(packageName); 1854 return true; 1855 } 1856 1857 @Override 1858 public void onPackageModified(String packageName) { 1859 final PackageManager pm = mContext.getPackageManager(); 1860 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1861 new ArrayList<Pair<Intent, Integer>>(); 1862 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1863 // Copy the list of recent tasks so that we don't hold onto the lock on 1864 // ActivityManagerService for long periods while checking if components exist. 1865 synchronized (ActivityManagerService.this) { 1866 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1867 TaskRecord tr = mRecentTasks.get(i); 1868 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1869 } 1870 } 1871 // Check the recent tasks and filter out all tasks with components that no longer exist. 1872 Intent tmpI = new Intent(); 1873 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1874 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1875 ComponentName cn = p.first.getComponent(); 1876 if (cn != null && cn.getPackageName().equals(packageName)) { 1877 try { 1878 // Add the task to the list to remove if the component no longer exists 1879 tmpI.setComponent(cn); 1880 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1881 tasksToRemove.add(p.second); 1882 } 1883 } catch (Exception e) {} 1884 } 1885 } 1886 // Prune all the tasks with removed components from the list of recent tasks 1887 synchronized (ActivityManagerService.this) { 1888 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1889 // Remove the task but don't kill the process (since other components in that 1890 // package may still be running and in the background) 1891 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1892 } 1893 } 1894 } 1895 1896 @Override 1897 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1898 // Force stop the specified packages 1899 if (packages != null) { 1900 for (String pkg : packages) { 1901 synchronized (ActivityManagerService.this) { 1902 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1903 "finished booting")) { 1904 return true; 1905 } 1906 } 1907 } 1908 } 1909 return false; 1910 } 1911 }; 1912 1913 public void setSystemProcess() { 1914 try { 1915 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1916 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1917 ServiceManager.addService("meminfo", new MemBinder(this)); 1918 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1919 ServiceManager.addService("dbinfo", new DbBinder(this)); 1920 if (MONITOR_CPU_USAGE) { 1921 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1922 } 1923 ServiceManager.addService("permission", new PermissionController(this)); 1924 1925 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1926 "android", STOCK_PM_FLAGS); 1927 mSystemThread.installSystemApplicationInfo(info); 1928 1929 synchronized (this) { 1930 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1931 app.persistent = true; 1932 app.pid = MY_PID; 1933 app.maxAdj = ProcessList.SYSTEM_ADJ; 1934 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1935 mProcessNames.put(app.processName, app.uid, app); 1936 synchronized (mPidsSelfLocked) { 1937 mPidsSelfLocked.put(app.pid, app); 1938 } 1939 updateLruProcessLocked(app, false, null); 1940 updateOomAdjLocked(); 1941 } 1942 } catch (PackageManager.NameNotFoundException e) { 1943 throw new RuntimeException( 1944 "Unable to find android system package", e); 1945 } 1946 } 1947 1948 public void setWindowManager(WindowManagerService wm) { 1949 mWindowManager = wm; 1950 mStackSupervisor.setWindowManager(wm); 1951 } 1952 1953 public void startObservingNativeCrashes() { 1954 final NativeCrashListener ncl = new NativeCrashListener(this); 1955 ncl.start(); 1956 } 1957 1958 public IAppOpsService getAppOpsService() { 1959 return mAppOpsService; 1960 } 1961 1962 static class MemBinder extends Binder { 1963 ActivityManagerService mActivityManagerService; 1964 MemBinder(ActivityManagerService activityManagerService) { 1965 mActivityManagerService = activityManagerService; 1966 } 1967 1968 @Override 1969 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1970 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1971 != PackageManager.PERMISSION_GRANTED) { 1972 pw.println("Permission Denial: can't dump meminfo from from pid=" 1973 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1974 + " without permission " + android.Manifest.permission.DUMP); 1975 return; 1976 } 1977 1978 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1979 } 1980 } 1981 1982 static class GraphicsBinder extends Binder { 1983 ActivityManagerService mActivityManagerService; 1984 GraphicsBinder(ActivityManagerService activityManagerService) { 1985 mActivityManagerService = activityManagerService; 1986 } 1987 1988 @Override 1989 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1990 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1991 != PackageManager.PERMISSION_GRANTED) { 1992 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1993 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1994 + " without permission " + android.Manifest.permission.DUMP); 1995 return; 1996 } 1997 1998 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1999 } 2000 } 2001 2002 static class DbBinder extends Binder { 2003 ActivityManagerService mActivityManagerService; 2004 DbBinder(ActivityManagerService activityManagerService) { 2005 mActivityManagerService = activityManagerService; 2006 } 2007 2008 @Override 2009 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2010 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2011 != PackageManager.PERMISSION_GRANTED) { 2012 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2013 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2014 + " without permission " + android.Manifest.permission.DUMP); 2015 return; 2016 } 2017 2018 mActivityManagerService.dumpDbInfo(fd, pw, args); 2019 } 2020 } 2021 2022 static class CpuBinder extends Binder { 2023 ActivityManagerService mActivityManagerService; 2024 CpuBinder(ActivityManagerService activityManagerService) { 2025 mActivityManagerService = activityManagerService; 2026 } 2027 2028 @Override 2029 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2030 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2031 != PackageManager.PERMISSION_GRANTED) { 2032 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2033 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2034 + " without permission " + android.Manifest.permission.DUMP); 2035 return; 2036 } 2037 2038 synchronized (mActivityManagerService.mProcessCpuThread) { 2039 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2040 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2041 SystemClock.uptimeMillis())); 2042 } 2043 } 2044 } 2045 2046 public static final class Lifecycle extends SystemService { 2047 private final ActivityManagerService mService; 2048 2049 public Lifecycle(Context context) { 2050 super(context); 2051 mService = new ActivityManagerService(context); 2052 } 2053 2054 @Override 2055 public void onStart() { 2056 mService.start(); 2057 } 2058 2059 public ActivityManagerService getService() { 2060 return mService; 2061 } 2062 } 2063 2064 // Note: This method is invoked on the main thread but may need to attach various 2065 // handlers to other threads. So take care to be explicit about the looper. 2066 public ActivityManagerService(Context systemContext) { 2067 mContext = systemContext; 2068 mFactoryTest = FactoryTest.getMode(); 2069 mSystemThread = ActivityThread.currentActivityThread(); 2070 2071 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2072 2073 mHandlerThread = new ServiceThread(TAG, 2074 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2075 mHandlerThread.start(); 2076 mHandler = new MainHandler(mHandlerThread.getLooper()); 2077 2078 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2079 "foreground", BROADCAST_FG_TIMEOUT, false); 2080 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2081 "background", BROADCAST_BG_TIMEOUT, true); 2082 mBroadcastQueues[0] = mFgBroadcastQueue; 2083 mBroadcastQueues[1] = mBgBroadcastQueue; 2084 2085 mServices = new ActiveServices(this); 2086 mProviderMap = new ProviderMap(this); 2087 2088 // TODO: Move creation of battery stats service outside of activity manager service. 2089 File dataDir = Environment.getDataDirectory(); 2090 File systemDir = new File(dataDir, "system"); 2091 systemDir.mkdirs(); 2092 mBatteryStatsService = new BatteryStatsService(new File( 2093 systemDir, "batterystats.bin").toString(), mHandler); 2094 mBatteryStatsService.getActiveStatistics().readLocked(); 2095 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2096 mOnBattery = DEBUG_POWER ? true 2097 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2098 mBatteryStatsService.getActiveStatistics().setCallback(this); 2099 2100 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2101 2102 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2103 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2104 2105 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2106 2107 // User 0 is the first and only user that runs at boot. 2108 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2109 mUserLru.add(Integer.valueOf(0)); 2110 updateStartedUserArrayLocked(); 2111 2112 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2113 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2114 2115 mConfiguration.setToDefaults(); 2116 mConfiguration.setLocale(Locale.getDefault()); 2117 2118 mConfigurationSeq = mConfiguration.seq = 1; 2119 mProcessCpuTracker.init(); 2120 2121 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2122 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2123 mStackSupervisor = new ActivityStackSupervisor(this); 2124 2125 mProcessCpuThread = new Thread("CpuTracker") { 2126 @Override 2127 public void run() { 2128 while (true) { 2129 try { 2130 try { 2131 synchronized(this) { 2132 final long now = SystemClock.uptimeMillis(); 2133 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2134 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2135 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2136 // + ", write delay=" + nextWriteDelay); 2137 if (nextWriteDelay < nextCpuDelay) { 2138 nextCpuDelay = nextWriteDelay; 2139 } 2140 if (nextCpuDelay > 0) { 2141 mProcessCpuMutexFree.set(true); 2142 this.wait(nextCpuDelay); 2143 } 2144 } 2145 } catch (InterruptedException e) { 2146 } 2147 updateCpuStatsNow(); 2148 } catch (Exception e) { 2149 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2150 } 2151 } 2152 } 2153 }; 2154 2155 Watchdog.getInstance().addMonitor(this); 2156 Watchdog.getInstance().addThread(mHandler); 2157 } 2158 2159 public void setSystemServiceManager(SystemServiceManager mgr) { 2160 mSystemServiceManager = mgr; 2161 } 2162 2163 private void start() { 2164 mProcessCpuThread.start(); 2165 2166 mBatteryStatsService.publish(mContext); 2167 mUsageStatsService.publish(mContext); 2168 mAppOpsService.publish(mContext); 2169 2170 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2171 } 2172 2173 @Override 2174 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2175 throws RemoteException { 2176 if (code == SYSPROPS_TRANSACTION) { 2177 // We need to tell all apps about the system property change. 2178 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2179 synchronized(this) { 2180 final int NP = mProcessNames.getMap().size(); 2181 for (int ip=0; ip<NP; ip++) { 2182 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2183 final int NA = apps.size(); 2184 for (int ia=0; ia<NA; ia++) { 2185 ProcessRecord app = apps.valueAt(ia); 2186 if (app.thread != null) { 2187 procs.add(app.thread.asBinder()); 2188 } 2189 } 2190 } 2191 } 2192 2193 int N = procs.size(); 2194 for (int i=0; i<N; i++) { 2195 Parcel data2 = Parcel.obtain(); 2196 try { 2197 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2198 } catch (RemoteException e) { 2199 } 2200 data2.recycle(); 2201 } 2202 } 2203 try { 2204 return super.onTransact(code, data, reply, flags); 2205 } catch (RuntimeException e) { 2206 // The activity manager only throws security exceptions, so let's 2207 // log all others. 2208 if (!(e instanceof SecurityException)) { 2209 Slog.wtf(TAG, "Activity Manager Crash", e); 2210 } 2211 throw e; 2212 } 2213 } 2214 2215 void updateCpuStats() { 2216 final long now = SystemClock.uptimeMillis(); 2217 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2218 return; 2219 } 2220 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2221 synchronized (mProcessCpuThread) { 2222 mProcessCpuThread.notify(); 2223 } 2224 } 2225 } 2226 2227 void updateCpuStatsNow() { 2228 synchronized (mProcessCpuThread) { 2229 mProcessCpuMutexFree.set(false); 2230 final long now = SystemClock.uptimeMillis(); 2231 boolean haveNewCpuStats = false; 2232 2233 if (MONITOR_CPU_USAGE && 2234 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2235 mLastCpuTime.set(now); 2236 haveNewCpuStats = true; 2237 mProcessCpuTracker.update(); 2238 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2239 //Slog.i(TAG, "Total CPU usage: " 2240 // + mProcessCpu.getTotalCpuPercent() + "%"); 2241 2242 // Slog the cpu usage if the property is set. 2243 if ("true".equals(SystemProperties.get("events.cpu"))) { 2244 int user = mProcessCpuTracker.getLastUserTime(); 2245 int system = mProcessCpuTracker.getLastSystemTime(); 2246 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2247 int irq = mProcessCpuTracker.getLastIrqTime(); 2248 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2249 int idle = mProcessCpuTracker.getLastIdleTime(); 2250 2251 int total = user + system + iowait + irq + softIrq + idle; 2252 if (total == 0) total = 1; 2253 2254 EventLog.writeEvent(EventLogTags.CPU, 2255 ((user+system+iowait+irq+softIrq) * 100) / total, 2256 (user * 100) / total, 2257 (system * 100) / total, 2258 (iowait * 100) / total, 2259 (irq * 100) / total, 2260 (softIrq * 100) / total); 2261 } 2262 } 2263 2264 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2265 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2266 synchronized(bstats) { 2267 synchronized(mPidsSelfLocked) { 2268 if (haveNewCpuStats) { 2269 if (mOnBattery) { 2270 int perc = bstats.startAddingCpuLocked(); 2271 int totalUTime = 0; 2272 int totalSTime = 0; 2273 final int N = mProcessCpuTracker.countStats(); 2274 for (int i=0; i<N; i++) { 2275 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2276 if (!st.working) { 2277 continue; 2278 } 2279 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2280 int otherUTime = (st.rel_utime*perc)/100; 2281 int otherSTime = (st.rel_stime*perc)/100; 2282 totalUTime += otherUTime; 2283 totalSTime += otherSTime; 2284 if (pr != null) { 2285 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2286 if (ps == null || !ps.isActive()) { 2287 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2288 pr.info.uid, pr.processName); 2289 } 2290 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2291 st.rel_stime-otherSTime); 2292 ps.addSpeedStepTimes(cpuSpeedTimes); 2293 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2294 } else { 2295 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2296 if (ps == null || !ps.isActive()) { 2297 st.batteryStats = ps = bstats.getProcessStatsLocked( 2298 bstats.mapUid(st.uid), st.name); 2299 } 2300 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2301 st.rel_stime-otherSTime); 2302 ps.addSpeedStepTimes(cpuSpeedTimes); 2303 } 2304 } 2305 bstats.finishAddingCpuLocked(perc, totalUTime, 2306 totalSTime, cpuSpeedTimes); 2307 } 2308 } 2309 } 2310 2311 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2312 mLastWriteTime = now; 2313 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2314 } 2315 } 2316 } 2317 } 2318 2319 @Override 2320 public void batteryNeedsCpuUpdate() { 2321 updateCpuStatsNow(); 2322 } 2323 2324 @Override 2325 public void batteryPowerChanged(boolean onBattery) { 2326 // When plugging in, update the CPU stats first before changing 2327 // the plug state. 2328 updateCpuStatsNow(); 2329 synchronized (this) { 2330 synchronized(mPidsSelfLocked) { 2331 mOnBattery = DEBUG_POWER ? true : onBattery; 2332 } 2333 } 2334 } 2335 2336 /** 2337 * Initialize the application bind args. These are passed to each 2338 * process when the bindApplication() IPC is sent to the process. They're 2339 * lazily setup to make sure the services are running when they're asked for. 2340 */ 2341 private HashMap<String, IBinder> getCommonServicesLocked() { 2342 if (mAppBindArgs == null) { 2343 mAppBindArgs = new HashMap<String, IBinder>(); 2344 2345 // Setup the application init args 2346 mAppBindArgs.put("package", ServiceManager.getService("package")); 2347 mAppBindArgs.put("window", ServiceManager.getService("window")); 2348 mAppBindArgs.put(Context.ALARM_SERVICE, 2349 ServiceManager.getService(Context.ALARM_SERVICE)); 2350 } 2351 return mAppBindArgs; 2352 } 2353 2354 final void setFocusedActivityLocked(ActivityRecord r) { 2355 if (mFocusedActivity != r) { 2356 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2357 mFocusedActivity = r; 2358 if (r.task != null && r.task.voiceInteractor != null) { 2359 startRunningVoiceLocked(); 2360 } else { 2361 finishRunningVoiceLocked(); 2362 } 2363 mStackSupervisor.setFocusedStack(r); 2364 if (r != null) { 2365 mWindowManager.setFocusedApp(r.appToken, true); 2366 } 2367 applyUpdateLockStateLocked(r); 2368 } 2369 } 2370 2371 final void clearFocusedActivity(ActivityRecord r) { 2372 if (mFocusedActivity == r) { 2373 mFocusedActivity = null; 2374 } 2375 } 2376 2377 @Override 2378 public void setFocusedStack(int stackId) { 2379 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2380 synchronized (ActivityManagerService.this) { 2381 ActivityStack stack = mStackSupervisor.getStack(stackId); 2382 if (stack != null) { 2383 ActivityRecord r = stack.topRunningActivityLocked(null); 2384 if (r != null) { 2385 setFocusedActivityLocked(r); 2386 } 2387 } 2388 } 2389 } 2390 2391 @Override 2392 public void notifyActivityDrawn(IBinder token) { 2393 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2394 synchronized (this) { 2395 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2396 if (r != null) { 2397 r.task.stack.notifyActivityDrawnLocked(r); 2398 } 2399 } 2400 } 2401 2402 final void applyUpdateLockStateLocked(ActivityRecord r) { 2403 // Modifications to the UpdateLock state are done on our handler, outside 2404 // the activity manager's locks. The new state is determined based on the 2405 // state *now* of the relevant activity record. The object is passed to 2406 // the handler solely for logging detail, not to be consulted/modified. 2407 final boolean nextState = r != null && r.immersive; 2408 mHandler.sendMessage( 2409 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2410 } 2411 2412 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2413 Message msg = Message.obtain(); 2414 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2415 msg.obj = r.task.askedCompatMode ? null : r; 2416 mHandler.sendMessage(msg); 2417 } 2418 2419 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2420 String what, Object obj, ProcessRecord srcApp) { 2421 app.lastActivityTime = now; 2422 2423 if (app.activities.size() > 0) { 2424 // Don't want to touch dependent processes that are hosting activities. 2425 return index; 2426 } 2427 2428 int lrui = mLruProcesses.lastIndexOf(app); 2429 if (lrui < 0) { 2430 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2431 + what + " " + obj + " from " + srcApp); 2432 return index; 2433 } 2434 2435 if (lrui >= index) { 2436 // Don't want to cause this to move dependent processes *back* in the 2437 // list as if they were less frequently used. 2438 return index; 2439 } 2440 2441 if (lrui >= mLruProcessActivityStart) { 2442 // Don't want to touch dependent processes that are hosting activities. 2443 return index; 2444 } 2445 2446 mLruProcesses.remove(lrui); 2447 if (index > 0) { 2448 index--; 2449 } 2450 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2451 + " in LRU list: " + app); 2452 mLruProcesses.add(index, app); 2453 return index; 2454 } 2455 2456 final void removeLruProcessLocked(ProcessRecord app) { 2457 int lrui = mLruProcesses.lastIndexOf(app); 2458 if (lrui >= 0) { 2459 if (lrui <= mLruProcessActivityStart) { 2460 mLruProcessActivityStart--; 2461 } 2462 if (lrui <= mLruProcessServiceStart) { 2463 mLruProcessServiceStart--; 2464 } 2465 mLruProcesses.remove(lrui); 2466 } 2467 } 2468 2469 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2470 ProcessRecord client) { 2471 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2472 || app.treatLikeActivity; 2473 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2474 if (!activityChange && hasActivity) { 2475 // The process has activities, so we are only allowing activity-based adjustments 2476 // to move it. It should be kept in the front of the list with other 2477 // processes that have activities, and we don't want those to change their 2478 // order except due to activity operations. 2479 return; 2480 } 2481 2482 mLruSeq++; 2483 final long now = SystemClock.uptimeMillis(); 2484 app.lastActivityTime = now; 2485 2486 // First a quick reject: if the app is already at the position we will 2487 // put it, then there is nothing to do. 2488 if (hasActivity) { 2489 final int N = mLruProcesses.size(); 2490 if (N > 0 && mLruProcesses.get(N-1) == app) { 2491 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2492 return; 2493 } 2494 } else { 2495 if (mLruProcessServiceStart > 0 2496 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2497 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2498 return; 2499 } 2500 } 2501 2502 int lrui = mLruProcesses.lastIndexOf(app); 2503 2504 if (app.persistent && lrui >= 0) { 2505 // We don't care about the position of persistent processes, as long as 2506 // they are in the list. 2507 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2508 return; 2509 } 2510 2511 /* In progress: compute new position first, so we can avoid doing work 2512 if the process is not actually going to move. Not yet working. 2513 int addIndex; 2514 int nextIndex; 2515 boolean inActivity = false, inService = false; 2516 if (hasActivity) { 2517 // Process has activities, put it at the very tipsy-top. 2518 addIndex = mLruProcesses.size(); 2519 nextIndex = mLruProcessServiceStart; 2520 inActivity = true; 2521 } else if (hasService) { 2522 // Process has services, put it at the top of the service list. 2523 addIndex = mLruProcessActivityStart; 2524 nextIndex = mLruProcessServiceStart; 2525 inActivity = true; 2526 inService = true; 2527 } else { 2528 // Process not otherwise of interest, it goes to the top of the non-service area. 2529 addIndex = mLruProcessServiceStart; 2530 if (client != null) { 2531 int clientIndex = mLruProcesses.lastIndexOf(client); 2532 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2533 + app); 2534 if (clientIndex >= 0 && addIndex > clientIndex) { 2535 addIndex = clientIndex; 2536 } 2537 } 2538 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2539 } 2540 2541 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2542 + mLruProcessActivityStart + "): " + app); 2543 */ 2544 2545 if (lrui >= 0) { 2546 if (lrui < mLruProcessActivityStart) { 2547 mLruProcessActivityStart--; 2548 } 2549 if (lrui < mLruProcessServiceStart) { 2550 mLruProcessServiceStart--; 2551 } 2552 /* 2553 if (addIndex > lrui) { 2554 addIndex--; 2555 } 2556 if (nextIndex > lrui) { 2557 nextIndex--; 2558 } 2559 */ 2560 mLruProcesses.remove(lrui); 2561 } 2562 2563 /* 2564 mLruProcesses.add(addIndex, app); 2565 if (inActivity) { 2566 mLruProcessActivityStart++; 2567 } 2568 if (inService) { 2569 mLruProcessActivityStart++; 2570 } 2571 */ 2572 2573 int nextIndex; 2574 if (hasActivity) { 2575 final int N = mLruProcesses.size(); 2576 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2577 // Process doesn't have activities, but has clients with 2578 // activities... move it up, but one below the top (the top 2579 // should always have a real activity). 2580 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2581 mLruProcesses.add(N-1, app); 2582 // To keep it from spamming the LRU list (by making a bunch of clients), 2583 // we will push down any other entries owned by the app. 2584 final int uid = app.info.uid; 2585 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2586 ProcessRecord subProc = mLruProcesses.get(i); 2587 if (subProc.info.uid == uid) { 2588 // We want to push this one down the list. If the process after 2589 // it is for the same uid, however, don't do so, because we don't 2590 // want them internally to be re-ordered. 2591 if (mLruProcesses.get(i-1).info.uid != uid) { 2592 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2593 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2594 ProcessRecord tmp = mLruProcesses.get(i); 2595 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2596 mLruProcesses.set(i-1, tmp); 2597 i--; 2598 } 2599 } else { 2600 // A gap, we can stop here. 2601 break; 2602 } 2603 } 2604 } else { 2605 // Process has activities, put it at the very tipsy-top. 2606 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2607 mLruProcesses.add(app); 2608 } 2609 nextIndex = mLruProcessServiceStart; 2610 } else if (hasService) { 2611 // Process has services, put it at the top of the service list. 2612 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2613 mLruProcesses.add(mLruProcessActivityStart, app); 2614 nextIndex = mLruProcessServiceStart; 2615 mLruProcessActivityStart++; 2616 } else { 2617 // Process not otherwise of interest, it goes to the top of the non-service area. 2618 int index = mLruProcessServiceStart; 2619 if (client != null) { 2620 // If there is a client, don't allow the process to be moved up higher 2621 // in the list than that client. 2622 int clientIndex = mLruProcesses.lastIndexOf(client); 2623 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2624 + " when updating " + app); 2625 if (clientIndex <= lrui) { 2626 // Don't allow the client index restriction to push it down farther in the 2627 // list than it already is. 2628 clientIndex = lrui; 2629 } 2630 if (clientIndex >= 0 && index > clientIndex) { 2631 index = clientIndex; 2632 } 2633 } 2634 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2635 mLruProcesses.add(index, app); 2636 nextIndex = index-1; 2637 mLruProcessActivityStart++; 2638 mLruProcessServiceStart++; 2639 } 2640 2641 // If the app is currently using a content provider or service, 2642 // bump those processes as well. 2643 for (int j=app.connections.size()-1; j>=0; j--) { 2644 ConnectionRecord cr = app.connections.valueAt(j); 2645 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2646 && cr.binding.service.app != null 2647 && cr.binding.service.app.lruSeq != mLruSeq 2648 && !cr.binding.service.app.persistent) { 2649 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2650 "service connection", cr, app); 2651 } 2652 } 2653 for (int j=app.conProviders.size()-1; j>=0; j--) { 2654 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2655 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2656 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2657 "provider reference", cpr, app); 2658 } 2659 } 2660 } 2661 2662 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2663 if (uid == Process.SYSTEM_UID) { 2664 // The system gets to run in any process. If there are multiple 2665 // processes with the same uid, just pick the first (this 2666 // should never happen). 2667 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2668 if (procs == null) return null; 2669 final int N = procs.size(); 2670 for (int i = 0; i < N; i++) { 2671 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2672 } 2673 } 2674 ProcessRecord proc = mProcessNames.get(processName, uid); 2675 if (false && proc != null && !keepIfLarge 2676 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2677 && proc.lastCachedPss >= 4000) { 2678 // Turn this condition on to cause killing to happen regularly, for testing. 2679 if (proc.baseProcessTracker != null) { 2680 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2681 } 2682 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2683 + "k from cached"); 2684 } else if (proc != null && !keepIfLarge 2685 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2686 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2687 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2688 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2689 if (proc.baseProcessTracker != null) { 2690 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2691 } 2692 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2693 + "k from cached"); 2694 } 2695 } 2696 return proc; 2697 } 2698 2699 void ensurePackageDexOpt(String packageName) { 2700 IPackageManager pm = AppGlobals.getPackageManager(); 2701 try { 2702 if (pm.performDexOpt(packageName)) { 2703 mDidDexOpt = true; 2704 } 2705 } catch (RemoteException e) { 2706 } 2707 } 2708 2709 boolean isNextTransitionForward() { 2710 int transit = mWindowManager.getPendingAppTransition(); 2711 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2712 || transit == AppTransition.TRANSIT_TASK_OPEN 2713 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2714 } 2715 2716 final ProcessRecord startProcessLocked(String processName, 2717 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2718 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2719 boolean isolated, boolean keepIfLarge) { 2720 ProcessRecord app; 2721 if (!isolated) { 2722 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2723 } else { 2724 // If this is an isolated process, it can't re-use an existing process. 2725 app = null; 2726 } 2727 // We don't have to do anything more if: 2728 // (1) There is an existing application record; and 2729 // (2) The caller doesn't think it is dead, OR there is no thread 2730 // object attached to it so we know it couldn't have crashed; and 2731 // (3) There is a pid assigned to it, so it is either starting or 2732 // already running. 2733 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2734 + " app=" + app + " knownToBeDead=" + knownToBeDead 2735 + " thread=" + (app != null ? app.thread : null) 2736 + " pid=" + (app != null ? app.pid : -1)); 2737 if (app != null && app.pid > 0) { 2738 if (!knownToBeDead || app.thread == null) { 2739 // We already have the app running, or are waiting for it to 2740 // come up (we have a pid but not yet its thread), so keep it. 2741 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2742 // If this is a new package in the process, add the package to the list 2743 app.addPackage(info.packageName, mProcessStats); 2744 return app; 2745 } 2746 2747 // An application record is attached to a previous process, 2748 // clean it up now. 2749 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2750 handleAppDiedLocked(app, true, true); 2751 } 2752 2753 String hostingNameStr = hostingName != null 2754 ? hostingName.flattenToShortString() : null; 2755 2756 if (!isolated) { 2757 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2758 // If we are in the background, then check to see if this process 2759 // is bad. If so, we will just silently fail. 2760 if (mBadProcesses.get(info.processName, info.uid) != null) { 2761 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2762 + "/" + info.processName); 2763 return null; 2764 } 2765 } else { 2766 // When the user is explicitly starting a process, then clear its 2767 // crash count so that we won't make it bad until they see at 2768 // least one crash dialog again, and make the process good again 2769 // if it had been bad. 2770 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2771 + "/" + info.processName); 2772 mProcessCrashTimes.remove(info.processName, info.uid); 2773 if (mBadProcesses.get(info.processName, info.uid) != null) { 2774 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2775 UserHandle.getUserId(info.uid), info.uid, 2776 info.processName); 2777 mBadProcesses.remove(info.processName, info.uid); 2778 if (app != null) { 2779 app.bad = false; 2780 } 2781 } 2782 } 2783 } 2784 2785 if (app == null) { 2786 app = newProcessRecordLocked(info, processName, isolated); 2787 if (app == null) { 2788 Slog.w(TAG, "Failed making new process record for " 2789 + processName + "/" + info.uid + " isolated=" + isolated); 2790 return null; 2791 } 2792 mProcessNames.put(processName, app.uid, app); 2793 if (isolated) { 2794 mIsolatedProcesses.put(app.uid, app); 2795 } 2796 } else { 2797 // If this is a new package in the process, add the package to the list 2798 app.addPackage(info.packageName, mProcessStats); 2799 } 2800 2801 // If the system is not ready yet, then hold off on starting this 2802 // process until it is. 2803 if (!mProcessesReady 2804 && !isAllowedWhileBooting(info) 2805 && !allowWhileBooting) { 2806 if (!mProcessesOnHold.contains(app)) { 2807 mProcessesOnHold.add(app); 2808 } 2809 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2810 return app; 2811 } 2812 2813 startProcessLocked(app, hostingType, hostingNameStr); 2814 return (app.pid != 0) ? app : null; 2815 } 2816 2817 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2818 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2819 } 2820 2821 private final void startProcessLocked(ProcessRecord app, 2822 String hostingType, String hostingNameStr) { 2823 if (app.pid > 0 && app.pid != MY_PID) { 2824 synchronized (mPidsSelfLocked) { 2825 mPidsSelfLocked.remove(app.pid); 2826 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2827 } 2828 app.setPid(0); 2829 } 2830 2831 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2832 "startProcessLocked removing on hold: " + app); 2833 mProcessesOnHold.remove(app); 2834 2835 updateCpuStats(); 2836 2837 try { 2838 int uid = app.uid; 2839 2840 int[] gids = null; 2841 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2842 if (!app.isolated) { 2843 int[] permGids = null; 2844 try { 2845 final PackageManager pm = mContext.getPackageManager(); 2846 permGids = pm.getPackageGids(app.info.packageName); 2847 2848 if (Environment.isExternalStorageEmulated()) { 2849 if (pm.checkPermission( 2850 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2851 app.info.packageName) == PERMISSION_GRANTED) { 2852 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2853 } else { 2854 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2855 } 2856 } 2857 } catch (PackageManager.NameNotFoundException e) { 2858 Slog.w(TAG, "Unable to retrieve gids", e); 2859 } 2860 2861 /* 2862 * Add shared application GID so applications can share some 2863 * resources like shared libraries 2864 */ 2865 if (permGids == null) { 2866 gids = new int[1]; 2867 } else { 2868 gids = new int[permGids.length + 1]; 2869 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2870 } 2871 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2872 } 2873 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2874 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2875 && mTopComponent != null 2876 && app.processName.equals(mTopComponent.getPackageName())) { 2877 uid = 0; 2878 } 2879 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2880 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2881 uid = 0; 2882 } 2883 } 2884 int debugFlags = 0; 2885 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2886 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2887 // Also turn on CheckJNI for debuggable apps. It's quite 2888 // awkward to turn on otherwise. 2889 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2890 } 2891 // Run the app in safe mode if its manifest requests so or the 2892 // system is booted in safe mode. 2893 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2894 mSafeMode == true) { 2895 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2896 } 2897 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2898 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2899 } 2900 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2901 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2902 } 2903 if ("1".equals(SystemProperties.get("debug.assert"))) { 2904 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2905 } 2906 2907 String requiredAbi = app.info.requiredCpuAbi; 2908 if (requiredAbi == null) { 2909 requiredAbi = Build.SUPPORTED_ABIS[0]; 2910 } 2911 2912 // Start the process. It will either succeed and return a result containing 2913 // the PID of the new process, or else throw a RuntimeException. 2914 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2915 app.processName, uid, uid, gids, debugFlags, mountExternal, 2916 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2917 2918 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2919 synchronized (bs) { 2920 if (bs.isOnBattery()) { 2921 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2922 } 2923 } 2924 2925 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2926 UserHandle.getUserId(uid), startResult.pid, uid, 2927 app.processName, hostingType, 2928 hostingNameStr != null ? hostingNameStr : ""); 2929 2930 if (app.persistent) { 2931 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2932 } 2933 2934 StringBuilder buf = mStringBuilder; 2935 buf.setLength(0); 2936 buf.append("Start proc "); 2937 buf.append(app.processName); 2938 buf.append(" for "); 2939 buf.append(hostingType); 2940 if (hostingNameStr != null) { 2941 buf.append(" "); 2942 buf.append(hostingNameStr); 2943 } 2944 buf.append(": pid="); 2945 buf.append(startResult.pid); 2946 buf.append(" uid="); 2947 buf.append(uid); 2948 buf.append(" gids={"); 2949 if (gids != null) { 2950 for (int gi=0; gi<gids.length; gi++) { 2951 if (gi != 0) buf.append(", "); 2952 buf.append(gids[gi]); 2953 2954 } 2955 } 2956 buf.append("}"); 2957 Slog.i(TAG, buf.toString()); 2958 app.setPid(startResult.pid); 2959 app.usingWrapper = startResult.usingWrapper; 2960 app.removed = false; 2961 synchronized (mPidsSelfLocked) { 2962 this.mPidsSelfLocked.put(startResult.pid, app); 2963 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2964 msg.obj = app; 2965 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2966 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2967 } 2968 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2969 app.processName, app.info.uid); 2970 if (app.isolated) { 2971 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2972 } 2973 } catch (RuntimeException e) { 2974 // XXX do better error recovery. 2975 app.setPid(0); 2976 Slog.e(TAG, "Failure starting process " + app.processName, e); 2977 } 2978 } 2979 2980 void updateUsageStats(ActivityRecord component, boolean resumed) { 2981 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2982 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2983 if (resumed) { 2984 mUsageStatsService.noteResumeComponent(component.realActivity); 2985 synchronized (stats) { 2986 stats.noteActivityResumedLocked(component.app.uid); 2987 } 2988 } else { 2989 mUsageStatsService.notePauseComponent(component.realActivity); 2990 synchronized (stats) { 2991 stats.noteActivityPausedLocked(component.app.uid); 2992 } 2993 } 2994 } 2995 2996 Intent getHomeIntent() { 2997 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2998 intent.setComponent(mTopComponent); 2999 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3000 intent.addCategory(Intent.CATEGORY_HOME); 3001 } 3002 return intent; 3003 } 3004 3005 boolean startHomeActivityLocked(int userId) { 3006 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3007 && mTopAction == null) { 3008 // We are running in factory test mode, but unable to find 3009 // the factory test app, so just sit around displaying the 3010 // error message and don't try to start anything. 3011 return false; 3012 } 3013 Intent intent = getHomeIntent(); 3014 ActivityInfo aInfo = 3015 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3016 if (aInfo != null) { 3017 intent.setComponent(new ComponentName( 3018 aInfo.applicationInfo.packageName, aInfo.name)); 3019 // Don't do this if the home app is currently being 3020 // instrumented. 3021 aInfo = new ActivityInfo(aInfo); 3022 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3023 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3024 aInfo.applicationInfo.uid, true); 3025 if (app == null || app.instrumentationClass == null) { 3026 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3027 mStackSupervisor.startHomeActivity(intent, aInfo); 3028 } 3029 } 3030 3031 return true; 3032 } 3033 3034 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3035 ActivityInfo ai = null; 3036 ComponentName comp = intent.getComponent(); 3037 try { 3038 if (comp != null) { 3039 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3040 } else { 3041 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3042 intent, 3043 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3044 flags, userId); 3045 3046 if (info != null) { 3047 ai = info.activityInfo; 3048 } 3049 } 3050 } catch (RemoteException e) { 3051 // ignore 3052 } 3053 3054 return ai; 3055 } 3056 3057 /** 3058 * Starts the "new version setup screen" if appropriate. 3059 */ 3060 void startSetupActivityLocked() { 3061 // Only do this once per boot. 3062 if (mCheckedForSetup) { 3063 return; 3064 } 3065 3066 // We will show this screen if the current one is a different 3067 // version than the last one shown, and we are not running in 3068 // low-level factory test mode. 3069 final ContentResolver resolver = mContext.getContentResolver(); 3070 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3071 Settings.Global.getInt(resolver, 3072 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3073 mCheckedForSetup = true; 3074 3075 // See if we should be showing the platform update setup UI. 3076 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3077 List<ResolveInfo> ris = mContext.getPackageManager() 3078 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3079 3080 // We don't allow third party apps to replace this. 3081 ResolveInfo ri = null; 3082 for (int i=0; ris != null && i<ris.size(); i++) { 3083 if ((ris.get(i).activityInfo.applicationInfo.flags 3084 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3085 ri = ris.get(i); 3086 break; 3087 } 3088 } 3089 3090 if (ri != null) { 3091 String vers = ri.activityInfo.metaData != null 3092 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3093 : null; 3094 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3095 vers = ri.activityInfo.applicationInfo.metaData.getString( 3096 Intent.METADATA_SETUP_VERSION); 3097 } 3098 String lastVers = Settings.Secure.getString( 3099 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3100 if (vers != null && !vers.equals(lastVers)) { 3101 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3102 intent.setComponent(new ComponentName( 3103 ri.activityInfo.packageName, ri.activityInfo.name)); 3104 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3105 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3106 } 3107 } 3108 } 3109 } 3110 3111 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3112 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3113 } 3114 3115 void enforceNotIsolatedCaller(String caller) { 3116 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3117 throw new SecurityException("Isolated process not allowed to call " + caller); 3118 } 3119 } 3120 3121 @Override 3122 public int getFrontActivityScreenCompatMode() { 3123 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3124 synchronized (this) { 3125 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3126 } 3127 } 3128 3129 @Override 3130 public void setFrontActivityScreenCompatMode(int mode) { 3131 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3132 "setFrontActivityScreenCompatMode"); 3133 synchronized (this) { 3134 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3135 } 3136 } 3137 3138 @Override 3139 public int getPackageScreenCompatMode(String packageName) { 3140 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3141 synchronized (this) { 3142 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3143 } 3144 } 3145 3146 @Override 3147 public void setPackageScreenCompatMode(String packageName, int mode) { 3148 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3149 "setPackageScreenCompatMode"); 3150 synchronized (this) { 3151 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3152 } 3153 } 3154 3155 @Override 3156 public boolean getPackageAskScreenCompat(String packageName) { 3157 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3158 synchronized (this) { 3159 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3160 } 3161 } 3162 3163 @Override 3164 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3165 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3166 "setPackageAskScreenCompat"); 3167 synchronized (this) { 3168 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3169 } 3170 } 3171 3172 private void dispatchProcessesChanged() { 3173 int N; 3174 synchronized (this) { 3175 N = mPendingProcessChanges.size(); 3176 if (mActiveProcessChanges.length < N) { 3177 mActiveProcessChanges = new ProcessChangeItem[N]; 3178 } 3179 mPendingProcessChanges.toArray(mActiveProcessChanges); 3180 mAvailProcessChanges.addAll(mPendingProcessChanges); 3181 mPendingProcessChanges.clear(); 3182 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3183 } 3184 3185 int i = mProcessObservers.beginBroadcast(); 3186 while (i > 0) { 3187 i--; 3188 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3189 if (observer != null) { 3190 try { 3191 for (int j=0; j<N; j++) { 3192 ProcessChangeItem item = mActiveProcessChanges[j]; 3193 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3194 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3195 + item.pid + " uid=" + item.uid + ": " 3196 + item.foregroundActivities); 3197 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3198 item.foregroundActivities); 3199 } 3200 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3201 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3202 + item.pid + " uid=" + item.uid + ": " + item.processState); 3203 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3204 } 3205 } 3206 } catch (RemoteException e) { 3207 } 3208 } 3209 } 3210 mProcessObservers.finishBroadcast(); 3211 } 3212 3213 private void dispatchProcessDied(int pid, int uid) { 3214 int i = mProcessObservers.beginBroadcast(); 3215 while (i > 0) { 3216 i--; 3217 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3218 if (observer != null) { 3219 try { 3220 observer.onProcessDied(pid, uid); 3221 } catch (RemoteException e) { 3222 } 3223 } 3224 } 3225 mProcessObservers.finishBroadcast(); 3226 } 3227 3228 final void doPendingActivityLaunchesLocked(boolean doResume) { 3229 final int N = mPendingActivityLaunches.size(); 3230 if (N <= 0) { 3231 return; 3232 } 3233 for (int i=0; i<N; i++) { 3234 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3235 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3236 doResume && i == (N-1), null); 3237 } 3238 mPendingActivityLaunches.clear(); 3239 } 3240 3241 @Override 3242 public final int startActivity(IApplicationThread caller, String callingPackage, 3243 Intent intent, String resolvedType, IBinder resultTo, 3244 String resultWho, int requestCode, int startFlags, 3245 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3246 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3247 resultWho, requestCode, 3248 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3249 } 3250 3251 @Override 3252 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3253 Intent intent, String resolvedType, IBinder resultTo, 3254 String resultWho, int requestCode, int startFlags, 3255 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3256 enforceNotIsolatedCaller("startActivity"); 3257 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3258 false, true, "startActivity", null); 3259 // TODO: Switch to user app stacks here. 3260 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3261 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3262 null, null, options, userId, null); 3263 } 3264 3265 @Override 3266 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3267 Intent intent, String resolvedType, IBinder resultTo, 3268 String resultWho, int requestCode, int startFlags, String profileFile, 3269 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3270 enforceNotIsolatedCaller("startActivityAndWait"); 3271 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3272 false, true, "startActivityAndWait", null); 3273 WaitResult res = new WaitResult(); 3274 // TODO: Switch to user app stacks here. 3275 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3276 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3277 res, null, options, UserHandle.getCallingUserId(), null); 3278 return res; 3279 } 3280 3281 @Override 3282 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3283 Intent intent, String resolvedType, IBinder resultTo, 3284 String resultWho, int requestCode, int startFlags, Configuration config, 3285 Bundle options, int userId) { 3286 enforceNotIsolatedCaller("startActivityWithConfig"); 3287 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3288 false, true, "startActivityWithConfig", null); 3289 // TODO: Switch to user app stacks here. 3290 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3291 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3292 null, null, null, config, options, userId, null); 3293 return ret; 3294 } 3295 3296 @Override 3297 public int startActivityIntentSender(IApplicationThread caller, 3298 IntentSender intent, Intent fillInIntent, String resolvedType, 3299 IBinder resultTo, String resultWho, int requestCode, 3300 int flagsMask, int flagsValues, Bundle options) { 3301 enforceNotIsolatedCaller("startActivityIntentSender"); 3302 // Refuse possible leaked file descriptors 3303 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3304 throw new IllegalArgumentException("File descriptors passed in Intent"); 3305 } 3306 3307 IIntentSender sender = intent.getTarget(); 3308 if (!(sender instanceof PendingIntentRecord)) { 3309 throw new IllegalArgumentException("Bad PendingIntent object"); 3310 } 3311 3312 PendingIntentRecord pir = (PendingIntentRecord)sender; 3313 3314 synchronized (this) { 3315 // If this is coming from the currently resumed activity, it is 3316 // effectively saying that app switches are allowed at this point. 3317 final ActivityStack stack = getFocusedStack(); 3318 if (stack.mResumedActivity != null && 3319 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3320 mAppSwitchesAllowedTime = 0; 3321 } 3322 } 3323 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3324 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3325 return ret; 3326 } 3327 3328 @Override 3329 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3330 Intent intent, String resolvedType, IVoiceInteractionSession session, 3331 IVoiceInteractor interactor, int startFlags, String profileFile, 3332 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3333 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3334 != PackageManager.PERMISSION_GRANTED) { 3335 String msg = "Permission Denial: startVoiceActivity() from pid=" 3336 + Binder.getCallingPid() 3337 + ", uid=" + Binder.getCallingUid() 3338 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3339 Slog.w(TAG, msg); 3340 throw new SecurityException(msg); 3341 } 3342 if (session == null || interactor == null) { 3343 throw new NullPointerException("null session or interactor"); 3344 } 3345 userId = handleIncomingUser(callingPid, callingUid, userId, 3346 false, true, "startVoiceActivity", null); 3347 // TODO: Switch to user app stacks here. 3348 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3349 resolvedType, session, interactor, null, null, 0, startFlags, 3350 profileFile, profileFd, null, null, options, userId, null); 3351 } 3352 3353 @Override 3354 public boolean startNextMatchingActivity(IBinder callingActivity, 3355 Intent intent, Bundle options) { 3356 // Refuse possible leaked file descriptors 3357 if (intent != null && intent.hasFileDescriptors() == true) { 3358 throw new IllegalArgumentException("File descriptors passed in Intent"); 3359 } 3360 3361 synchronized (this) { 3362 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3363 if (r == null) { 3364 ActivityOptions.abort(options); 3365 return false; 3366 } 3367 if (r.app == null || r.app.thread == null) { 3368 // The caller is not running... d'oh! 3369 ActivityOptions.abort(options); 3370 return false; 3371 } 3372 intent = new Intent(intent); 3373 // The caller is not allowed to change the data. 3374 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3375 // And we are resetting to find the next component... 3376 intent.setComponent(null); 3377 3378 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3379 3380 ActivityInfo aInfo = null; 3381 try { 3382 List<ResolveInfo> resolves = 3383 AppGlobals.getPackageManager().queryIntentActivities( 3384 intent, r.resolvedType, 3385 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3386 UserHandle.getCallingUserId()); 3387 3388 // Look for the original activity in the list... 3389 final int N = resolves != null ? resolves.size() : 0; 3390 for (int i=0; i<N; i++) { 3391 ResolveInfo rInfo = resolves.get(i); 3392 if (rInfo.activityInfo.packageName.equals(r.packageName) 3393 && rInfo.activityInfo.name.equals(r.info.name)) { 3394 // We found the current one... the next matching is 3395 // after it. 3396 i++; 3397 if (i<N) { 3398 aInfo = resolves.get(i).activityInfo; 3399 } 3400 if (debug) { 3401 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3402 + "/" + r.info.name); 3403 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3404 + "/" + aInfo.name); 3405 } 3406 break; 3407 } 3408 } 3409 } catch (RemoteException e) { 3410 } 3411 3412 if (aInfo == null) { 3413 // Nobody who is next! 3414 ActivityOptions.abort(options); 3415 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3416 return false; 3417 } 3418 3419 intent.setComponent(new ComponentName( 3420 aInfo.applicationInfo.packageName, aInfo.name)); 3421 intent.setFlags(intent.getFlags()&~( 3422 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3423 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3424 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3425 Intent.FLAG_ACTIVITY_NEW_TASK)); 3426 3427 // Okay now we need to start the new activity, replacing the 3428 // currently running activity. This is a little tricky because 3429 // we want to start the new one as if the current one is finished, 3430 // but not finish the current one first so that there is no flicker. 3431 // And thus... 3432 final boolean wasFinishing = r.finishing; 3433 r.finishing = true; 3434 3435 // Propagate reply information over to the new activity. 3436 final ActivityRecord resultTo = r.resultTo; 3437 final String resultWho = r.resultWho; 3438 final int requestCode = r.requestCode; 3439 r.resultTo = null; 3440 if (resultTo != null) { 3441 resultTo.removeResultsLocked(r, resultWho, requestCode); 3442 } 3443 3444 final long origId = Binder.clearCallingIdentity(); 3445 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3446 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3447 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3448 options, false, null, null); 3449 Binder.restoreCallingIdentity(origId); 3450 3451 r.finishing = wasFinishing; 3452 if (res != ActivityManager.START_SUCCESS) { 3453 return false; 3454 } 3455 return true; 3456 } 3457 } 3458 3459 final int startActivityInPackage(int uid, String callingPackage, 3460 Intent intent, String resolvedType, IBinder resultTo, 3461 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3462 IActivityContainer container) { 3463 3464 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3465 false, true, "startActivityInPackage", null); 3466 3467 // TODO: Switch to user app stacks here. 3468 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3469 null, null, resultTo, resultWho, requestCode, startFlags, 3470 null, null, null, null, options, userId, container); 3471 return ret; 3472 } 3473 3474 @Override 3475 public final int startActivities(IApplicationThread caller, String callingPackage, 3476 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3477 int userId) { 3478 enforceNotIsolatedCaller("startActivities"); 3479 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3480 false, true, "startActivity", null); 3481 // TODO: Switch to user app stacks here. 3482 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3483 resolvedTypes, resultTo, options, userId); 3484 return ret; 3485 } 3486 3487 final int startActivitiesInPackage(int uid, String callingPackage, 3488 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3489 Bundle options, int userId) { 3490 3491 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3492 false, true, "startActivityInPackage", null); 3493 // TODO: Switch to user app stacks here. 3494 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3495 resultTo, options, userId); 3496 return ret; 3497 } 3498 3499 final void addRecentTaskLocked(TaskRecord task) { 3500 int N = mRecentTasks.size(); 3501 // Quick case: check if the top-most recent task is the same. 3502 if (N > 0 && mRecentTasks.get(0) == task) { 3503 return; 3504 } 3505 // Another quick case: never add voice sessions. 3506 if (task.voiceSession != null) { 3507 return; 3508 } 3509 // Remove any existing entries that are the same kind of task. 3510 final Intent intent = task.intent; 3511 final boolean document = intent != null && intent.isDocument(); 3512 for (int i=0; i<N; i++) { 3513 TaskRecord tr = mRecentTasks.get(i); 3514 if (task != tr) { 3515 if (task.userId != tr.userId) { 3516 continue; 3517 } 3518 final Intent trIntent = tr.intent; 3519 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3520 (intent == null || !intent.filterEquals(trIntent))) { 3521 continue; 3522 } 3523 if (document || trIntent != null && trIntent.isDocument()) { 3524 // Document tasks do not match other tasks. 3525 continue; 3526 } 3527 } 3528 3529 // Either task and tr are the same or, their affinities match or their intents match 3530 // and neither of them is a document. 3531 tr.disposeThumbnail(); 3532 mRecentTasks.remove(i); 3533 i--; 3534 N--; 3535 if (task.intent == null) { 3536 // If the new recent task we are adding is not fully 3537 // specified, then replace it with the existing recent task. 3538 task = tr; 3539 } 3540 } 3541 if (N >= MAX_RECENT_TASKS) { 3542 mRecentTasks.remove(N-1).disposeThumbnail(); 3543 } 3544 mRecentTasks.add(0, task); 3545 } 3546 3547 @Override 3548 public void reportActivityFullyDrawn(IBinder token) { 3549 synchronized (this) { 3550 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3551 if (r == null) { 3552 return; 3553 } 3554 r.reportFullyDrawnLocked(); 3555 } 3556 } 3557 3558 @Override 3559 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3560 synchronized (this) { 3561 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3562 if (r == null) { 3563 return; 3564 } 3565 final long origId = Binder.clearCallingIdentity(); 3566 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3567 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3568 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3569 if (config != null) { 3570 r.frozenBeforeDestroy = true; 3571 if (!updateConfigurationLocked(config, r, false, false)) { 3572 mStackSupervisor.resumeTopActivitiesLocked(); 3573 } 3574 } 3575 Binder.restoreCallingIdentity(origId); 3576 } 3577 } 3578 3579 @Override 3580 public int getRequestedOrientation(IBinder token) { 3581 synchronized (this) { 3582 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3583 if (r == null) { 3584 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3585 } 3586 return mWindowManager.getAppOrientation(r.appToken); 3587 } 3588 } 3589 3590 /** 3591 * This is the internal entry point for handling Activity.finish(). 3592 * 3593 * @param token The Binder token referencing the Activity we want to finish. 3594 * @param resultCode Result code, if any, from this Activity. 3595 * @param resultData Result data (Intent), if any, from this Activity. 3596 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3597 * the root Activity in the task. 3598 * 3599 * @return Returns true if the activity successfully finished, or false if it is still running. 3600 */ 3601 @Override 3602 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3603 boolean finishTask) { 3604 // Refuse possible leaked file descriptors 3605 if (resultData != null && resultData.hasFileDescriptors() == true) { 3606 throw new IllegalArgumentException("File descriptors passed in Intent"); 3607 } 3608 3609 synchronized(this) { 3610 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3611 if (r == null) { 3612 return true; 3613 } 3614 // Keep track of the root activity of the task before we finish it 3615 TaskRecord tr = r.task; 3616 ActivityRecord rootR = tr.getRootActivity(); 3617 if (mController != null) { 3618 // Find the first activity that is not finishing. 3619 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3620 if (next != null) { 3621 // ask watcher if this is allowed 3622 boolean resumeOK = true; 3623 try { 3624 resumeOK = mController.activityResuming(next.packageName); 3625 } catch (RemoteException e) { 3626 mController = null; 3627 Watchdog.getInstance().setActivityController(null); 3628 } 3629 3630 if (!resumeOK) { 3631 return false; 3632 } 3633 } 3634 } 3635 final long origId = Binder.clearCallingIdentity(); 3636 try { 3637 boolean res; 3638 if (finishTask && r == rootR) { 3639 // If requested, remove the task that is associated to this activity only if it 3640 // was the root activity in the task. The result code and data is ignored because 3641 // we don't support returning them across task boundaries. 3642 res = removeTaskByIdLocked(tr.taskId, 0); 3643 } else { 3644 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3645 resultData, "app-request", true); 3646 } 3647 return res; 3648 } finally { 3649 Binder.restoreCallingIdentity(origId); 3650 } 3651 } 3652 } 3653 3654 @Override 3655 public final void finishHeavyWeightApp() { 3656 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3657 != PackageManager.PERMISSION_GRANTED) { 3658 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3659 + Binder.getCallingPid() 3660 + ", uid=" + Binder.getCallingUid() 3661 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3662 Slog.w(TAG, msg); 3663 throw new SecurityException(msg); 3664 } 3665 3666 synchronized(this) { 3667 if (mHeavyWeightProcess == null) { 3668 return; 3669 } 3670 3671 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3672 mHeavyWeightProcess.activities); 3673 for (int i=0; i<activities.size(); i++) { 3674 ActivityRecord r = activities.get(i); 3675 if (!r.finishing) { 3676 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3677 null, "finish-heavy", true); 3678 } 3679 } 3680 3681 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3682 mHeavyWeightProcess.userId, 0)); 3683 mHeavyWeightProcess = null; 3684 } 3685 } 3686 3687 @Override 3688 public void crashApplication(int uid, int initialPid, String packageName, 3689 String message) { 3690 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3691 != PackageManager.PERMISSION_GRANTED) { 3692 String msg = "Permission Denial: crashApplication() from pid=" 3693 + Binder.getCallingPid() 3694 + ", uid=" + Binder.getCallingUid() 3695 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3696 Slog.w(TAG, msg); 3697 throw new SecurityException(msg); 3698 } 3699 3700 synchronized(this) { 3701 ProcessRecord proc = null; 3702 3703 // Figure out which process to kill. We don't trust that initialPid 3704 // still has any relation to current pids, so must scan through the 3705 // list. 3706 synchronized (mPidsSelfLocked) { 3707 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3708 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3709 if (p.uid != uid) { 3710 continue; 3711 } 3712 if (p.pid == initialPid) { 3713 proc = p; 3714 break; 3715 } 3716 if (p.pkgList.containsKey(packageName)) { 3717 proc = p; 3718 } 3719 } 3720 } 3721 3722 if (proc == null) { 3723 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3724 + " initialPid=" + initialPid 3725 + " packageName=" + packageName); 3726 return; 3727 } 3728 3729 if (proc.thread != null) { 3730 if (proc.pid == Process.myPid()) { 3731 Log.w(TAG, "crashApplication: trying to crash self!"); 3732 return; 3733 } 3734 long ident = Binder.clearCallingIdentity(); 3735 try { 3736 proc.thread.scheduleCrash(message); 3737 } catch (RemoteException e) { 3738 } 3739 Binder.restoreCallingIdentity(ident); 3740 } 3741 } 3742 } 3743 3744 @Override 3745 public final void finishSubActivity(IBinder token, String resultWho, 3746 int requestCode) { 3747 synchronized(this) { 3748 final long origId = Binder.clearCallingIdentity(); 3749 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3750 if (r != null) { 3751 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3752 } 3753 Binder.restoreCallingIdentity(origId); 3754 } 3755 } 3756 3757 @Override 3758 public boolean finishActivityAffinity(IBinder token) { 3759 synchronized(this) { 3760 final long origId = Binder.clearCallingIdentity(); 3761 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3762 boolean res = false; 3763 if (r != null) { 3764 res = r.task.stack.finishActivityAffinityLocked(r); 3765 } 3766 Binder.restoreCallingIdentity(origId); 3767 return res; 3768 } 3769 } 3770 3771 @Override 3772 public boolean willActivityBeVisible(IBinder token) { 3773 synchronized(this) { 3774 ActivityStack stack = ActivityRecord.getStackLocked(token); 3775 if (stack != null) { 3776 return stack.willActivityBeVisibleLocked(token); 3777 } 3778 return false; 3779 } 3780 } 3781 3782 @Override 3783 public void overridePendingTransition(IBinder token, String packageName, 3784 int enterAnim, int exitAnim) { 3785 synchronized(this) { 3786 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3787 if (self == null) { 3788 return; 3789 } 3790 3791 final long origId = Binder.clearCallingIdentity(); 3792 3793 if (self.state == ActivityState.RESUMED 3794 || self.state == ActivityState.PAUSING) { 3795 mWindowManager.overridePendingAppTransition(packageName, 3796 enterAnim, exitAnim, null); 3797 } 3798 3799 Binder.restoreCallingIdentity(origId); 3800 } 3801 } 3802 3803 /** 3804 * Main function for removing an existing process from the activity manager 3805 * as a result of that process going away. Clears out all connections 3806 * to the process. 3807 */ 3808 private final void handleAppDiedLocked(ProcessRecord app, 3809 boolean restarting, boolean allowRestart) { 3810 int pid = app.pid; 3811 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3812 if (!restarting) { 3813 removeLruProcessLocked(app); 3814 if (pid > 0) { 3815 ProcessList.remove(pid); 3816 } 3817 } 3818 3819 if (mProfileProc == app) { 3820 clearProfilerLocked(); 3821 } 3822 3823 // Remove this application's activities from active lists. 3824 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3825 3826 app.activities.clear(); 3827 3828 if (app.instrumentationClass != null) { 3829 Slog.w(TAG, "Crash of app " + app.processName 3830 + " running instrumentation " + app.instrumentationClass); 3831 Bundle info = new Bundle(); 3832 info.putString("shortMsg", "Process crashed."); 3833 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3834 } 3835 3836 if (!restarting) { 3837 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3838 // If there was nothing to resume, and we are not already 3839 // restarting this process, but there is a visible activity that 3840 // is hosted by the process... then make sure all visible 3841 // activities are running, taking care of restarting this 3842 // process. 3843 if (hasVisibleActivities) { 3844 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3845 } 3846 } 3847 } 3848 } 3849 3850 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3851 IBinder threadBinder = thread.asBinder(); 3852 // Find the application record. 3853 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3854 ProcessRecord rec = mLruProcesses.get(i); 3855 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3856 return i; 3857 } 3858 } 3859 return -1; 3860 } 3861 3862 final ProcessRecord getRecordForAppLocked( 3863 IApplicationThread thread) { 3864 if (thread == null) { 3865 return null; 3866 } 3867 3868 int appIndex = getLRURecordIndexForAppLocked(thread); 3869 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3870 } 3871 3872 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3873 // If there are no longer any background processes running, 3874 // and the app that died was not running instrumentation, 3875 // then tell everyone we are now low on memory. 3876 boolean haveBg = false; 3877 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3878 ProcessRecord rec = mLruProcesses.get(i); 3879 if (rec.thread != null 3880 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3881 haveBg = true; 3882 break; 3883 } 3884 } 3885 3886 if (!haveBg) { 3887 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3888 if (doReport) { 3889 long now = SystemClock.uptimeMillis(); 3890 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3891 doReport = false; 3892 } else { 3893 mLastMemUsageReportTime = now; 3894 } 3895 } 3896 final ArrayList<ProcessMemInfo> memInfos 3897 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3898 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3899 long now = SystemClock.uptimeMillis(); 3900 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3901 ProcessRecord rec = mLruProcesses.get(i); 3902 if (rec == dyingProc || rec.thread == null) { 3903 continue; 3904 } 3905 if (doReport) { 3906 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3907 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3908 } 3909 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3910 // The low memory report is overriding any current 3911 // state for a GC request. Make sure to do 3912 // heavy/important/visible/foreground processes first. 3913 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3914 rec.lastRequestedGc = 0; 3915 } else { 3916 rec.lastRequestedGc = rec.lastLowMemory; 3917 } 3918 rec.reportLowMemory = true; 3919 rec.lastLowMemory = now; 3920 mProcessesToGc.remove(rec); 3921 addProcessToGcListLocked(rec); 3922 } 3923 } 3924 if (doReport) { 3925 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3926 mHandler.sendMessage(msg); 3927 } 3928 scheduleAppGcsLocked(); 3929 } 3930 } 3931 3932 final void appDiedLocked(ProcessRecord app, int pid, 3933 IApplicationThread thread) { 3934 3935 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3936 synchronized (stats) { 3937 stats.noteProcessDiedLocked(app.info.uid, pid); 3938 } 3939 3940 // Clean up already done if the process has been re-started. 3941 if (app.pid == pid && app.thread != null && 3942 app.thread.asBinder() == thread.asBinder()) { 3943 boolean doLowMem = app.instrumentationClass == null; 3944 boolean doOomAdj = doLowMem; 3945 if (!app.killedByAm) { 3946 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3947 + ") has died."); 3948 mAllowLowerMemLevel = true; 3949 } else { 3950 // Note that we always want to do oom adj to update our state with the 3951 // new number of procs. 3952 mAllowLowerMemLevel = false; 3953 doLowMem = false; 3954 } 3955 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3956 if (DEBUG_CLEANUP) Slog.v( 3957 TAG, "Dying app: " + app + ", pid: " + pid 3958 + ", thread: " + thread.asBinder()); 3959 handleAppDiedLocked(app, false, true); 3960 3961 if (doOomAdj) { 3962 updateOomAdjLocked(); 3963 } 3964 if (doLowMem) { 3965 doLowMemReportIfNeededLocked(app); 3966 } 3967 } else if (app.pid != pid) { 3968 // A new process has already been started. 3969 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3970 + ") has died and restarted (pid " + app.pid + ")."); 3971 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3972 } else if (DEBUG_PROCESSES) { 3973 Slog.d(TAG, "Received spurious death notification for thread " 3974 + thread.asBinder()); 3975 } 3976 } 3977 3978 /** 3979 * If a stack trace dump file is configured, dump process stack traces. 3980 * @param clearTraces causes the dump file to be erased prior to the new 3981 * traces being written, if true; when false, the new traces will be 3982 * appended to any existing file content. 3983 * @param firstPids of dalvik VM processes to dump stack traces for first 3984 * @param lastPids of dalvik VM processes to dump stack traces for last 3985 * @param nativeProcs optional list of native process names to dump stack crawls 3986 * @return file containing stack traces, or null if no dump file is configured 3987 */ 3988 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3989 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3990 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3991 if (tracesPath == null || tracesPath.length() == 0) { 3992 return null; 3993 } 3994 3995 File tracesFile = new File(tracesPath); 3996 try { 3997 File tracesDir = tracesFile.getParentFile(); 3998 if (!tracesDir.exists()) { 3999 tracesFile.mkdirs(); 4000 if (!SELinux.restorecon(tracesDir)) { 4001 return null; 4002 } 4003 } 4004 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4005 4006 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4007 tracesFile.createNewFile(); 4008 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4009 } catch (IOException e) { 4010 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4011 return null; 4012 } 4013 4014 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4015 return tracesFile; 4016 } 4017 4018 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4019 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4020 // Use a FileObserver to detect when traces finish writing. 4021 // The order of traces is considered important to maintain for legibility. 4022 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4023 @Override 4024 public synchronized void onEvent(int event, String path) { notify(); } 4025 }; 4026 4027 try { 4028 observer.startWatching(); 4029 4030 // First collect all of the stacks of the most important pids. 4031 if (firstPids != null) { 4032 try { 4033 int num = firstPids.size(); 4034 for (int i = 0; i < num; i++) { 4035 synchronized (observer) { 4036 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4037 observer.wait(200); // Wait for write-close, give up after 200msec 4038 } 4039 } 4040 } catch (InterruptedException e) { 4041 Log.wtf(TAG, e); 4042 } 4043 } 4044 4045 // Next collect the stacks of the native pids 4046 if (nativeProcs != null) { 4047 int[] pids = Process.getPidsForCommands(nativeProcs); 4048 if (pids != null) { 4049 for (int pid : pids) { 4050 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4051 } 4052 } 4053 } 4054 4055 // Lastly, measure CPU usage. 4056 if (processCpuTracker != null) { 4057 processCpuTracker.init(); 4058 System.gc(); 4059 processCpuTracker.update(); 4060 try { 4061 synchronized (processCpuTracker) { 4062 processCpuTracker.wait(500); // measure over 1/2 second. 4063 } 4064 } catch (InterruptedException e) { 4065 } 4066 processCpuTracker.update(); 4067 4068 // We'll take the stack crawls of just the top apps using CPU. 4069 final int N = processCpuTracker.countWorkingStats(); 4070 int numProcs = 0; 4071 for (int i=0; i<N && numProcs<5; i++) { 4072 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4073 if (lastPids.indexOfKey(stats.pid) >= 0) { 4074 numProcs++; 4075 try { 4076 synchronized (observer) { 4077 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4078 observer.wait(200); // Wait for write-close, give up after 200msec 4079 } 4080 } catch (InterruptedException e) { 4081 Log.wtf(TAG, e); 4082 } 4083 4084 } 4085 } 4086 } 4087 } finally { 4088 observer.stopWatching(); 4089 } 4090 } 4091 4092 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4093 if (true || IS_USER_BUILD) { 4094 return; 4095 } 4096 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4097 if (tracesPath == null || tracesPath.length() == 0) { 4098 return; 4099 } 4100 4101 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4102 StrictMode.allowThreadDiskWrites(); 4103 try { 4104 final File tracesFile = new File(tracesPath); 4105 final File tracesDir = tracesFile.getParentFile(); 4106 final File tracesTmp = new File(tracesDir, "__tmp__"); 4107 try { 4108 if (!tracesDir.exists()) { 4109 tracesFile.mkdirs(); 4110 if (!SELinux.restorecon(tracesDir.getPath())) { 4111 return; 4112 } 4113 } 4114 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4115 4116 if (tracesFile.exists()) { 4117 tracesTmp.delete(); 4118 tracesFile.renameTo(tracesTmp); 4119 } 4120 StringBuilder sb = new StringBuilder(); 4121 Time tobj = new Time(); 4122 tobj.set(System.currentTimeMillis()); 4123 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4124 sb.append(": "); 4125 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4126 sb.append(" since "); 4127 sb.append(msg); 4128 FileOutputStream fos = new FileOutputStream(tracesFile); 4129 fos.write(sb.toString().getBytes()); 4130 if (app == null) { 4131 fos.write("\n*** No application process!".getBytes()); 4132 } 4133 fos.close(); 4134 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4135 } catch (IOException e) { 4136 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4137 return; 4138 } 4139 4140 if (app != null) { 4141 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4142 firstPids.add(app.pid); 4143 dumpStackTraces(tracesPath, firstPids, null, null, null); 4144 } 4145 4146 File lastTracesFile = null; 4147 File curTracesFile = null; 4148 for (int i=9; i>=0; i--) { 4149 String name = String.format(Locale.US, "slow%02d.txt", i); 4150 curTracesFile = new File(tracesDir, name); 4151 if (curTracesFile.exists()) { 4152 if (lastTracesFile != null) { 4153 curTracesFile.renameTo(lastTracesFile); 4154 } else { 4155 curTracesFile.delete(); 4156 } 4157 } 4158 lastTracesFile = curTracesFile; 4159 } 4160 tracesFile.renameTo(curTracesFile); 4161 if (tracesTmp.exists()) { 4162 tracesTmp.renameTo(tracesFile); 4163 } 4164 } finally { 4165 StrictMode.setThreadPolicy(oldPolicy); 4166 } 4167 } 4168 4169 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4170 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4171 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4172 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4173 4174 if (mController != null) { 4175 try { 4176 // 0 == continue, -1 = kill process immediately 4177 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4178 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4179 } catch (RemoteException e) { 4180 mController = null; 4181 Watchdog.getInstance().setActivityController(null); 4182 } 4183 } 4184 4185 long anrTime = SystemClock.uptimeMillis(); 4186 if (MONITOR_CPU_USAGE) { 4187 updateCpuStatsNow(); 4188 } 4189 4190 synchronized (this) { 4191 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4192 if (mShuttingDown) { 4193 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4194 return; 4195 } else if (app.notResponding) { 4196 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4197 return; 4198 } else if (app.crashing) { 4199 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4200 return; 4201 } 4202 4203 // In case we come through here for the same app before completing 4204 // this one, mark as anring now so we will bail out. 4205 app.notResponding = true; 4206 4207 // Log the ANR to the event log. 4208 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4209 app.processName, app.info.flags, annotation); 4210 4211 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4212 firstPids.add(app.pid); 4213 4214 int parentPid = app.pid; 4215 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4216 if (parentPid != app.pid) firstPids.add(parentPid); 4217 4218 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4219 4220 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4221 ProcessRecord r = mLruProcesses.get(i); 4222 if (r != null && r.thread != null) { 4223 int pid = r.pid; 4224 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4225 if (r.persistent) { 4226 firstPids.add(pid); 4227 } else { 4228 lastPids.put(pid, Boolean.TRUE); 4229 } 4230 } 4231 } 4232 } 4233 } 4234 4235 // Log the ANR to the main log. 4236 StringBuilder info = new StringBuilder(); 4237 info.setLength(0); 4238 info.append("ANR in ").append(app.processName); 4239 if (activity != null && activity.shortComponentName != null) { 4240 info.append(" (").append(activity.shortComponentName).append(")"); 4241 } 4242 info.append("\n"); 4243 info.append("PID: ").append(app.pid).append("\n"); 4244 if (annotation != null) { 4245 info.append("Reason: ").append(annotation).append("\n"); 4246 } 4247 if (parent != null && parent != activity) { 4248 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4249 } 4250 4251 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4252 4253 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4254 NATIVE_STACKS_OF_INTEREST); 4255 4256 String cpuInfo = null; 4257 if (MONITOR_CPU_USAGE) { 4258 updateCpuStatsNow(); 4259 synchronized (mProcessCpuThread) { 4260 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4261 } 4262 info.append(processCpuTracker.printCurrentLoad()); 4263 info.append(cpuInfo); 4264 } 4265 4266 info.append(processCpuTracker.printCurrentState(anrTime)); 4267 4268 Slog.e(TAG, info.toString()); 4269 if (tracesFile == null) { 4270 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4271 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4272 } 4273 4274 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4275 cpuInfo, tracesFile, null); 4276 4277 if (mController != null) { 4278 try { 4279 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4280 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4281 if (res != 0) { 4282 if (res < 0 && app.pid != MY_PID) { 4283 Process.killProcess(app.pid); 4284 } else { 4285 synchronized (this) { 4286 mServices.scheduleServiceTimeoutLocked(app); 4287 } 4288 } 4289 return; 4290 } 4291 } catch (RemoteException e) { 4292 mController = null; 4293 Watchdog.getInstance().setActivityController(null); 4294 } 4295 } 4296 4297 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4298 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4299 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4300 4301 synchronized (this) { 4302 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4303 killUnneededProcessLocked(app, "background ANR"); 4304 return; 4305 } 4306 4307 // Set the app's notResponding state, and look up the errorReportReceiver 4308 makeAppNotRespondingLocked(app, 4309 activity != null ? activity.shortComponentName : null, 4310 annotation != null ? "ANR " + annotation : "ANR", 4311 info.toString()); 4312 4313 // Bring up the infamous App Not Responding dialog 4314 Message msg = Message.obtain(); 4315 HashMap<String, Object> map = new HashMap<String, Object>(); 4316 msg.what = SHOW_NOT_RESPONDING_MSG; 4317 msg.obj = map; 4318 msg.arg1 = aboveSystem ? 1 : 0; 4319 map.put("app", app); 4320 if (activity != null) { 4321 map.put("activity", activity); 4322 } 4323 4324 mHandler.sendMessage(msg); 4325 } 4326 } 4327 4328 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4329 if (!mLaunchWarningShown) { 4330 mLaunchWarningShown = true; 4331 mHandler.post(new Runnable() { 4332 @Override 4333 public void run() { 4334 synchronized (ActivityManagerService.this) { 4335 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4336 d.show(); 4337 mHandler.postDelayed(new Runnable() { 4338 @Override 4339 public void run() { 4340 synchronized (ActivityManagerService.this) { 4341 d.dismiss(); 4342 mLaunchWarningShown = false; 4343 } 4344 } 4345 }, 4000); 4346 } 4347 } 4348 }); 4349 } 4350 } 4351 4352 @Override 4353 public boolean clearApplicationUserData(final String packageName, 4354 final IPackageDataObserver observer, int userId) { 4355 enforceNotIsolatedCaller("clearApplicationUserData"); 4356 int uid = Binder.getCallingUid(); 4357 int pid = Binder.getCallingPid(); 4358 userId = handleIncomingUser(pid, uid, 4359 userId, false, true, "clearApplicationUserData", null); 4360 long callingId = Binder.clearCallingIdentity(); 4361 try { 4362 IPackageManager pm = AppGlobals.getPackageManager(); 4363 int pkgUid = -1; 4364 synchronized(this) { 4365 try { 4366 pkgUid = pm.getPackageUid(packageName, userId); 4367 } catch (RemoteException e) { 4368 } 4369 if (pkgUid == -1) { 4370 Slog.w(TAG, "Invalid packageName: " + packageName); 4371 if (observer != null) { 4372 try { 4373 observer.onRemoveCompleted(packageName, false); 4374 } catch (RemoteException e) { 4375 Slog.i(TAG, "Observer no longer exists."); 4376 } 4377 } 4378 return false; 4379 } 4380 if (uid == pkgUid || checkComponentPermission( 4381 android.Manifest.permission.CLEAR_APP_USER_DATA, 4382 pid, uid, -1, true) 4383 == PackageManager.PERMISSION_GRANTED) { 4384 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4385 } else { 4386 throw new SecurityException("PID " + pid + " does not have permission " 4387 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4388 + " of package " + packageName); 4389 } 4390 } 4391 4392 try { 4393 // Clear application user data 4394 pm.clearApplicationUserData(packageName, observer, userId); 4395 4396 // Remove all permissions granted from/to this package 4397 removeUriPermissionsForPackageLocked(packageName, userId, true); 4398 4399 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4400 Uri.fromParts("package", packageName, null)); 4401 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4402 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4403 null, null, 0, null, null, null, false, false, userId); 4404 } catch (RemoteException e) { 4405 } 4406 } finally { 4407 Binder.restoreCallingIdentity(callingId); 4408 } 4409 return true; 4410 } 4411 4412 @Override 4413 public void killBackgroundProcesses(final String packageName, int userId) { 4414 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4415 != PackageManager.PERMISSION_GRANTED && 4416 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4417 != PackageManager.PERMISSION_GRANTED) { 4418 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4419 + Binder.getCallingPid() 4420 + ", uid=" + Binder.getCallingUid() 4421 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4422 Slog.w(TAG, msg); 4423 throw new SecurityException(msg); 4424 } 4425 4426 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4427 userId, true, true, "killBackgroundProcesses", null); 4428 long callingId = Binder.clearCallingIdentity(); 4429 try { 4430 IPackageManager pm = AppGlobals.getPackageManager(); 4431 synchronized(this) { 4432 int appId = -1; 4433 try { 4434 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4435 } catch (RemoteException e) { 4436 } 4437 if (appId == -1) { 4438 Slog.w(TAG, "Invalid packageName: " + packageName); 4439 return; 4440 } 4441 killPackageProcessesLocked(packageName, appId, userId, 4442 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4443 } 4444 } finally { 4445 Binder.restoreCallingIdentity(callingId); 4446 } 4447 } 4448 4449 @Override 4450 public void killAllBackgroundProcesses() { 4451 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4452 != PackageManager.PERMISSION_GRANTED) { 4453 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4454 + Binder.getCallingPid() 4455 + ", uid=" + Binder.getCallingUid() 4456 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4457 Slog.w(TAG, msg); 4458 throw new SecurityException(msg); 4459 } 4460 4461 long callingId = Binder.clearCallingIdentity(); 4462 try { 4463 synchronized(this) { 4464 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4465 final int NP = mProcessNames.getMap().size(); 4466 for (int ip=0; ip<NP; ip++) { 4467 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4468 final int NA = apps.size(); 4469 for (int ia=0; ia<NA; ia++) { 4470 ProcessRecord app = apps.valueAt(ia); 4471 if (app.persistent) { 4472 // we don't kill persistent processes 4473 continue; 4474 } 4475 if (app.removed) { 4476 procs.add(app); 4477 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4478 app.removed = true; 4479 procs.add(app); 4480 } 4481 } 4482 } 4483 4484 int N = procs.size(); 4485 for (int i=0; i<N; i++) { 4486 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4487 } 4488 mAllowLowerMemLevel = true; 4489 updateOomAdjLocked(); 4490 doLowMemReportIfNeededLocked(null); 4491 } 4492 } finally { 4493 Binder.restoreCallingIdentity(callingId); 4494 } 4495 } 4496 4497 @Override 4498 public void forceStopPackage(final String packageName, int userId) { 4499 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4500 != PackageManager.PERMISSION_GRANTED) { 4501 String msg = "Permission Denial: forceStopPackage() from pid=" 4502 + Binder.getCallingPid() 4503 + ", uid=" + Binder.getCallingUid() 4504 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4505 Slog.w(TAG, msg); 4506 throw new SecurityException(msg); 4507 } 4508 final int callingPid = Binder.getCallingPid(); 4509 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4510 userId, true, true, "forceStopPackage", null); 4511 long callingId = Binder.clearCallingIdentity(); 4512 try { 4513 IPackageManager pm = AppGlobals.getPackageManager(); 4514 synchronized(this) { 4515 int[] users = userId == UserHandle.USER_ALL 4516 ? getUsersLocked() : new int[] { userId }; 4517 for (int user : users) { 4518 int pkgUid = -1; 4519 try { 4520 pkgUid = pm.getPackageUid(packageName, user); 4521 } catch (RemoteException e) { 4522 } 4523 if (pkgUid == -1) { 4524 Slog.w(TAG, "Invalid packageName: " + packageName); 4525 continue; 4526 } 4527 try { 4528 pm.setPackageStoppedState(packageName, true, user); 4529 } catch (RemoteException e) { 4530 } catch (IllegalArgumentException e) { 4531 Slog.w(TAG, "Failed trying to unstop package " 4532 + packageName + ": " + e); 4533 } 4534 if (isUserRunningLocked(user, false)) { 4535 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4536 } 4537 } 4538 } 4539 } finally { 4540 Binder.restoreCallingIdentity(callingId); 4541 } 4542 } 4543 4544 /* 4545 * The pkg name and app id have to be specified. 4546 */ 4547 @Override 4548 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4549 if (pkg == null) { 4550 return; 4551 } 4552 // Make sure the uid is valid. 4553 if (appid < 0) { 4554 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4555 return; 4556 } 4557 int callerUid = Binder.getCallingUid(); 4558 // Only the system server can kill an application 4559 if (callerUid == Process.SYSTEM_UID) { 4560 // Post an aysnc message to kill the application 4561 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4562 msg.arg1 = appid; 4563 msg.arg2 = 0; 4564 Bundle bundle = new Bundle(); 4565 bundle.putString("pkg", pkg); 4566 bundle.putString("reason", reason); 4567 msg.obj = bundle; 4568 mHandler.sendMessage(msg); 4569 } else { 4570 throw new SecurityException(callerUid + " cannot kill pkg: " + 4571 pkg); 4572 } 4573 } 4574 4575 @Override 4576 public void closeSystemDialogs(String reason) { 4577 enforceNotIsolatedCaller("closeSystemDialogs"); 4578 4579 final int pid = Binder.getCallingPid(); 4580 final int uid = Binder.getCallingUid(); 4581 final long origId = Binder.clearCallingIdentity(); 4582 try { 4583 synchronized (this) { 4584 // Only allow this from foreground processes, so that background 4585 // applications can't abuse it to prevent system UI from being shown. 4586 if (uid >= Process.FIRST_APPLICATION_UID) { 4587 ProcessRecord proc; 4588 synchronized (mPidsSelfLocked) { 4589 proc = mPidsSelfLocked.get(pid); 4590 } 4591 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4592 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4593 + " from background process " + proc); 4594 return; 4595 } 4596 } 4597 closeSystemDialogsLocked(reason); 4598 } 4599 } finally { 4600 Binder.restoreCallingIdentity(origId); 4601 } 4602 } 4603 4604 void closeSystemDialogsLocked(String reason) { 4605 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4606 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4607 | Intent.FLAG_RECEIVER_FOREGROUND); 4608 if (reason != null) { 4609 intent.putExtra("reason", reason); 4610 } 4611 mWindowManager.closeSystemDialogs(reason); 4612 4613 mStackSupervisor.closeSystemDialogsLocked(); 4614 4615 broadcastIntentLocked(null, null, intent, null, 4616 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4617 Process.SYSTEM_UID, UserHandle.USER_ALL); 4618 } 4619 4620 @Override 4621 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4622 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4623 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4624 for (int i=pids.length-1; i>=0; i--) { 4625 ProcessRecord proc; 4626 int oomAdj; 4627 synchronized (this) { 4628 synchronized (mPidsSelfLocked) { 4629 proc = mPidsSelfLocked.get(pids[i]); 4630 oomAdj = proc != null ? proc.setAdj : 0; 4631 } 4632 } 4633 infos[i] = new Debug.MemoryInfo(); 4634 Debug.getMemoryInfo(pids[i], infos[i]); 4635 if (proc != null) { 4636 synchronized (this) { 4637 if (proc.thread != null && proc.setAdj == oomAdj) { 4638 // Record this for posterity if the process has been stable. 4639 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4640 infos[i].getTotalUss(), false, proc.pkgList); 4641 } 4642 } 4643 } 4644 } 4645 return infos; 4646 } 4647 4648 @Override 4649 public long[] getProcessPss(int[] pids) { 4650 enforceNotIsolatedCaller("getProcessPss"); 4651 long[] pss = new long[pids.length]; 4652 for (int i=pids.length-1; i>=0; i--) { 4653 ProcessRecord proc; 4654 int oomAdj; 4655 synchronized (this) { 4656 synchronized (mPidsSelfLocked) { 4657 proc = mPidsSelfLocked.get(pids[i]); 4658 oomAdj = proc != null ? proc.setAdj : 0; 4659 } 4660 } 4661 long[] tmpUss = new long[1]; 4662 pss[i] = Debug.getPss(pids[i], tmpUss); 4663 if (proc != null) { 4664 synchronized (this) { 4665 if (proc.thread != null && proc.setAdj == oomAdj) { 4666 // Record this for posterity if the process has been stable. 4667 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4668 } 4669 } 4670 } 4671 } 4672 return pss; 4673 } 4674 4675 @Override 4676 public void killApplicationProcess(String processName, int uid) { 4677 if (processName == null) { 4678 return; 4679 } 4680 4681 int callerUid = Binder.getCallingUid(); 4682 // Only the system server can kill an application 4683 if (callerUid == Process.SYSTEM_UID) { 4684 synchronized (this) { 4685 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4686 if (app != null && app.thread != null) { 4687 try { 4688 app.thread.scheduleSuicide(); 4689 } catch (RemoteException e) { 4690 // If the other end already died, then our work here is done. 4691 } 4692 } else { 4693 Slog.w(TAG, "Process/uid not found attempting kill of " 4694 + processName + " / " + uid); 4695 } 4696 } 4697 } else { 4698 throw new SecurityException(callerUid + " cannot kill app process: " + 4699 processName); 4700 } 4701 } 4702 4703 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4704 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4705 false, true, false, false, UserHandle.getUserId(uid), reason); 4706 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4707 Uri.fromParts("package", packageName, null)); 4708 if (!mProcessesReady) { 4709 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4710 | Intent.FLAG_RECEIVER_FOREGROUND); 4711 } 4712 intent.putExtra(Intent.EXTRA_UID, uid); 4713 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4714 broadcastIntentLocked(null, null, intent, 4715 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4716 false, false, 4717 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4718 } 4719 4720 private void forceStopUserLocked(int userId, String reason) { 4721 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4722 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4723 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4724 | Intent.FLAG_RECEIVER_FOREGROUND); 4725 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4726 broadcastIntentLocked(null, null, intent, 4727 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4728 false, false, 4729 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4730 } 4731 4732 private final boolean killPackageProcessesLocked(String packageName, int appId, 4733 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4734 boolean doit, boolean evenPersistent, String reason) { 4735 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4736 4737 // Remove all processes this package may have touched: all with the 4738 // same UID (except for the system or root user), and all whose name 4739 // matches the package name. 4740 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4741 final int NP = mProcessNames.getMap().size(); 4742 for (int ip=0; ip<NP; ip++) { 4743 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4744 final int NA = apps.size(); 4745 for (int ia=0; ia<NA; ia++) { 4746 ProcessRecord app = apps.valueAt(ia); 4747 if (app.persistent && !evenPersistent) { 4748 // we don't kill persistent processes 4749 continue; 4750 } 4751 if (app.removed) { 4752 if (doit) { 4753 procs.add(app); 4754 } 4755 continue; 4756 } 4757 4758 // Skip process if it doesn't meet our oom adj requirement. 4759 if (app.setAdj < minOomAdj) { 4760 continue; 4761 } 4762 4763 // If no package is specified, we call all processes under the 4764 // give user id. 4765 if (packageName == null) { 4766 if (app.userId != userId) { 4767 continue; 4768 } 4769 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4770 continue; 4771 } 4772 // Package has been specified, we want to hit all processes 4773 // that match it. We need to qualify this by the processes 4774 // that are running under the specified app and user ID. 4775 } else { 4776 if (UserHandle.getAppId(app.uid) != appId) { 4777 continue; 4778 } 4779 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4780 continue; 4781 } 4782 if (!app.pkgList.containsKey(packageName)) { 4783 continue; 4784 } 4785 } 4786 4787 // Process has passed all conditions, kill it! 4788 if (!doit) { 4789 return true; 4790 } 4791 app.removed = true; 4792 procs.add(app); 4793 } 4794 } 4795 4796 int N = procs.size(); 4797 for (int i=0; i<N; i++) { 4798 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4799 } 4800 updateOomAdjLocked(); 4801 return N > 0; 4802 } 4803 4804 private final boolean forceStopPackageLocked(String name, int appId, 4805 boolean callerWillRestart, boolean purgeCache, boolean doit, 4806 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4807 int i; 4808 int N; 4809 4810 if (userId == UserHandle.USER_ALL && name == null) { 4811 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4812 } 4813 4814 if (appId < 0 && name != null) { 4815 try { 4816 appId = UserHandle.getAppId( 4817 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4818 } catch (RemoteException e) { 4819 } 4820 } 4821 4822 if (doit) { 4823 if (name != null) { 4824 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4825 + " user=" + userId + ": " + reason); 4826 } else { 4827 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4828 } 4829 4830 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4831 for (int ip=pmap.size()-1; ip>=0; ip--) { 4832 SparseArray<Long> ba = pmap.valueAt(ip); 4833 for (i=ba.size()-1; i>=0; i--) { 4834 boolean remove = false; 4835 final int entUid = ba.keyAt(i); 4836 if (name != null) { 4837 if (userId == UserHandle.USER_ALL) { 4838 if (UserHandle.getAppId(entUid) == appId) { 4839 remove = true; 4840 } 4841 } else { 4842 if (entUid == UserHandle.getUid(userId, appId)) { 4843 remove = true; 4844 } 4845 } 4846 } else if (UserHandle.getUserId(entUid) == userId) { 4847 remove = true; 4848 } 4849 if (remove) { 4850 ba.removeAt(i); 4851 } 4852 } 4853 if (ba.size() == 0) { 4854 pmap.removeAt(ip); 4855 } 4856 } 4857 } 4858 4859 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4860 -100, callerWillRestart, true, doit, evenPersistent, 4861 name == null ? ("stop user " + userId) : ("stop " + name)); 4862 4863 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4864 if (!doit) { 4865 return true; 4866 } 4867 didSomething = true; 4868 } 4869 4870 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4871 if (!doit) { 4872 return true; 4873 } 4874 didSomething = true; 4875 } 4876 4877 if (name == null) { 4878 // Remove all sticky broadcasts from this user. 4879 mStickyBroadcasts.remove(userId); 4880 } 4881 4882 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4883 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4884 userId, providers)) { 4885 if (!doit) { 4886 return true; 4887 } 4888 didSomething = true; 4889 } 4890 N = providers.size(); 4891 for (i=0; i<N; i++) { 4892 removeDyingProviderLocked(null, providers.get(i), true); 4893 } 4894 4895 // Remove transient permissions granted from/to this package/user 4896 removeUriPermissionsForPackageLocked(name, userId, false); 4897 4898 if (name == null || uninstalling) { 4899 // Remove pending intents. For now we only do this when force 4900 // stopping users, because we have some problems when doing this 4901 // for packages -- app widgets are not currently cleaned up for 4902 // such packages, so they can be left with bad pending intents. 4903 if (mIntentSenderRecords.size() > 0) { 4904 Iterator<WeakReference<PendingIntentRecord>> it 4905 = mIntentSenderRecords.values().iterator(); 4906 while (it.hasNext()) { 4907 WeakReference<PendingIntentRecord> wpir = it.next(); 4908 if (wpir == null) { 4909 it.remove(); 4910 continue; 4911 } 4912 PendingIntentRecord pir = wpir.get(); 4913 if (pir == null) { 4914 it.remove(); 4915 continue; 4916 } 4917 if (name == null) { 4918 // Stopping user, remove all objects for the user. 4919 if (pir.key.userId != userId) { 4920 // Not the same user, skip it. 4921 continue; 4922 } 4923 } else { 4924 if (UserHandle.getAppId(pir.uid) != appId) { 4925 // Different app id, skip it. 4926 continue; 4927 } 4928 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4929 // Different user, skip it. 4930 continue; 4931 } 4932 if (!pir.key.packageName.equals(name)) { 4933 // Different package, skip it. 4934 continue; 4935 } 4936 } 4937 if (!doit) { 4938 return true; 4939 } 4940 didSomething = true; 4941 it.remove(); 4942 pir.canceled = true; 4943 if (pir.key.activity != null) { 4944 pir.key.activity.pendingResults.remove(pir.ref); 4945 } 4946 } 4947 } 4948 } 4949 4950 if (doit) { 4951 if (purgeCache && name != null) { 4952 AttributeCache ac = AttributeCache.instance(); 4953 if (ac != null) { 4954 ac.removePackage(name); 4955 } 4956 } 4957 if (mBooted) { 4958 mStackSupervisor.resumeTopActivitiesLocked(); 4959 mStackSupervisor.scheduleIdleLocked(); 4960 } 4961 } 4962 4963 return didSomething; 4964 } 4965 4966 private final boolean removeProcessLocked(ProcessRecord app, 4967 boolean callerWillRestart, boolean allowRestart, String reason) { 4968 final String name = app.processName; 4969 final int uid = app.uid; 4970 if (DEBUG_PROCESSES) Slog.d( 4971 TAG, "Force removing proc " + app.toShortString() + " (" + name 4972 + "/" + uid + ")"); 4973 4974 mProcessNames.remove(name, uid); 4975 mIsolatedProcesses.remove(app.uid); 4976 if (mHeavyWeightProcess == app) { 4977 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4978 mHeavyWeightProcess.userId, 0)); 4979 mHeavyWeightProcess = null; 4980 } 4981 boolean needRestart = false; 4982 if (app.pid > 0 && app.pid != MY_PID) { 4983 int pid = app.pid; 4984 synchronized (mPidsSelfLocked) { 4985 mPidsSelfLocked.remove(pid); 4986 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4987 } 4988 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4989 app.processName, app.info.uid); 4990 if (app.isolated) { 4991 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4992 } 4993 killUnneededProcessLocked(app, reason); 4994 handleAppDiedLocked(app, true, allowRestart); 4995 removeLruProcessLocked(app); 4996 4997 if (app.persistent && !app.isolated) { 4998 if (!callerWillRestart) { 4999 addAppLocked(app.info, false); 5000 } else { 5001 needRestart = true; 5002 } 5003 } 5004 } else { 5005 mRemovedProcesses.add(app); 5006 } 5007 5008 return needRestart; 5009 } 5010 5011 private final void processStartTimedOutLocked(ProcessRecord app) { 5012 final int pid = app.pid; 5013 boolean gone = false; 5014 synchronized (mPidsSelfLocked) { 5015 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5016 if (knownApp != null && knownApp.thread == null) { 5017 mPidsSelfLocked.remove(pid); 5018 gone = true; 5019 } 5020 } 5021 5022 if (gone) { 5023 Slog.w(TAG, "Process " + app + " failed to attach"); 5024 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5025 pid, app.uid, app.processName); 5026 mProcessNames.remove(app.processName, app.uid); 5027 mIsolatedProcesses.remove(app.uid); 5028 if (mHeavyWeightProcess == app) { 5029 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5030 mHeavyWeightProcess.userId, 0)); 5031 mHeavyWeightProcess = null; 5032 } 5033 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5034 app.processName, app.info.uid); 5035 if (app.isolated) { 5036 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5037 } 5038 // Take care of any launching providers waiting for this process. 5039 checkAppInLaunchingProvidersLocked(app, true); 5040 // Take care of any services that are waiting for the process. 5041 mServices.processStartTimedOutLocked(app); 5042 killUnneededProcessLocked(app, "start timeout"); 5043 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5044 Slog.w(TAG, "Unattached app died before backup, skipping"); 5045 try { 5046 IBackupManager bm = IBackupManager.Stub.asInterface( 5047 ServiceManager.getService(Context.BACKUP_SERVICE)); 5048 bm.agentDisconnected(app.info.packageName); 5049 } catch (RemoteException e) { 5050 // Can't happen; the backup manager is local 5051 } 5052 } 5053 if (isPendingBroadcastProcessLocked(pid)) { 5054 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5055 skipPendingBroadcastLocked(pid); 5056 } 5057 } else { 5058 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5059 } 5060 } 5061 5062 private final boolean attachApplicationLocked(IApplicationThread thread, 5063 int pid) { 5064 5065 // Find the application record that is being attached... either via 5066 // the pid if we are running in multiple processes, or just pull the 5067 // next app record if we are emulating process with anonymous threads. 5068 ProcessRecord app; 5069 if (pid != MY_PID && pid >= 0) { 5070 synchronized (mPidsSelfLocked) { 5071 app = mPidsSelfLocked.get(pid); 5072 } 5073 } else { 5074 app = null; 5075 } 5076 5077 if (app == null) { 5078 Slog.w(TAG, "No pending application record for pid " + pid 5079 + " (IApplicationThread " + thread + "); dropping process"); 5080 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5081 if (pid > 0 && pid != MY_PID) { 5082 Process.killProcessQuiet(pid); 5083 } else { 5084 try { 5085 thread.scheduleExit(); 5086 } catch (Exception e) { 5087 // Ignore exceptions. 5088 } 5089 } 5090 return false; 5091 } 5092 5093 // If this application record is still attached to a previous 5094 // process, clean it up now. 5095 if (app.thread != null) { 5096 handleAppDiedLocked(app, true, true); 5097 } 5098 5099 // Tell the process all about itself. 5100 5101 if (localLOGV) Slog.v( 5102 TAG, "Binding process pid " + pid + " to record " + app); 5103 5104 final String processName = app.processName; 5105 try { 5106 AppDeathRecipient adr = new AppDeathRecipient( 5107 app, pid, thread); 5108 thread.asBinder().linkToDeath(adr, 0); 5109 app.deathRecipient = adr; 5110 } catch (RemoteException e) { 5111 app.resetPackageList(mProcessStats); 5112 startProcessLocked(app, "link fail", processName); 5113 return false; 5114 } 5115 5116 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5117 5118 app.makeActive(thread, mProcessStats); 5119 app.curAdj = app.setAdj = -100; 5120 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5121 app.forcingToForeground = null; 5122 updateProcessForegroundLocked(app, false, false); 5123 app.hasShownUi = false; 5124 app.debugging = false; 5125 app.cached = false; 5126 5127 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5128 5129 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5130 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5131 5132 if (!normalMode) { 5133 Slog.i(TAG, "Launching preboot mode app: " + app); 5134 } 5135 5136 if (localLOGV) Slog.v( 5137 TAG, "New app record " + app 5138 + " thread=" + thread.asBinder() + " pid=" + pid); 5139 try { 5140 int testMode = IApplicationThread.DEBUG_OFF; 5141 if (mDebugApp != null && mDebugApp.equals(processName)) { 5142 testMode = mWaitForDebugger 5143 ? IApplicationThread.DEBUG_WAIT 5144 : IApplicationThread.DEBUG_ON; 5145 app.debugging = true; 5146 if (mDebugTransient) { 5147 mDebugApp = mOrigDebugApp; 5148 mWaitForDebugger = mOrigWaitForDebugger; 5149 } 5150 } 5151 String profileFile = app.instrumentationProfileFile; 5152 ParcelFileDescriptor profileFd = null; 5153 boolean profileAutoStop = false; 5154 if (mProfileApp != null && mProfileApp.equals(processName)) { 5155 mProfileProc = app; 5156 profileFile = mProfileFile; 5157 profileFd = mProfileFd; 5158 profileAutoStop = mAutoStopProfiler; 5159 } 5160 boolean enableOpenGlTrace = false; 5161 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5162 enableOpenGlTrace = true; 5163 mOpenGlTraceApp = null; 5164 } 5165 5166 // If the app is being launched for restore or full backup, set it up specially 5167 boolean isRestrictedBackupMode = false; 5168 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5169 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5170 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5171 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5172 } 5173 5174 ensurePackageDexOpt(app.instrumentationInfo != null 5175 ? app.instrumentationInfo.packageName 5176 : app.info.packageName); 5177 if (app.instrumentationClass != null) { 5178 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5179 } 5180 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5181 + processName + " with config " + mConfiguration); 5182 ApplicationInfo appInfo = app.instrumentationInfo != null 5183 ? app.instrumentationInfo : app.info; 5184 app.compat = compatibilityInfoForPackageLocked(appInfo); 5185 if (profileFd != null) { 5186 profileFd = profileFd.dup(); 5187 } 5188 thread.bindApplication(processName, appInfo, providers, 5189 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5190 app.instrumentationArguments, app.instrumentationWatcher, 5191 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5192 isRestrictedBackupMode || !normalMode, app.persistent, 5193 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5194 mCoreSettingsObserver.getCoreSettingsLocked()); 5195 updateLruProcessLocked(app, false, null); 5196 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5197 } catch (Exception e) { 5198 // todo: Yikes! What should we do? For now we will try to 5199 // start another process, but that could easily get us in 5200 // an infinite loop of restarting processes... 5201 Slog.w(TAG, "Exception thrown during bind!", e); 5202 5203 app.resetPackageList(mProcessStats); 5204 app.unlinkDeathRecipient(); 5205 startProcessLocked(app, "bind fail", processName); 5206 return false; 5207 } 5208 5209 // Remove this record from the list of starting applications. 5210 mPersistentStartingProcesses.remove(app); 5211 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5212 "Attach application locked removing on hold: " + app); 5213 mProcessesOnHold.remove(app); 5214 5215 boolean badApp = false; 5216 boolean didSomething = false; 5217 5218 // See if the top visible activity is waiting to run in this process... 5219 if (normalMode) { 5220 try { 5221 if (mStackSupervisor.attachApplicationLocked(app)) { 5222 didSomething = true; 5223 } 5224 } catch (Exception e) { 5225 badApp = true; 5226 } 5227 } 5228 5229 // Find any services that should be running in this process... 5230 if (!badApp) { 5231 try { 5232 didSomething |= mServices.attachApplicationLocked(app, processName); 5233 } catch (Exception e) { 5234 badApp = true; 5235 } 5236 } 5237 5238 // Check if a next-broadcast receiver is in this process... 5239 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5240 try { 5241 didSomething |= sendPendingBroadcastsLocked(app); 5242 } catch (Exception e) { 5243 // If the app died trying to launch the receiver we declare it 'bad' 5244 badApp = true; 5245 } 5246 } 5247 5248 // Check whether the next backup agent is in this process... 5249 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5250 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5251 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5252 try { 5253 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5254 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5255 mBackupTarget.backupMode); 5256 } catch (Exception e) { 5257 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5258 e.printStackTrace(); 5259 } 5260 } 5261 5262 if (badApp) { 5263 // todo: Also need to kill application to deal with all 5264 // kinds of exceptions. 5265 handleAppDiedLocked(app, false, true); 5266 return false; 5267 } 5268 5269 if (!didSomething) { 5270 updateOomAdjLocked(); 5271 } 5272 5273 return true; 5274 } 5275 5276 @Override 5277 public final void attachApplication(IApplicationThread thread) { 5278 synchronized (this) { 5279 int callingPid = Binder.getCallingPid(); 5280 final long origId = Binder.clearCallingIdentity(); 5281 attachApplicationLocked(thread, callingPid); 5282 Binder.restoreCallingIdentity(origId); 5283 } 5284 } 5285 5286 @Override 5287 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5288 final long origId = Binder.clearCallingIdentity(); 5289 synchronized (this) { 5290 ActivityStack stack = ActivityRecord.getStackLocked(token); 5291 if (stack != null) { 5292 ActivityRecord r = 5293 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5294 if (stopProfiling) { 5295 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5296 try { 5297 mProfileFd.close(); 5298 } catch (IOException e) { 5299 } 5300 clearProfilerLocked(); 5301 } 5302 } 5303 } 5304 } 5305 Binder.restoreCallingIdentity(origId); 5306 } 5307 5308 void enableScreenAfterBoot() { 5309 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5310 SystemClock.uptimeMillis()); 5311 mWindowManager.enableScreenAfterBoot(); 5312 5313 synchronized (this) { 5314 updateEventDispatchingLocked(); 5315 } 5316 } 5317 5318 @Override 5319 public void showBootMessage(final CharSequence msg, final boolean always) { 5320 enforceNotIsolatedCaller("showBootMessage"); 5321 mWindowManager.showBootMessage(msg, always); 5322 } 5323 5324 @Override 5325 public void dismissKeyguardOnNextActivity() { 5326 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5327 final long token = Binder.clearCallingIdentity(); 5328 try { 5329 synchronized (this) { 5330 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5331 if (mLockScreenShown) { 5332 mLockScreenShown = false; 5333 comeOutOfSleepIfNeededLocked(); 5334 } 5335 mStackSupervisor.setDismissKeyguard(true); 5336 } 5337 } finally { 5338 Binder.restoreCallingIdentity(token); 5339 } 5340 } 5341 5342 final void finishBooting() { 5343 // Register receivers to handle package update events 5344 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5345 5346 synchronized (this) { 5347 // Ensure that any processes we had put on hold are now started 5348 // up. 5349 final int NP = mProcessesOnHold.size(); 5350 if (NP > 0) { 5351 ArrayList<ProcessRecord> procs = 5352 new ArrayList<ProcessRecord>(mProcessesOnHold); 5353 for (int ip=0; ip<NP; ip++) { 5354 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5355 + procs.get(ip)); 5356 startProcessLocked(procs.get(ip), "on-hold", null); 5357 } 5358 } 5359 5360 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5361 // Start looking for apps that are abusing wake locks. 5362 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5363 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5364 // Tell anyone interested that we are done booting! 5365 SystemProperties.set("sys.boot_completed", "1"); 5366 SystemProperties.set("dev.bootcomplete", "1"); 5367 for (int i=0; i<mStartedUsers.size(); i++) { 5368 UserStartedState uss = mStartedUsers.valueAt(i); 5369 if (uss.mState == UserStartedState.STATE_BOOTING) { 5370 uss.mState = UserStartedState.STATE_RUNNING; 5371 final int userId = mStartedUsers.keyAt(i); 5372 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5373 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5374 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5375 broadcastIntentLocked(null, null, intent, null, 5376 new IIntentReceiver.Stub() { 5377 @Override 5378 public void performReceive(Intent intent, int resultCode, 5379 String data, Bundle extras, boolean ordered, 5380 boolean sticky, int sendingUser) { 5381 synchronized (ActivityManagerService.this) { 5382 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5383 true, false); 5384 } 5385 } 5386 }, 5387 0, null, null, 5388 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5389 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5390 userId); 5391 } 5392 } 5393 scheduleStartProfilesLocked(); 5394 } 5395 } 5396 } 5397 5398 final void ensureBootCompleted() { 5399 boolean booting; 5400 boolean enableScreen; 5401 synchronized (this) { 5402 booting = mBooting; 5403 mBooting = false; 5404 enableScreen = !mBooted; 5405 mBooted = true; 5406 } 5407 5408 if (booting) { 5409 finishBooting(); 5410 } 5411 5412 if (enableScreen) { 5413 enableScreenAfterBoot(); 5414 } 5415 } 5416 5417 @Override 5418 public final void activityResumed(IBinder token) { 5419 final long origId = Binder.clearCallingIdentity(); 5420 synchronized(this) { 5421 ActivityStack stack = ActivityRecord.getStackLocked(token); 5422 if (stack != null) { 5423 ActivityRecord.activityResumedLocked(token); 5424 } 5425 } 5426 Binder.restoreCallingIdentity(origId); 5427 } 5428 5429 @Override 5430 public final void activityPaused(IBinder token) { 5431 final long origId = Binder.clearCallingIdentity(); 5432 synchronized(this) { 5433 ActivityStack stack = ActivityRecord.getStackLocked(token); 5434 if (stack != null) { 5435 stack.activityPausedLocked(token, false); 5436 } 5437 } 5438 Binder.restoreCallingIdentity(origId); 5439 } 5440 5441 @Override 5442 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5443 CharSequence description) { 5444 if (localLOGV) Slog.v( 5445 TAG, "Activity stopped: token=" + token); 5446 5447 // Refuse possible leaked file descriptors 5448 if (icicle != null && icicle.hasFileDescriptors()) { 5449 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5450 } 5451 5452 final long origId = Binder.clearCallingIdentity(); 5453 5454 synchronized (this) { 5455 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5456 if (r != null) { 5457 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5458 } 5459 } 5460 5461 trimApplications(); 5462 5463 Binder.restoreCallingIdentity(origId); 5464 } 5465 5466 @Override 5467 public final void activityDestroyed(IBinder token) { 5468 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5469 synchronized (this) { 5470 ActivityStack stack = ActivityRecord.getStackLocked(token); 5471 if (stack != null) { 5472 stack.activityDestroyedLocked(token); 5473 } 5474 } 5475 } 5476 5477 @Override 5478 public String getCallingPackage(IBinder token) { 5479 synchronized (this) { 5480 ActivityRecord r = getCallingRecordLocked(token); 5481 return r != null ? r.info.packageName : null; 5482 } 5483 } 5484 5485 @Override 5486 public ComponentName getCallingActivity(IBinder token) { 5487 synchronized (this) { 5488 ActivityRecord r = getCallingRecordLocked(token); 5489 return r != null ? r.intent.getComponent() : null; 5490 } 5491 } 5492 5493 private ActivityRecord getCallingRecordLocked(IBinder token) { 5494 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5495 if (r == null) { 5496 return null; 5497 } 5498 return r.resultTo; 5499 } 5500 5501 @Override 5502 public ComponentName getActivityClassForToken(IBinder token) { 5503 synchronized(this) { 5504 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5505 if (r == null) { 5506 return null; 5507 } 5508 return r.intent.getComponent(); 5509 } 5510 } 5511 5512 @Override 5513 public String getPackageForToken(IBinder token) { 5514 synchronized(this) { 5515 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5516 if (r == null) { 5517 return null; 5518 } 5519 return r.packageName; 5520 } 5521 } 5522 5523 @Override 5524 public IIntentSender getIntentSender(int type, 5525 String packageName, IBinder token, String resultWho, 5526 int requestCode, Intent[] intents, String[] resolvedTypes, 5527 int flags, Bundle options, int userId) { 5528 enforceNotIsolatedCaller("getIntentSender"); 5529 // Refuse possible leaked file descriptors 5530 if (intents != null) { 5531 if (intents.length < 1) { 5532 throw new IllegalArgumentException("Intents array length must be >= 1"); 5533 } 5534 for (int i=0; i<intents.length; i++) { 5535 Intent intent = intents[i]; 5536 if (intent != null) { 5537 if (intent.hasFileDescriptors()) { 5538 throw new IllegalArgumentException("File descriptors passed in Intent"); 5539 } 5540 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5541 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5542 throw new IllegalArgumentException( 5543 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5544 } 5545 intents[i] = new Intent(intent); 5546 } 5547 } 5548 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5549 throw new IllegalArgumentException( 5550 "Intent array length does not match resolvedTypes length"); 5551 } 5552 } 5553 if (options != null) { 5554 if (options.hasFileDescriptors()) { 5555 throw new IllegalArgumentException("File descriptors passed in options"); 5556 } 5557 } 5558 5559 synchronized(this) { 5560 int callingUid = Binder.getCallingUid(); 5561 int origUserId = userId; 5562 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5563 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5564 "getIntentSender", null); 5565 if (origUserId == UserHandle.USER_CURRENT) { 5566 // We don't want to evaluate this until the pending intent is 5567 // actually executed. However, we do want to always do the 5568 // security checking for it above. 5569 userId = UserHandle.USER_CURRENT; 5570 } 5571 try { 5572 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5573 int uid = AppGlobals.getPackageManager() 5574 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5575 if (!UserHandle.isSameApp(callingUid, uid)) { 5576 String msg = "Permission Denial: getIntentSender() from pid=" 5577 + Binder.getCallingPid() 5578 + ", uid=" + Binder.getCallingUid() 5579 + ", (need uid=" + uid + ")" 5580 + " is not allowed to send as package " + packageName; 5581 Slog.w(TAG, msg); 5582 throw new SecurityException(msg); 5583 } 5584 } 5585 5586 return getIntentSenderLocked(type, packageName, callingUid, userId, 5587 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5588 5589 } catch (RemoteException e) { 5590 throw new SecurityException(e); 5591 } 5592 } 5593 } 5594 5595 IIntentSender getIntentSenderLocked(int type, String packageName, 5596 int callingUid, int userId, IBinder token, String resultWho, 5597 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5598 Bundle options) { 5599 if (DEBUG_MU) 5600 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5601 ActivityRecord activity = null; 5602 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5603 activity = ActivityRecord.isInStackLocked(token); 5604 if (activity == null) { 5605 return null; 5606 } 5607 if (activity.finishing) { 5608 return null; 5609 } 5610 } 5611 5612 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5613 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5614 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5615 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5616 |PendingIntent.FLAG_UPDATE_CURRENT); 5617 5618 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5619 type, packageName, activity, resultWho, 5620 requestCode, intents, resolvedTypes, flags, options, userId); 5621 WeakReference<PendingIntentRecord> ref; 5622 ref = mIntentSenderRecords.get(key); 5623 PendingIntentRecord rec = ref != null ? ref.get() : null; 5624 if (rec != null) { 5625 if (!cancelCurrent) { 5626 if (updateCurrent) { 5627 if (rec.key.requestIntent != null) { 5628 rec.key.requestIntent.replaceExtras(intents != null ? 5629 intents[intents.length - 1] : null); 5630 } 5631 if (intents != null) { 5632 intents[intents.length-1] = rec.key.requestIntent; 5633 rec.key.allIntents = intents; 5634 rec.key.allResolvedTypes = resolvedTypes; 5635 } else { 5636 rec.key.allIntents = null; 5637 rec.key.allResolvedTypes = null; 5638 } 5639 } 5640 return rec; 5641 } 5642 rec.canceled = true; 5643 mIntentSenderRecords.remove(key); 5644 } 5645 if (noCreate) { 5646 return rec; 5647 } 5648 rec = new PendingIntentRecord(this, key, callingUid); 5649 mIntentSenderRecords.put(key, rec.ref); 5650 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5651 if (activity.pendingResults == null) { 5652 activity.pendingResults 5653 = new HashSet<WeakReference<PendingIntentRecord>>(); 5654 } 5655 activity.pendingResults.add(rec.ref); 5656 } 5657 return rec; 5658 } 5659 5660 @Override 5661 public void cancelIntentSender(IIntentSender sender) { 5662 if (!(sender instanceof PendingIntentRecord)) { 5663 return; 5664 } 5665 synchronized(this) { 5666 PendingIntentRecord rec = (PendingIntentRecord)sender; 5667 try { 5668 int uid = AppGlobals.getPackageManager() 5669 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5670 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5671 String msg = "Permission Denial: cancelIntentSender() from pid=" 5672 + Binder.getCallingPid() 5673 + ", uid=" + Binder.getCallingUid() 5674 + " is not allowed to cancel packges " 5675 + rec.key.packageName; 5676 Slog.w(TAG, msg); 5677 throw new SecurityException(msg); 5678 } 5679 } catch (RemoteException e) { 5680 throw new SecurityException(e); 5681 } 5682 cancelIntentSenderLocked(rec, true); 5683 } 5684 } 5685 5686 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5687 rec.canceled = true; 5688 mIntentSenderRecords.remove(rec.key); 5689 if (cleanActivity && rec.key.activity != null) { 5690 rec.key.activity.pendingResults.remove(rec.ref); 5691 } 5692 } 5693 5694 @Override 5695 public String getPackageForIntentSender(IIntentSender pendingResult) { 5696 if (!(pendingResult instanceof PendingIntentRecord)) { 5697 return null; 5698 } 5699 try { 5700 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5701 return res.key.packageName; 5702 } catch (ClassCastException e) { 5703 } 5704 return null; 5705 } 5706 5707 @Override 5708 public int getUidForIntentSender(IIntentSender sender) { 5709 if (sender instanceof PendingIntentRecord) { 5710 try { 5711 PendingIntentRecord res = (PendingIntentRecord)sender; 5712 return res.uid; 5713 } catch (ClassCastException e) { 5714 } 5715 } 5716 return -1; 5717 } 5718 5719 @Override 5720 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5721 if (!(pendingResult instanceof PendingIntentRecord)) { 5722 return false; 5723 } 5724 try { 5725 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5726 if (res.key.allIntents == null) { 5727 return false; 5728 } 5729 for (int i=0; i<res.key.allIntents.length; i++) { 5730 Intent intent = res.key.allIntents[i]; 5731 if (intent.getPackage() != null && intent.getComponent() != null) { 5732 return false; 5733 } 5734 } 5735 return true; 5736 } catch (ClassCastException e) { 5737 } 5738 return false; 5739 } 5740 5741 @Override 5742 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5743 if (!(pendingResult instanceof PendingIntentRecord)) { 5744 return false; 5745 } 5746 try { 5747 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5748 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5749 return true; 5750 } 5751 return false; 5752 } catch (ClassCastException e) { 5753 } 5754 return false; 5755 } 5756 5757 @Override 5758 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5759 if (!(pendingResult instanceof PendingIntentRecord)) { 5760 return null; 5761 } 5762 try { 5763 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5764 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5765 } catch (ClassCastException e) { 5766 } 5767 return null; 5768 } 5769 5770 @Override 5771 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5772 if (!(pendingResult instanceof PendingIntentRecord)) { 5773 return null; 5774 } 5775 try { 5776 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5777 Intent intent = res.key.requestIntent; 5778 if (intent != null) { 5779 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5780 || res.lastTagPrefix.equals(prefix))) { 5781 return res.lastTag; 5782 } 5783 res.lastTagPrefix = prefix; 5784 StringBuilder sb = new StringBuilder(128); 5785 if (prefix != null) { 5786 sb.append(prefix); 5787 } 5788 if (intent.getAction() != null) { 5789 sb.append(intent.getAction()); 5790 } else if (intent.getComponent() != null) { 5791 intent.getComponent().appendShortString(sb); 5792 } else { 5793 sb.append("?"); 5794 } 5795 return res.lastTag = sb.toString(); 5796 } 5797 } catch (ClassCastException e) { 5798 } 5799 return null; 5800 } 5801 5802 @Override 5803 public void setProcessLimit(int max) { 5804 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5805 "setProcessLimit()"); 5806 synchronized (this) { 5807 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5808 mProcessLimitOverride = max; 5809 } 5810 trimApplications(); 5811 } 5812 5813 @Override 5814 public int getProcessLimit() { 5815 synchronized (this) { 5816 return mProcessLimitOverride; 5817 } 5818 } 5819 5820 void foregroundTokenDied(ForegroundToken token) { 5821 synchronized (ActivityManagerService.this) { 5822 synchronized (mPidsSelfLocked) { 5823 ForegroundToken cur 5824 = mForegroundProcesses.get(token.pid); 5825 if (cur != token) { 5826 return; 5827 } 5828 mForegroundProcesses.remove(token.pid); 5829 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5830 if (pr == null) { 5831 return; 5832 } 5833 pr.forcingToForeground = null; 5834 updateProcessForegroundLocked(pr, false, false); 5835 } 5836 updateOomAdjLocked(); 5837 } 5838 } 5839 5840 @Override 5841 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5842 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5843 "setProcessForeground()"); 5844 synchronized(this) { 5845 boolean changed = false; 5846 5847 synchronized (mPidsSelfLocked) { 5848 ProcessRecord pr = mPidsSelfLocked.get(pid); 5849 if (pr == null && isForeground) { 5850 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5851 return; 5852 } 5853 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5854 if (oldToken != null) { 5855 oldToken.token.unlinkToDeath(oldToken, 0); 5856 mForegroundProcesses.remove(pid); 5857 if (pr != null) { 5858 pr.forcingToForeground = null; 5859 } 5860 changed = true; 5861 } 5862 if (isForeground && token != null) { 5863 ForegroundToken newToken = new ForegroundToken() { 5864 @Override 5865 public void binderDied() { 5866 foregroundTokenDied(this); 5867 } 5868 }; 5869 newToken.pid = pid; 5870 newToken.token = token; 5871 try { 5872 token.linkToDeath(newToken, 0); 5873 mForegroundProcesses.put(pid, newToken); 5874 pr.forcingToForeground = token; 5875 changed = true; 5876 } catch (RemoteException e) { 5877 // If the process died while doing this, we will later 5878 // do the cleanup with the process death link. 5879 } 5880 } 5881 } 5882 5883 if (changed) { 5884 updateOomAdjLocked(); 5885 } 5886 } 5887 } 5888 5889 // ========================================================= 5890 // PERMISSIONS 5891 // ========================================================= 5892 5893 static class PermissionController extends IPermissionController.Stub { 5894 ActivityManagerService mActivityManagerService; 5895 PermissionController(ActivityManagerService activityManagerService) { 5896 mActivityManagerService = activityManagerService; 5897 } 5898 5899 @Override 5900 public boolean checkPermission(String permission, int pid, int uid) { 5901 return mActivityManagerService.checkPermission(permission, pid, 5902 uid) == PackageManager.PERMISSION_GRANTED; 5903 } 5904 } 5905 5906 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5907 @Override 5908 public int checkComponentPermission(String permission, int pid, int uid, 5909 int owningUid, boolean exported) { 5910 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5911 owningUid, exported); 5912 } 5913 5914 @Override 5915 public Object getAMSLock() { 5916 return ActivityManagerService.this; 5917 } 5918 } 5919 5920 /** 5921 * This can be called with or without the global lock held. 5922 */ 5923 int checkComponentPermission(String permission, int pid, int uid, 5924 int owningUid, boolean exported) { 5925 // We might be performing an operation on behalf of an indirect binder 5926 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5927 // client identity accordingly before proceeding. 5928 Identity tlsIdentity = sCallerIdentity.get(); 5929 if (tlsIdentity != null) { 5930 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5931 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5932 uid = tlsIdentity.uid; 5933 pid = tlsIdentity.pid; 5934 } 5935 5936 if (pid == MY_PID) { 5937 return PackageManager.PERMISSION_GRANTED; 5938 } 5939 5940 return ActivityManager.checkComponentPermission(permission, uid, 5941 owningUid, exported); 5942 } 5943 5944 /** 5945 * As the only public entry point for permissions checking, this method 5946 * can enforce the semantic that requesting a check on a null global 5947 * permission is automatically denied. (Internally a null permission 5948 * string is used when calling {@link #checkComponentPermission} in cases 5949 * when only uid-based security is needed.) 5950 * 5951 * This can be called with or without the global lock held. 5952 */ 5953 @Override 5954 public int checkPermission(String permission, int pid, int uid) { 5955 if (permission == null) { 5956 return PackageManager.PERMISSION_DENIED; 5957 } 5958 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5959 } 5960 5961 /** 5962 * Binder IPC calls go through the public entry point. 5963 * This can be called with or without the global lock held. 5964 */ 5965 int checkCallingPermission(String permission) { 5966 return checkPermission(permission, 5967 Binder.getCallingPid(), 5968 UserHandle.getAppId(Binder.getCallingUid())); 5969 } 5970 5971 /** 5972 * This can be called with or without the global lock held. 5973 */ 5974 void enforceCallingPermission(String permission, String func) { 5975 if (checkCallingPermission(permission) 5976 == PackageManager.PERMISSION_GRANTED) { 5977 return; 5978 } 5979 5980 String msg = "Permission Denial: " + func + " from pid=" 5981 + Binder.getCallingPid() 5982 + ", uid=" + Binder.getCallingUid() 5983 + " requires " + permission; 5984 Slog.w(TAG, msg); 5985 throw new SecurityException(msg); 5986 } 5987 5988 /** 5989 * Determine if UID is holding permissions required to access {@link Uri} in 5990 * the given {@link ProviderInfo}. Final permission checking is always done 5991 * in {@link ContentProvider}. 5992 */ 5993 private final boolean checkHoldingPermissionsLocked( 5994 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) { 5995 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5996 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5997 5998 if (pi.applicationInfo.uid == uid) { 5999 return true; 6000 } else if (!pi.exported) { 6001 return false; 6002 } 6003 6004 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6005 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6006 try { 6007 // check if target holds top-level <provider> permissions 6008 if (!readMet && pi.readPermission != null 6009 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6010 readMet = true; 6011 } 6012 if (!writeMet && pi.writePermission != null 6013 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6014 writeMet = true; 6015 } 6016 6017 // track if unprotected read/write is allowed; any denied 6018 // <path-permission> below removes this ability 6019 boolean allowDefaultRead = pi.readPermission == null; 6020 boolean allowDefaultWrite = pi.writePermission == null; 6021 6022 // check if target holds any <path-permission> that match uri 6023 final PathPermission[] pps = pi.pathPermissions; 6024 if (pps != null) { 6025 final String path = uri.getPath(); 6026 int i = pps.length; 6027 while (i > 0 && (!readMet || !writeMet)) { 6028 i--; 6029 PathPermission pp = pps[i]; 6030 if (pp.match(path)) { 6031 if (!readMet) { 6032 final String pprperm = pp.getReadPermission(); 6033 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6034 + pprperm + " for " + pp.getPath() 6035 + ": match=" + pp.match(path) 6036 + " check=" + pm.checkUidPermission(pprperm, uid)); 6037 if (pprperm != null) { 6038 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 6039 readMet = true; 6040 } else { 6041 allowDefaultRead = false; 6042 } 6043 } 6044 } 6045 if (!writeMet) { 6046 final String ppwperm = pp.getWritePermission(); 6047 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6048 + ppwperm + " for " + pp.getPath() 6049 + ": match=" + pp.match(path) 6050 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6051 if (ppwperm != null) { 6052 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 6053 writeMet = true; 6054 } else { 6055 allowDefaultWrite = false; 6056 } 6057 } 6058 } 6059 } 6060 } 6061 } 6062 6063 // grant unprotected <provider> read/write, if not blocked by 6064 // <path-permission> above 6065 if (allowDefaultRead) readMet = true; 6066 if (allowDefaultWrite) writeMet = true; 6067 6068 } catch (RemoteException e) { 6069 return false; 6070 } 6071 6072 return readMet && writeMet; 6073 } 6074 6075 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6076 ProviderInfo pi = null; 6077 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6078 if (cpr != null) { 6079 pi = cpr.info; 6080 } else { 6081 try { 6082 pi = AppGlobals.getPackageManager().resolveContentProvider( 6083 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6084 } catch (RemoteException ex) { 6085 } 6086 } 6087 return pi; 6088 } 6089 6090 private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) { 6091 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6092 if (targetUris != null) { 6093 return targetUris.get(uri); 6094 } 6095 return null; 6096 } 6097 6098 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6099 String targetPkg, int targetUid, GrantUri uri) { 6100 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6101 if (targetUris == null) { 6102 targetUris = Maps.newArrayMap(); 6103 mGrantedUriPermissions.put(targetUid, targetUris); 6104 } 6105 6106 UriPermission perm = targetUris.get(uri); 6107 if (perm == null) { 6108 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 6109 targetUris.put(uri, perm); 6110 } 6111 6112 return perm; 6113 } 6114 6115 private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) { 6116 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6117 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6118 : UriPermission.STRENGTH_OWNED; 6119 6120 // Root gets to do everything. 6121 if (uid == 0) { 6122 return true; 6123 } 6124 6125 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6126 if (perms == null) return false; 6127 6128 // First look for exact match 6129 final UriPermission exactPerm = perms.get(new GrantUri(uri, false)); 6130 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6131 return true; 6132 } 6133 6134 // No exact match, look for prefixes 6135 final int N = perms.size(); 6136 for (int i = 0; i < N; i++) { 6137 final UriPermission perm = perms.valueAt(i); 6138 if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri) 6139 && perm.getStrength(modeFlags) >= minStrength) { 6140 return true; 6141 } 6142 } 6143 6144 return false; 6145 } 6146 6147 @Override 6148 public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) { 6149 enforceNotIsolatedCaller("checkUriPermission"); 6150 6151 // Another redirected-binder-call permissions check as in 6152 // {@link checkComponentPermission}. 6153 Identity tlsIdentity = sCallerIdentity.get(); 6154 if (tlsIdentity != null) { 6155 uid = tlsIdentity.uid; 6156 pid = tlsIdentity.pid; 6157 } 6158 6159 // Our own process gets to do everything. 6160 if (pid == MY_PID) { 6161 return PackageManager.PERMISSION_GRANTED; 6162 } 6163 synchronized (this) { 6164 return checkUriPermissionLocked(uri, uid, modeFlags) 6165 ? PackageManager.PERMISSION_GRANTED 6166 : PackageManager.PERMISSION_DENIED; 6167 } 6168 } 6169 6170 /** 6171 * Check if the targetPkg can be granted permission to access uri by 6172 * the callingUid using the given modeFlags. Throws a security exception 6173 * if callingUid is not allowed to do this. Returns the uid of the target 6174 * if the URI permission grant should be performed; returns -1 if it is not 6175 * needed (for example targetPkg already has permission to access the URI). 6176 * If you already know the uid of the target, you can supply it in 6177 * lastTargetUid else set that to -1. 6178 */ 6179 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 6180 Uri uri, final int modeFlags, int lastTargetUid) { 6181 if (!Intent.isAccessUriMode(modeFlags)) { 6182 return -1; 6183 } 6184 6185 if (targetPkg != null) { 6186 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6187 "Checking grant " + targetPkg + " permission to " + uri); 6188 } 6189 6190 final IPackageManager pm = AppGlobals.getPackageManager(); 6191 6192 // If this is not a content: uri, we can't do anything with it. 6193 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 6194 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6195 "Can't grant URI permission for non-content URI: " + uri); 6196 return -1; 6197 } 6198 6199 final String authority = uri.getAuthority(); 6200 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6201 if (pi == null) { 6202 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 6203 return -1; 6204 } 6205 6206 int targetUid = lastTargetUid; 6207 if (targetUid < 0 && targetPkg != null) { 6208 try { 6209 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6210 if (targetUid < 0) { 6211 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6212 "Can't grant URI permission no uid for: " + targetPkg); 6213 return -1; 6214 } 6215 } catch (RemoteException ex) { 6216 return -1; 6217 } 6218 } 6219 6220 if (targetUid >= 0) { 6221 // First... does the target actually need this permission? 6222 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 6223 // No need to grant the target this permission. 6224 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6225 "Target " + targetPkg + " already has full permission to " + uri); 6226 return -1; 6227 } 6228 } else { 6229 // First... there is no target package, so can anyone access it? 6230 boolean allowed = pi.exported; 6231 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6232 if (pi.readPermission != null) { 6233 allowed = false; 6234 } 6235 } 6236 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6237 if (pi.writePermission != null) { 6238 allowed = false; 6239 } 6240 } 6241 if (allowed) { 6242 return -1; 6243 } 6244 } 6245 6246 // Second... is the provider allowing granting of URI permissions? 6247 if (!pi.grantUriPermissions) { 6248 throw new SecurityException("Provider " + pi.packageName 6249 + "/" + pi.name 6250 + " does not allow granting of Uri permissions (uri " 6251 + uri + ")"); 6252 } 6253 if (pi.uriPermissionPatterns != null) { 6254 final int N = pi.uriPermissionPatterns.length; 6255 boolean allowed = false; 6256 for (int i=0; i<N; i++) { 6257 if (pi.uriPermissionPatterns[i] != null 6258 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6259 allowed = true; 6260 break; 6261 } 6262 } 6263 if (!allowed) { 6264 throw new SecurityException("Provider " + pi.packageName 6265 + "/" + pi.name 6266 + " does not allow granting of permission to path of Uri " 6267 + uri); 6268 } 6269 } 6270 6271 // Third... does the caller itself have permission to access 6272 // this uri? 6273 if (callingUid != Process.myUid()) { 6274 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6275 // Require they hold a strong enough Uri permission 6276 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6277 throw new SecurityException("Uid " + callingUid 6278 + " does not have permission to uri " + uri); 6279 } 6280 } 6281 } 6282 6283 return targetUid; 6284 } 6285 6286 @Override 6287 public int checkGrantUriPermission(int callingUid, String targetPkg, 6288 Uri uri, final int modeFlags) { 6289 enforceNotIsolatedCaller("checkGrantUriPermission"); 6290 synchronized(this) { 6291 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6292 } 6293 } 6294 6295 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri, 6296 final int modeFlags, UriPermissionOwner owner) { 6297 if (!Intent.isAccessUriMode(modeFlags)) { 6298 return; 6299 } 6300 6301 // So here we are: the caller has the assumed permission 6302 // to the uri, and the target doesn't. Let's now give this to 6303 // the target. 6304 6305 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6306 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6307 6308 final String authority = uri.getAuthority(); 6309 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6310 if (pi == null) { 6311 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6312 return; 6313 } 6314 6315 final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0; 6316 final UriPermission perm = findOrCreateUriPermissionLocked( 6317 pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix)); 6318 perm.grantModes(modeFlags, owner); 6319 } 6320 6321 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6322 final int modeFlags, UriPermissionOwner owner) { 6323 if (targetPkg == null) { 6324 throw new NullPointerException("targetPkg"); 6325 } 6326 6327 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6328 if (targetUid < 0) { 6329 return; 6330 } 6331 6332 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6333 } 6334 6335 static class NeededUriGrants extends ArrayList<Uri> { 6336 final String targetPkg; 6337 final int targetUid; 6338 final int flags; 6339 6340 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6341 this.targetPkg = targetPkg; 6342 this.targetUid = targetUid; 6343 this.flags = flags; 6344 } 6345 } 6346 6347 /** 6348 * Like checkGrantUriPermissionLocked, but takes an Intent. 6349 */ 6350 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6351 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6352 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6353 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6354 + " clip=" + (intent != null ? intent.getClipData() : null) 6355 + " from " + intent + "; flags=0x" 6356 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6357 6358 if (targetPkg == null) { 6359 throw new NullPointerException("targetPkg"); 6360 } 6361 6362 if (intent == null) { 6363 return null; 6364 } 6365 Uri data = intent.getData(); 6366 ClipData clip = intent.getClipData(); 6367 if (data == null && clip == null) { 6368 return null; 6369 } 6370 6371 if (data != null) { 6372 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6373 mode, needed != null ? needed.targetUid : -1); 6374 if (targetUid > 0) { 6375 if (needed == null) { 6376 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6377 } 6378 needed.add(data); 6379 } 6380 } 6381 if (clip != null) { 6382 for (int i=0; i<clip.getItemCount(); i++) { 6383 Uri uri = clip.getItemAt(i).getUri(); 6384 if (uri != null) { 6385 int targetUid = -1; 6386 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6387 mode, needed != null ? needed.targetUid : -1); 6388 if (targetUid > 0) { 6389 if (needed == null) { 6390 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6391 } 6392 needed.add(uri); 6393 } 6394 } else { 6395 Intent clipIntent = clip.getItemAt(i).getIntent(); 6396 if (clipIntent != null) { 6397 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6398 callingUid, targetPkg, clipIntent, mode, needed); 6399 if (newNeeded != null) { 6400 needed = newNeeded; 6401 } 6402 } 6403 } 6404 } 6405 } 6406 6407 return needed; 6408 } 6409 6410 /** 6411 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6412 */ 6413 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6414 UriPermissionOwner owner) { 6415 if (needed != null) { 6416 for (int i=0; i<needed.size(); i++) { 6417 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6418 needed.get(i), needed.flags, owner); 6419 } 6420 } 6421 } 6422 6423 void grantUriPermissionFromIntentLocked(int callingUid, 6424 String targetPkg, Intent intent, UriPermissionOwner owner) { 6425 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6426 intent, intent != null ? intent.getFlags() : 0, null); 6427 if (needed == null) { 6428 return; 6429 } 6430 6431 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6432 } 6433 6434 @Override 6435 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6436 Uri uri, final int modeFlags) { 6437 enforceNotIsolatedCaller("grantUriPermission"); 6438 synchronized(this) { 6439 final ProcessRecord r = getRecordForAppLocked(caller); 6440 if (r == null) { 6441 throw new SecurityException("Unable to find app for caller " 6442 + caller 6443 + " when granting permission to uri " + uri); 6444 } 6445 if (targetPkg == null) { 6446 throw new IllegalArgumentException("null target"); 6447 } 6448 if (uri == null) { 6449 throw new IllegalArgumentException("null uri"); 6450 } 6451 6452 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6453 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6454 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6455 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6456 6457 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null); 6458 } 6459 } 6460 6461 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6462 if (perm.modeFlags == 0) { 6463 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6464 perm.targetUid); 6465 if (perms != null) { 6466 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6467 "Removing " + perm.targetUid + " permission to " + perm.uri); 6468 6469 perms.remove(perm.uri); 6470 if (perms.isEmpty()) { 6471 mGrantedUriPermissions.remove(perm.targetUid); 6472 } 6473 } 6474 } 6475 } 6476 6477 private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) { 6478 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6479 6480 final IPackageManager pm = AppGlobals.getPackageManager(); 6481 final String authority = uri.getAuthority(); 6482 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6483 if (pi == null) { 6484 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6485 return; 6486 } 6487 6488 // Does the caller have this permission on the URI? 6489 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6490 // Right now, if you are not the original owner of the permission, 6491 // you are not allowed to revoke it. 6492 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6493 throw new SecurityException("Uid " + callingUid 6494 + " does not have permission to uri " + uri); 6495 //} 6496 } 6497 6498 boolean persistChanged = false; 6499 6500 // Go through all of the permissions and remove any that match. 6501 int N = mGrantedUriPermissions.size(); 6502 for (int i = 0; i < N; i++) { 6503 final int targetUid = mGrantedUriPermissions.keyAt(i); 6504 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6505 6506 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6507 final UriPermission perm = it.next(); 6508 if (perm.uri.uri.isPathPrefixMatch(uri)) { 6509 if (DEBUG_URI_PERMISSION) 6510 Slog.v(TAG, 6511 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6512 persistChanged |= perm.revokeModes( 6513 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6514 if (perm.modeFlags == 0) { 6515 it.remove(); 6516 } 6517 } 6518 } 6519 6520 if (perms.isEmpty()) { 6521 mGrantedUriPermissions.remove(targetUid); 6522 N--; 6523 i--; 6524 } 6525 } 6526 6527 if (persistChanged) { 6528 schedulePersistUriGrants(); 6529 } 6530 } 6531 6532 @Override 6533 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6534 final int modeFlags) { 6535 enforceNotIsolatedCaller("revokeUriPermission"); 6536 synchronized(this) { 6537 final ProcessRecord r = getRecordForAppLocked(caller); 6538 if (r == null) { 6539 throw new SecurityException("Unable to find app for caller " 6540 + caller 6541 + " when revoking permission to uri " + uri); 6542 } 6543 if (uri == null) { 6544 Slog.w(TAG, "revokeUriPermission: null uri"); 6545 return; 6546 } 6547 6548 if (!Intent.isAccessUriMode(modeFlags)) { 6549 return; 6550 } 6551 6552 final IPackageManager pm = AppGlobals.getPackageManager(); 6553 final String authority = uri.getAuthority(); 6554 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6555 if (pi == null) { 6556 Slog.w(TAG, "No content provider found for permission revoke: " 6557 + uri.toSafeString()); 6558 return; 6559 } 6560 6561 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6562 } 6563 } 6564 6565 /** 6566 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6567 * given package. 6568 * 6569 * @param packageName Package name to match, or {@code null} to apply to all 6570 * packages. 6571 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6572 * to all users. 6573 * @param persistable If persistable grants should be removed. 6574 */ 6575 private void removeUriPermissionsForPackageLocked( 6576 String packageName, int userHandle, boolean persistable) { 6577 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6578 throw new IllegalArgumentException("Must narrow by either package or user"); 6579 } 6580 6581 boolean persistChanged = false; 6582 6583 int N = mGrantedUriPermissions.size(); 6584 for (int i = 0; i < N; i++) { 6585 final int targetUid = mGrantedUriPermissions.keyAt(i); 6586 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6587 6588 // Only inspect grants matching user 6589 if (userHandle == UserHandle.USER_ALL 6590 || userHandle == UserHandle.getUserId(targetUid)) { 6591 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6592 final UriPermission perm = it.next(); 6593 6594 // Only inspect grants matching package 6595 if (packageName == null || perm.sourcePkg.equals(packageName) 6596 || perm.targetPkg.equals(packageName)) { 6597 persistChanged |= perm.revokeModes( 6598 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6599 6600 // Only remove when no modes remain; any persisted grants 6601 // will keep this alive. 6602 if (perm.modeFlags == 0) { 6603 it.remove(); 6604 } 6605 } 6606 } 6607 6608 if (perms.isEmpty()) { 6609 mGrantedUriPermissions.remove(targetUid); 6610 N--; 6611 i--; 6612 } 6613 } 6614 } 6615 6616 if (persistChanged) { 6617 schedulePersistUriGrants(); 6618 } 6619 } 6620 6621 @Override 6622 public IBinder newUriPermissionOwner(String name) { 6623 enforceNotIsolatedCaller("newUriPermissionOwner"); 6624 synchronized(this) { 6625 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6626 return owner.getExternalTokenLocked(); 6627 } 6628 } 6629 6630 @Override 6631 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6632 Uri uri, final int modeFlags) { 6633 synchronized(this) { 6634 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6635 if (owner == null) { 6636 throw new IllegalArgumentException("Unknown owner: " + token); 6637 } 6638 if (fromUid != Binder.getCallingUid()) { 6639 if (Binder.getCallingUid() != Process.myUid()) { 6640 // Only system code can grant URI permissions on behalf 6641 // of other users. 6642 throw new SecurityException("nice try"); 6643 } 6644 } 6645 if (targetPkg == null) { 6646 throw new IllegalArgumentException("null target"); 6647 } 6648 if (uri == null) { 6649 throw new IllegalArgumentException("null uri"); 6650 } 6651 6652 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6653 } 6654 } 6655 6656 @Override 6657 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6658 synchronized(this) { 6659 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6660 if (owner == null) { 6661 throw new IllegalArgumentException("Unknown owner: " + token); 6662 } 6663 6664 if (uri == null) { 6665 owner.removeUriPermissionsLocked(mode); 6666 } else { 6667 owner.removeUriPermissionLocked(uri, mode); 6668 } 6669 } 6670 } 6671 6672 private void schedulePersistUriGrants() { 6673 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6674 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6675 10 * DateUtils.SECOND_IN_MILLIS); 6676 } 6677 } 6678 6679 private void writeGrantedUriPermissions() { 6680 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6681 6682 // Snapshot permissions so we can persist without lock 6683 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6684 synchronized (this) { 6685 final int size = mGrantedUriPermissions.size(); 6686 for (int i = 0; i < size; i++) { 6687 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6688 for (UriPermission perm : perms.values()) { 6689 if (perm.persistedModeFlags != 0) { 6690 persist.add(perm.snapshot()); 6691 } 6692 } 6693 } 6694 } 6695 6696 FileOutputStream fos = null; 6697 try { 6698 fos = mGrantFile.startWrite(); 6699 6700 XmlSerializer out = new FastXmlSerializer(); 6701 out.setOutput(fos, "utf-8"); 6702 out.startDocument(null, true); 6703 out.startTag(null, TAG_URI_GRANTS); 6704 for (UriPermission.Snapshot perm : persist) { 6705 out.startTag(null, TAG_URI_GRANT); 6706 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6707 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6708 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6709 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6710 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6711 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6712 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6713 out.endTag(null, TAG_URI_GRANT); 6714 } 6715 out.endTag(null, TAG_URI_GRANTS); 6716 out.endDocument(); 6717 6718 mGrantFile.finishWrite(fos); 6719 } catch (IOException e) { 6720 if (fos != null) { 6721 mGrantFile.failWrite(fos); 6722 } 6723 } 6724 } 6725 6726 private void readGrantedUriPermissionsLocked() { 6727 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6728 6729 final long now = System.currentTimeMillis(); 6730 6731 FileInputStream fis = null; 6732 try { 6733 fis = mGrantFile.openRead(); 6734 final XmlPullParser in = Xml.newPullParser(); 6735 in.setInput(fis, null); 6736 6737 int type; 6738 while ((type = in.next()) != END_DOCUMENT) { 6739 final String tag = in.getName(); 6740 if (type == START_TAG) { 6741 if (TAG_URI_GRANT.equals(tag)) { 6742 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6743 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6744 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6745 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6746 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6747 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6748 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6749 6750 // Sanity check that provider still belongs to source package 6751 final ProviderInfo pi = getProviderInfoLocked( 6752 uri.getAuthority(), userHandle); 6753 if (pi != null && sourcePkg.equals(pi.packageName)) { 6754 int targetUid = -1; 6755 try { 6756 targetUid = AppGlobals.getPackageManager() 6757 .getPackageUid(targetPkg, userHandle); 6758 } catch (RemoteException e) { 6759 } 6760 if (targetUid != -1) { 6761 final UriPermission perm = findOrCreateUriPermissionLocked( 6762 sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix)); 6763 perm.initPersistedModes(modeFlags, createdTime); 6764 } 6765 } else { 6766 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6767 + " but instead found " + pi); 6768 } 6769 } 6770 } 6771 } 6772 } catch (FileNotFoundException e) { 6773 // Missing grants is okay 6774 } catch (IOException e) { 6775 Log.wtf(TAG, "Failed reading Uri grants", e); 6776 } catch (XmlPullParserException e) { 6777 Log.wtf(TAG, "Failed reading Uri grants", e); 6778 } finally { 6779 IoUtils.closeQuietly(fis); 6780 } 6781 } 6782 6783 @Override 6784 public void takePersistableUriPermission(Uri uri, final int modeFlags) { 6785 enforceNotIsolatedCaller("takePersistableUriPermission"); 6786 6787 Preconditions.checkFlagsArgument(modeFlags, 6788 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6789 6790 synchronized (this) { 6791 final int callingUid = Binder.getCallingUid(); 6792 boolean persistChanged = false; 6793 6794 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6795 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6796 6797 final boolean exactValid = (exactPerm != null) 6798 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6799 final boolean prefixValid = (prefixPerm != null) 6800 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6801 6802 if (!(exactValid || prefixValid)) { 6803 throw new SecurityException("No persistable permission grants found for UID " 6804 + callingUid + " and Uri " + uri.toSafeString()); 6805 } 6806 6807 if (exactValid) { 6808 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6809 } 6810 if (prefixValid) { 6811 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6812 } 6813 6814 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6815 6816 if (persistChanged) { 6817 schedulePersistUriGrants(); 6818 } 6819 } 6820 } 6821 6822 @Override 6823 public void releasePersistableUriPermission(Uri uri, final int modeFlags) { 6824 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6825 6826 Preconditions.checkFlagsArgument(modeFlags, 6827 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6828 6829 synchronized (this) { 6830 final int callingUid = Binder.getCallingUid(); 6831 boolean persistChanged = false; 6832 6833 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6834 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6835 if (exactPerm == null && prefixPerm == null) { 6836 throw new SecurityException("No permission grants found for UID " + callingUid 6837 + " and Uri " + uri.toSafeString()); 6838 } 6839 6840 if (exactPerm != null) { 6841 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6842 removeUriPermissionIfNeededLocked(exactPerm); 6843 } 6844 if (prefixPerm != null) { 6845 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6846 removeUriPermissionIfNeededLocked(prefixPerm); 6847 } 6848 6849 if (persistChanged) { 6850 schedulePersistUriGrants(); 6851 } 6852 } 6853 } 6854 6855 /** 6856 * Prune any older {@link UriPermission} for the given UID until outstanding 6857 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6858 * 6859 * @return if any mutations occured that require persisting. 6860 */ 6861 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6862 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6863 if (perms == null) return false; 6864 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6865 6866 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6867 for (UriPermission perm : perms.values()) { 6868 if (perm.persistedModeFlags != 0) { 6869 persisted.add(perm); 6870 } 6871 } 6872 6873 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6874 if (trimCount <= 0) return false; 6875 6876 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6877 for (int i = 0; i < trimCount; i++) { 6878 final UriPermission perm = persisted.get(i); 6879 6880 if (DEBUG_URI_PERMISSION) { 6881 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6882 } 6883 6884 perm.releasePersistableModes(~0); 6885 removeUriPermissionIfNeededLocked(perm); 6886 } 6887 6888 return true; 6889 } 6890 6891 @Override 6892 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6893 String packageName, boolean incoming) { 6894 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6895 Preconditions.checkNotNull(packageName, "packageName"); 6896 6897 final int callingUid = Binder.getCallingUid(); 6898 final IPackageManager pm = AppGlobals.getPackageManager(); 6899 try { 6900 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6901 if (packageUid != callingUid) { 6902 throw new SecurityException( 6903 "Package " + packageName + " does not belong to calling UID " + callingUid); 6904 } 6905 } catch (RemoteException e) { 6906 throw new SecurityException("Failed to verify package name ownership"); 6907 } 6908 6909 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6910 synchronized (this) { 6911 if (incoming) { 6912 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6913 callingUid); 6914 if (perms == null) { 6915 Slog.w(TAG, "No permission grants found for " + packageName); 6916 } else { 6917 for (UriPermission perm : perms.values()) { 6918 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6919 result.add(perm.buildPersistedPublicApiObject()); 6920 } 6921 } 6922 } 6923 } else { 6924 final int size = mGrantedUriPermissions.size(); 6925 for (int i = 0; i < size; i++) { 6926 final ArrayMap<GrantUri, UriPermission> perms = 6927 mGrantedUriPermissions.valueAt(i); 6928 for (UriPermission perm : perms.values()) { 6929 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6930 result.add(perm.buildPersistedPublicApiObject()); 6931 } 6932 } 6933 } 6934 } 6935 } 6936 return new ParceledListSlice<android.content.UriPermission>(result); 6937 } 6938 6939 @Override 6940 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6941 synchronized (this) { 6942 ProcessRecord app = 6943 who != null ? getRecordForAppLocked(who) : null; 6944 if (app == null) return; 6945 6946 Message msg = Message.obtain(); 6947 msg.what = WAIT_FOR_DEBUGGER_MSG; 6948 msg.obj = app; 6949 msg.arg1 = waiting ? 1 : 0; 6950 mHandler.sendMessage(msg); 6951 } 6952 } 6953 6954 @Override 6955 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6956 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6957 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6958 outInfo.availMem = Process.getFreeMemory(); 6959 outInfo.totalMem = Process.getTotalMemory(); 6960 outInfo.threshold = homeAppMem; 6961 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6962 outInfo.hiddenAppThreshold = cachedAppMem; 6963 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6964 ProcessList.SERVICE_ADJ); 6965 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6966 ProcessList.VISIBLE_APP_ADJ); 6967 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6968 ProcessList.FOREGROUND_APP_ADJ); 6969 } 6970 6971 // ========================================================= 6972 // TASK MANAGEMENT 6973 // ========================================================= 6974 6975 @Override 6976 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 6977 final int callingUid = Binder.getCallingUid(); 6978 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6979 6980 synchronized(this) { 6981 if (localLOGV) Slog.v( 6982 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 6983 6984 final boolean allowed = checkCallingPermission( 6985 android.Manifest.permission.GET_TASKS) 6986 == PackageManager.PERMISSION_GRANTED; 6987 if (!allowed) { 6988 Slog.w(TAG, "getTasks: caller " + callingUid 6989 + " does not hold GET_TASKS; limiting output"); 6990 } 6991 6992 // TODO: Improve with MRU list from all ActivityStacks. 6993 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 6994 } 6995 6996 return list; 6997 } 6998 6999 TaskRecord getMostRecentTask() { 7000 return mRecentTasks.get(0); 7001 } 7002 7003 @Override 7004 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7005 int flags, int userId) { 7006 final int callingUid = Binder.getCallingUid(); 7007 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7008 false, true, "getRecentTasks", null); 7009 7010 synchronized (this) { 7011 final boolean allowed = checkCallingPermission( 7012 android.Manifest.permission.GET_TASKS) 7013 == PackageManager.PERMISSION_GRANTED; 7014 if (!allowed) { 7015 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7016 + " does not hold GET_TASKS; limiting output"); 7017 } 7018 final boolean detailed = checkCallingPermission( 7019 android.Manifest.permission.GET_DETAILED_TASKS) 7020 == PackageManager.PERMISSION_GRANTED; 7021 7022 IPackageManager pm = AppGlobals.getPackageManager(); 7023 7024 final int N = mRecentTasks.size(); 7025 ArrayList<ActivityManager.RecentTaskInfo> res 7026 = new ArrayList<ActivityManager.RecentTaskInfo>( 7027 maxNum < N ? maxNum : N); 7028 7029 final Set<Integer> includedUsers; 7030 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7031 includedUsers = getProfileIdsLocked(userId); 7032 } else { 7033 includedUsers = new HashSet<Integer>(); 7034 } 7035 includedUsers.add(Integer.valueOf(userId)); 7036 for (int i=0; i<N && maxNum > 0; i++) { 7037 TaskRecord tr = mRecentTasks.get(i); 7038 // Only add calling user or related users recent tasks 7039 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7040 7041 // Return the entry if desired by the caller. We always return 7042 // the first entry, because callers always expect this to be the 7043 // foreground app. We may filter others if the caller has 7044 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7045 // we should exclude the entry. 7046 7047 if (i == 0 7048 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7049 || (tr.intent == null) 7050 || ((tr.intent.getFlags() 7051 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7052 if (!allowed) { 7053 // If the caller doesn't have the GET_TASKS permission, then only 7054 // allow them to see a small subset of tasks -- their own and home. 7055 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7056 continue; 7057 } 7058 } 7059 ActivityManager.RecentTaskInfo rti 7060 = new ActivityManager.RecentTaskInfo(); 7061 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 7062 rti.persistentId = tr.taskId; 7063 rti.baseIntent = new Intent( 7064 tr.intent != null ? tr.intent : tr.affinityIntent); 7065 if (!detailed) { 7066 rti.baseIntent.replaceExtras((Bundle)null); 7067 } 7068 rti.origActivity = tr.origActivity; 7069 rti.description = tr.lastDescription; 7070 rti.stackId = tr.stack.mStackId; 7071 rti.userId = tr.userId; 7072 7073 // Traverse upwards looking for any break between main task activities and 7074 // utility activities. 7075 final ArrayList<ActivityRecord> activities = tr.mActivities; 7076 int activityNdx; 7077 final int numActivities = activities.size(); 7078 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities; 7079 ++activityNdx) { 7080 final ActivityRecord r = activities.get(activityNdx); 7081 if (r.intent != null && 7082 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) 7083 != 0) { 7084 break; 7085 } 7086 } 7087 if (activityNdx > 0) { 7088 // Traverse downwards starting below break looking for set label, icon. 7089 // Note that if there are activities in the task but none of them set the 7090 // recent activity values, then we do not fall back to the last set 7091 // values in the TaskRecord. 7092 rti.activityValues = new ActivityManager.RecentsActivityValues(); 7093 for (--activityNdx; activityNdx >= 0; --activityNdx) { 7094 final ActivityRecord r = activities.get(activityNdx); 7095 if (r.activityValues != null) { 7096 if (rti.activityValues.label == null) { 7097 rti.activityValues.label = r.activityValues.label; 7098 tr.lastActivityValues.label = r.activityValues.label; 7099 } 7100 if (rti.activityValues.icon == null) { 7101 rti.activityValues.icon = r.activityValues.icon; 7102 tr.lastActivityValues.icon = r.activityValues.icon; 7103 } 7104 if (rti.activityValues.colorPrimary == 0) { 7105 rti.activityValues.colorPrimary = r.activityValues.colorPrimary; 7106 tr.lastActivityValues.colorPrimary = r.activityValues.colorPrimary; 7107 } 7108 } 7109 } 7110 } else { 7111 // If there are no activity records in this task, then we use the last 7112 // resolved values 7113 rti.activityValues = 7114 new ActivityManager.RecentsActivityValues(tr.lastActivityValues); 7115 } 7116 7117 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7118 // Check whether this activity is currently available. 7119 try { 7120 if (rti.origActivity != null) { 7121 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7122 == null) { 7123 continue; 7124 } 7125 } else if (rti.baseIntent != null) { 7126 if (pm.queryIntentActivities(rti.baseIntent, 7127 null, 0, userId) == null) { 7128 continue; 7129 } 7130 } 7131 } catch (RemoteException e) { 7132 // Will never happen. 7133 } 7134 } 7135 7136 res.add(rti); 7137 maxNum--; 7138 } 7139 } 7140 return res; 7141 } 7142 } 7143 7144 private TaskRecord recentTaskForIdLocked(int id) { 7145 final int N = mRecentTasks.size(); 7146 for (int i=0; i<N; i++) { 7147 TaskRecord tr = mRecentTasks.get(i); 7148 if (tr.taskId == id) { 7149 return tr; 7150 } 7151 } 7152 return null; 7153 } 7154 7155 @Override 7156 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7157 synchronized (this) { 7158 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7159 "getTaskThumbnails()"); 7160 TaskRecord tr = recentTaskForIdLocked(id); 7161 if (tr != null) { 7162 return tr.getTaskThumbnailsLocked(); 7163 } 7164 } 7165 return null; 7166 } 7167 7168 @Override 7169 public Bitmap getTaskTopThumbnail(int id) { 7170 synchronized (this) { 7171 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7172 "getTaskTopThumbnail()"); 7173 TaskRecord tr = recentTaskForIdLocked(id); 7174 if (tr != null) { 7175 return tr.getTaskTopThumbnailLocked(); 7176 } 7177 } 7178 return null; 7179 } 7180 7181 @Override 7182 public void setRecentsActivityValues(IBinder token, ActivityManager.RecentsActivityValues rav) { 7183 synchronized (this) { 7184 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7185 if (r != null) { 7186 r.activityValues = rav; 7187 } 7188 } 7189 } 7190 7191 @Override 7192 public boolean removeSubTask(int taskId, int subTaskIndex) { 7193 synchronized (this) { 7194 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7195 "removeSubTask()"); 7196 long ident = Binder.clearCallingIdentity(); 7197 try { 7198 TaskRecord tr = recentTaskForIdLocked(taskId); 7199 if (tr != null) { 7200 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7201 } 7202 return false; 7203 } finally { 7204 Binder.restoreCallingIdentity(ident); 7205 } 7206 } 7207 } 7208 7209 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7210 if (!pr.killedByAm) { 7211 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7212 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7213 pr.processName, pr.setAdj, reason); 7214 pr.killedByAm = true; 7215 Process.killProcessQuiet(pr.pid); 7216 } 7217 } 7218 7219 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7220 tr.disposeThumbnail(); 7221 mRecentTasks.remove(tr); 7222 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7223 Intent baseIntent = new Intent( 7224 tr.intent != null ? tr.intent : tr.affinityIntent); 7225 ComponentName component = baseIntent.getComponent(); 7226 if (component == null) { 7227 Slog.w(TAG, "Now component for base intent of task: " + tr); 7228 return; 7229 } 7230 7231 // Find any running services associated with this app. 7232 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7233 7234 if (killProcesses) { 7235 // Find any running processes associated with this app. 7236 final String pkg = component.getPackageName(); 7237 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7238 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7239 for (int i=0; i<pmap.size(); i++) { 7240 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7241 for (int j=0; j<uids.size(); j++) { 7242 ProcessRecord proc = uids.valueAt(j); 7243 if (proc.userId != tr.userId) { 7244 continue; 7245 } 7246 if (!proc.pkgList.containsKey(pkg)) { 7247 continue; 7248 } 7249 procs.add(proc); 7250 } 7251 } 7252 7253 // Kill the running processes. 7254 for (int i=0; i<procs.size(); i++) { 7255 ProcessRecord pr = procs.get(i); 7256 if (pr == mHomeProcess) { 7257 // Don't kill the home process along with tasks from the same package. 7258 continue; 7259 } 7260 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7261 killUnneededProcessLocked(pr, "remove task"); 7262 } else { 7263 pr.waitingToKill = "remove task"; 7264 } 7265 } 7266 } 7267 } 7268 7269 /** 7270 * Removes the task with the specified task id. 7271 * 7272 * @param taskId Identifier of the task to be removed. 7273 * @param flags Additional operational flags. May be 0 or 7274 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7275 * @return Returns true if the given task was found and removed. 7276 */ 7277 private boolean removeTaskByIdLocked(int taskId, int flags) { 7278 TaskRecord tr = recentTaskForIdLocked(taskId); 7279 if (tr != null) { 7280 tr.removeTaskActivitiesLocked(-1, false); 7281 cleanUpRemovedTaskLocked(tr, flags); 7282 return true; 7283 } 7284 return false; 7285 } 7286 7287 @Override 7288 public boolean removeTask(int taskId, int flags) { 7289 synchronized (this) { 7290 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7291 "removeTask()"); 7292 long ident = Binder.clearCallingIdentity(); 7293 try { 7294 return removeTaskByIdLocked(taskId, flags); 7295 } finally { 7296 Binder.restoreCallingIdentity(ident); 7297 } 7298 } 7299 } 7300 7301 /** 7302 * TODO: Add mController hook 7303 */ 7304 @Override 7305 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7306 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7307 "moveTaskToFront()"); 7308 7309 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7310 synchronized(this) { 7311 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7312 Binder.getCallingUid(), "Task to front")) { 7313 ActivityOptions.abort(options); 7314 return; 7315 } 7316 final long origId = Binder.clearCallingIdentity(); 7317 try { 7318 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7319 if (task == null) { 7320 return; 7321 } 7322 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7323 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7324 return; 7325 } 7326 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7327 } finally { 7328 Binder.restoreCallingIdentity(origId); 7329 } 7330 ActivityOptions.abort(options); 7331 } 7332 } 7333 7334 @Override 7335 public void moveTaskToBack(int taskId) { 7336 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7337 "moveTaskToBack()"); 7338 7339 synchronized(this) { 7340 TaskRecord tr = recentTaskForIdLocked(taskId); 7341 if (tr != null) { 7342 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7343 ActivityStack stack = tr.stack; 7344 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7345 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7346 Binder.getCallingUid(), "Task to back")) { 7347 return; 7348 } 7349 } 7350 final long origId = Binder.clearCallingIdentity(); 7351 try { 7352 stack.moveTaskToBackLocked(taskId, null); 7353 } finally { 7354 Binder.restoreCallingIdentity(origId); 7355 } 7356 } 7357 } 7358 } 7359 7360 /** 7361 * Moves an activity, and all of the other activities within the same task, to the bottom 7362 * of the history stack. The activity's order within the task is unchanged. 7363 * 7364 * @param token A reference to the activity we wish to move 7365 * @param nonRoot If false then this only works if the activity is the root 7366 * of a task; if true it will work for any activity in a task. 7367 * @return Returns true if the move completed, false if not. 7368 */ 7369 @Override 7370 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7371 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7372 synchronized(this) { 7373 final long origId = Binder.clearCallingIdentity(); 7374 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7375 if (taskId >= 0) { 7376 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7377 } 7378 Binder.restoreCallingIdentity(origId); 7379 } 7380 return false; 7381 } 7382 7383 @Override 7384 public void moveTaskBackwards(int task) { 7385 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7386 "moveTaskBackwards()"); 7387 7388 synchronized(this) { 7389 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7390 Binder.getCallingUid(), "Task backwards")) { 7391 return; 7392 } 7393 final long origId = Binder.clearCallingIdentity(); 7394 moveTaskBackwardsLocked(task); 7395 Binder.restoreCallingIdentity(origId); 7396 } 7397 } 7398 7399 private final void moveTaskBackwardsLocked(int task) { 7400 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7401 } 7402 7403 @Override 7404 public IBinder getHomeActivityToken() throws RemoteException { 7405 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7406 "getHomeActivityToken()"); 7407 synchronized (this) { 7408 return mStackSupervisor.getHomeActivityToken(); 7409 } 7410 } 7411 7412 @Override 7413 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7414 IActivityContainerCallback callback) throws RemoteException { 7415 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7416 "createActivityContainer()"); 7417 synchronized (this) { 7418 if (parentActivityToken == null) { 7419 throw new IllegalArgumentException("parent token must not be null"); 7420 } 7421 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7422 if (r == null) { 7423 return null; 7424 } 7425 if (callback == null) { 7426 throw new IllegalArgumentException("callback must not be null"); 7427 } 7428 return mStackSupervisor.createActivityContainer(r, callback); 7429 } 7430 } 7431 7432 @Override 7433 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7434 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7435 "deleteActivityContainer()"); 7436 synchronized (this) { 7437 mStackSupervisor.deleteActivityContainer(container); 7438 } 7439 } 7440 7441 @Override 7442 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7443 throws RemoteException { 7444 synchronized (this) { 7445 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7446 if (stack != null) { 7447 return stack.mActivityContainer; 7448 } 7449 return null; 7450 } 7451 } 7452 7453 @Override 7454 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7455 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7456 "moveTaskToStack()"); 7457 if (stackId == HOME_STACK_ID) { 7458 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7459 new RuntimeException("here").fillInStackTrace()); 7460 } 7461 synchronized (this) { 7462 long ident = Binder.clearCallingIdentity(); 7463 try { 7464 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7465 + stackId + " toTop=" + toTop); 7466 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7467 } finally { 7468 Binder.restoreCallingIdentity(ident); 7469 } 7470 } 7471 } 7472 7473 @Override 7474 public void resizeStack(int stackBoxId, Rect bounds) { 7475 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7476 "resizeStackBox()"); 7477 long ident = Binder.clearCallingIdentity(); 7478 try { 7479 mWindowManager.resizeStack(stackBoxId, bounds); 7480 } finally { 7481 Binder.restoreCallingIdentity(ident); 7482 } 7483 } 7484 7485 @Override 7486 public List<StackInfo> getAllStackInfos() { 7487 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7488 "getAllStackInfos()"); 7489 long ident = Binder.clearCallingIdentity(); 7490 try { 7491 synchronized (this) { 7492 return mStackSupervisor.getAllStackInfosLocked(); 7493 } 7494 } finally { 7495 Binder.restoreCallingIdentity(ident); 7496 } 7497 } 7498 7499 @Override 7500 public StackInfo getStackInfo(int stackId) { 7501 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7502 "getStackInfo()"); 7503 long ident = Binder.clearCallingIdentity(); 7504 try { 7505 synchronized (this) { 7506 return mStackSupervisor.getStackInfoLocked(stackId); 7507 } 7508 } finally { 7509 Binder.restoreCallingIdentity(ident); 7510 } 7511 } 7512 7513 @Override 7514 public boolean isInHomeStack(int taskId) { 7515 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7516 "getStackInfo()"); 7517 long ident = Binder.clearCallingIdentity(); 7518 try { 7519 synchronized (this) { 7520 TaskRecord tr = recentTaskForIdLocked(taskId); 7521 if (tr != null) { 7522 return tr.stack.isHomeStack(); 7523 } 7524 } 7525 } finally { 7526 Binder.restoreCallingIdentity(ident); 7527 } 7528 return false; 7529 } 7530 7531 @Override 7532 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7533 synchronized(this) { 7534 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7535 } 7536 } 7537 7538 private boolean isLockTaskAuthorized(ComponentName name) { 7539// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7540// "startLockTaskMode()"); 7541// DevicePolicyManager dpm = (DevicePolicyManager) 7542// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7543// return dpm != null && dpm.isLockTaskPermitted(name); 7544 return true; 7545 } 7546 7547 private void startLockTaskMode(TaskRecord task) { 7548 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7549 return; 7550 } 7551 long ident = Binder.clearCallingIdentity(); 7552 try { 7553 synchronized (this) { 7554 // Since we lost lock on task, make sure it is still there. 7555 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7556 if (task != null) { 7557 mStackSupervisor.setLockTaskModeLocked(task); 7558 } 7559 } 7560 } finally { 7561 Binder.restoreCallingIdentity(ident); 7562 } 7563 } 7564 7565 @Override 7566 public void startLockTaskMode(int taskId) { 7567 long ident = Binder.clearCallingIdentity(); 7568 try { 7569 final TaskRecord task; 7570 synchronized (this) { 7571 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7572 } 7573 if (task != null) { 7574 startLockTaskMode(task); 7575 } 7576 } finally { 7577 Binder.restoreCallingIdentity(ident); 7578 } 7579 } 7580 7581 @Override 7582 public void startLockTaskMode(IBinder token) { 7583 long ident = Binder.clearCallingIdentity(); 7584 try { 7585 final TaskRecord task; 7586 synchronized (this) { 7587 final ActivityRecord r = ActivityRecord.forToken(token); 7588 if (r == null) { 7589 return; 7590 } 7591 task = r.task; 7592 } 7593 if (task != null) { 7594 startLockTaskMode(task); 7595 } 7596 } finally { 7597 Binder.restoreCallingIdentity(ident); 7598 } 7599 } 7600 7601 @Override 7602 public void stopLockTaskMode() { 7603// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7604// "stopLockTaskMode()"); 7605 synchronized (this) { 7606 mStackSupervisor.setLockTaskModeLocked(null); 7607 } 7608 } 7609 7610 @Override 7611 public boolean isInLockTaskMode() { 7612 synchronized (this) { 7613 return mStackSupervisor.isInLockTaskMode(); 7614 } 7615 } 7616 7617 // ========================================================= 7618 // CONTENT PROVIDERS 7619 // ========================================================= 7620 7621 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7622 List<ProviderInfo> providers = null; 7623 try { 7624 providers = AppGlobals.getPackageManager(). 7625 queryContentProviders(app.processName, app.uid, 7626 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7627 } catch (RemoteException ex) { 7628 } 7629 if (DEBUG_MU) 7630 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7631 int userId = app.userId; 7632 if (providers != null) { 7633 int N = providers.size(); 7634 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7635 for (int i=0; i<N; i++) { 7636 ProviderInfo cpi = 7637 (ProviderInfo)providers.get(i); 7638 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7639 cpi.name, cpi.flags); 7640 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7641 // This is a singleton provider, but a user besides the 7642 // default user is asking to initialize a process it runs 7643 // in... well, no, it doesn't actually run in this process, 7644 // it runs in the process of the default user. Get rid of it. 7645 providers.remove(i); 7646 N--; 7647 i--; 7648 continue; 7649 } 7650 7651 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7652 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7653 if (cpr == null) { 7654 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7655 mProviderMap.putProviderByClass(comp, cpr); 7656 } 7657 if (DEBUG_MU) 7658 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7659 app.pubProviders.put(cpi.name, cpr); 7660 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7661 // Don't add this if it is a platform component that is marked 7662 // to run in multiple processes, because this is actually 7663 // part of the framework so doesn't make sense to track as a 7664 // separate apk in the process. 7665 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7666 } 7667 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7668 } 7669 } 7670 return providers; 7671 } 7672 7673 /** 7674 * Check if {@link ProcessRecord} has a possible chance at accessing the 7675 * given {@link ProviderInfo}. Final permission checking is always done 7676 * in {@link ContentProvider}. 7677 */ 7678 private final String checkContentProviderPermissionLocked( 7679 ProviderInfo cpi, ProcessRecord r) { 7680 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7681 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7682 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7683 cpi.applicationInfo.uid, cpi.exported) 7684 == PackageManager.PERMISSION_GRANTED) { 7685 return null; 7686 } 7687 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7688 cpi.applicationInfo.uid, cpi.exported) 7689 == PackageManager.PERMISSION_GRANTED) { 7690 return null; 7691 } 7692 7693 PathPermission[] pps = cpi.pathPermissions; 7694 if (pps != null) { 7695 int i = pps.length; 7696 while (i > 0) { 7697 i--; 7698 PathPermission pp = pps[i]; 7699 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7700 cpi.applicationInfo.uid, cpi.exported) 7701 == PackageManager.PERMISSION_GRANTED) { 7702 return null; 7703 } 7704 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7705 cpi.applicationInfo.uid, cpi.exported) 7706 == PackageManager.PERMISSION_GRANTED) { 7707 return null; 7708 } 7709 } 7710 } 7711 7712 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7713 if (perms != null) { 7714 for (GrantUri uri : perms.keySet()) { 7715 if (uri.uri.getAuthority().equals(cpi.authority)) { 7716 return null; 7717 } 7718 } 7719 } 7720 7721 String msg; 7722 if (!cpi.exported) { 7723 msg = "Permission Denial: opening provider " + cpi.name 7724 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7725 + ", uid=" + callingUid + ") that is not exported from uid " 7726 + cpi.applicationInfo.uid; 7727 } else { 7728 msg = "Permission Denial: opening provider " + cpi.name 7729 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7730 + ", uid=" + callingUid + ") requires " 7731 + cpi.readPermission + " or " + cpi.writePermission; 7732 } 7733 Slog.w(TAG, msg); 7734 return msg; 7735 } 7736 7737 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7738 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7739 if (r != null) { 7740 for (int i=0; i<r.conProviders.size(); i++) { 7741 ContentProviderConnection conn = r.conProviders.get(i); 7742 if (conn.provider == cpr) { 7743 if (DEBUG_PROVIDER) Slog.v(TAG, 7744 "Adding provider requested by " 7745 + r.processName + " from process " 7746 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7747 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7748 if (stable) { 7749 conn.stableCount++; 7750 conn.numStableIncs++; 7751 } else { 7752 conn.unstableCount++; 7753 conn.numUnstableIncs++; 7754 } 7755 return conn; 7756 } 7757 } 7758 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7759 if (stable) { 7760 conn.stableCount = 1; 7761 conn.numStableIncs = 1; 7762 } else { 7763 conn.unstableCount = 1; 7764 conn.numUnstableIncs = 1; 7765 } 7766 cpr.connections.add(conn); 7767 r.conProviders.add(conn); 7768 return conn; 7769 } 7770 cpr.addExternalProcessHandleLocked(externalProcessToken); 7771 return null; 7772 } 7773 7774 boolean decProviderCountLocked(ContentProviderConnection conn, 7775 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7776 if (conn != null) { 7777 cpr = conn.provider; 7778 if (DEBUG_PROVIDER) Slog.v(TAG, 7779 "Removing provider requested by " 7780 + conn.client.processName + " from process " 7781 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7782 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7783 if (stable) { 7784 conn.stableCount--; 7785 } else { 7786 conn.unstableCount--; 7787 } 7788 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7789 cpr.connections.remove(conn); 7790 conn.client.conProviders.remove(conn); 7791 return true; 7792 } 7793 return false; 7794 } 7795 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7796 return false; 7797 } 7798 7799 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7800 String name, IBinder token, boolean stable, int userId) { 7801 ContentProviderRecord cpr; 7802 ContentProviderConnection conn = null; 7803 ProviderInfo cpi = null; 7804 7805 synchronized(this) { 7806 ProcessRecord r = null; 7807 if (caller != null) { 7808 r = getRecordForAppLocked(caller); 7809 if (r == null) { 7810 throw new SecurityException( 7811 "Unable to find app for caller " + caller 7812 + " (pid=" + Binder.getCallingPid() 7813 + ") when getting content provider " + name); 7814 } 7815 } 7816 7817 // First check if this content provider has been published... 7818 cpr = mProviderMap.getProviderByName(name, userId); 7819 boolean providerRunning = cpr != null; 7820 if (providerRunning) { 7821 cpi = cpr.info; 7822 String msg; 7823 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7824 throw new SecurityException(msg); 7825 } 7826 7827 if (r != null && cpr.canRunHere(r)) { 7828 // This provider has been published or is in the process 7829 // of being published... but it is also allowed to run 7830 // in the caller's process, so don't make a connection 7831 // and just let the caller instantiate its own instance. 7832 ContentProviderHolder holder = cpr.newHolder(null); 7833 // don't give caller the provider object, it needs 7834 // to make its own. 7835 holder.provider = null; 7836 return holder; 7837 } 7838 7839 final long origId = Binder.clearCallingIdentity(); 7840 7841 // In this case the provider instance already exists, so we can 7842 // return it right away. 7843 conn = incProviderCountLocked(r, cpr, token, stable); 7844 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7845 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7846 // If this is a perceptible app accessing the provider, 7847 // make sure to count it as being accessed and thus 7848 // back up on the LRU list. This is good because 7849 // content providers are often expensive to start. 7850 updateLruProcessLocked(cpr.proc, false, null); 7851 } 7852 } 7853 7854 if (cpr.proc != null) { 7855 if (false) { 7856 if (cpr.name.flattenToShortString().equals( 7857 "com.android.providers.calendar/.CalendarProvider2")) { 7858 Slog.v(TAG, "****************** KILLING " 7859 + cpr.name.flattenToShortString()); 7860 Process.killProcess(cpr.proc.pid); 7861 } 7862 } 7863 boolean success = updateOomAdjLocked(cpr.proc); 7864 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7865 // NOTE: there is still a race here where a signal could be 7866 // pending on the process even though we managed to update its 7867 // adj level. Not sure what to do about this, but at least 7868 // the race is now smaller. 7869 if (!success) { 7870 // Uh oh... it looks like the provider's process 7871 // has been killed on us. We need to wait for a new 7872 // process to be started, and make sure its death 7873 // doesn't kill our process. 7874 Slog.i(TAG, 7875 "Existing provider " + cpr.name.flattenToShortString() 7876 + " is crashing; detaching " + r); 7877 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7878 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7879 if (!lastRef) { 7880 // This wasn't the last ref our process had on 7881 // the provider... we have now been killed, bail. 7882 return null; 7883 } 7884 providerRunning = false; 7885 conn = null; 7886 } 7887 } 7888 7889 Binder.restoreCallingIdentity(origId); 7890 } 7891 7892 boolean singleton; 7893 if (!providerRunning) { 7894 try { 7895 cpi = AppGlobals.getPackageManager(). 7896 resolveContentProvider(name, 7897 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7898 } catch (RemoteException ex) { 7899 } 7900 if (cpi == null) { 7901 return null; 7902 } 7903 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7904 cpi.name, cpi.flags); 7905 if (singleton) { 7906 userId = 0; 7907 } 7908 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7909 7910 String msg; 7911 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7912 throw new SecurityException(msg); 7913 } 7914 7915 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7916 && !cpi.processName.equals("system")) { 7917 // If this content provider does not run in the system 7918 // process, and the system is not yet ready to run other 7919 // processes, then fail fast instead of hanging. 7920 throw new IllegalArgumentException( 7921 "Attempt to launch content provider before system ready"); 7922 } 7923 7924 // Make sure that the user who owns this provider is started. If not, 7925 // we don't want to allow it to run. 7926 if (mStartedUsers.get(userId) == null) { 7927 Slog.w(TAG, "Unable to launch app " 7928 + cpi.applicationInfo.packageName + "/" 7929 + cpi.applicationInfo.uid + " for provider " 7930 + name + ": user " + userId + " is stopped"); 7931 return null; 7932 } 7933 7934 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7935 cpr = mProviderMap.getProviderByClass(comp, userId); 7936 final boolean firstClass = cpr == null; 7937 if (firstClass) { 7938 try { 7939 ApplicationInfo ai = 7940 AppGlobals.getPackageManager(). 7941 getApplicationInfo( 7942 cpi.applicationInfo.packageName, 7943 STOCK_PM_FLAGS, userId); 7944 if (ai == null) { 7945 Slog.w(TAG, "No package info for content provider " 7946 + cpi.name); 7947 return null; 7948 } 7949 ai = getAppInfoForUser(ai, userId); 7950 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7951 } catch (RemoteException ex) { 7952 // pm is in same process, this will never happen. 7953 } 7954 } 7955 7956 if (r != null && cpr.canRunHere(r)) { 7957 // If this is a multiprocess provider, then just return its 7958 // info and allow the caller to instantiate it. Only do 7959 // this if the provider is the same user as the caller's 7960 // process, or can run as root (so can be in any process). 7961 return cpr.newHolder(null); 7962 } 7963 7964 if (DEBUG_PROVIDER) { 7965 RuntimeException e = new RuntimeException("here"); 7966 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7967 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7968 } 7969 7970 // This is single process, and our app is now connecting to it. 7971 // See if we are already in the process of launching this 7972 // provider. 7973 final int N = mLaunchingProviders.size(); 7974 int i; 7975 for (i=0; i<N; i++) { 7976 if (mLaunchingProviders.get(i) == cpr) { 7977 break; 7978 } 7979 } 7980 7981 // If the provider is not already being launched, then get it 7982 // started. 7983 if (i >= N) { 7984 final long origId = Binder.clearCallingIdentity(); 7985 7986 try { 7987 // Content provider is now in use, its package can't be stopped. 7988 try { 7989 AppGlobals.getPackageManager().setPackageStoppedState( 7990 cpr.appInfo.packageName, false, userId); 7991 } catch (RemoteException e) { 7992 } catch (IllegalArgumentException e) { 7993 Slog.w(TAG, "Failed trying to unstop package " 7994 + cpr.appInfo.packageName + ": " + e); 7995 } 7996 7997 // Use existing process if already started 7998 ProcessRecord proc = getProcessRecordLocked( 7999 cpi.processName, cpr.appInfo.uid, false); 8000 if (proc != null && proc.thread != null) { 8001 if (DEBUG_PROVIDER) { 8002 Slog.d(TAG, "Installing in existing process " + proc); 8003 } 8004 proc.pubProviders.put(cpi.name, cpr); 8005 try { 8006 proc.thread.scheduleInstallProvider(cpi); 8007 } catch (RemoteException e) { 8008 } 8009 } else { 8010 proc = startProcessLocked(cpi.processName, 8011 cpr.appInfo, false, 0, "content provider", 8012 new ComponentName(cpi.applicationInfo.packageName, 8013 cpi.name), false, false, false); 8014 if (proc == null) { 8015 Slog.w(TAG, "Unable to launch app " 8016 + cpi.applicationInfo.packageName + "/" 8017 + cpi.applicationInfo.uid + " for provider " 8018 + name + ": process is bad"); 8019 return null; 8020 } 8021 } 8022 cpr.launchingApp = proc; 8023 mLaunchingProviders.add(cpr); 8024 } finally { 8025 Binder.restoreCallingIdentity(origId); 8026 } 8027 } 8028 8029 // Make sure the provider is published (the same provider class 8030 // may be published under multiple names). 8031 if (firstClass) { 8032 mProviderMap.putProviderByClass(comp, cpr); 8033 } 8034 8035 mProviderMap.putProviderByName(name, cpr); 8036 conn = incProviderCountLocked(r, cpr, token, stable); 8037 if (conn != null) { 8038 conn.waiting = true; 8039 } 8040 } 8041 } 8042 8043 // Wait for the provider to be published... 8044 synchronized (cpr) { 8045 while (cpr.provider == null) { 8046 if (cpr.launchingApp == null) { 8047 Slog.w(TAG, "Unable to launch app " 8048 + cpi.applicationInfo.packageName + "/" 8049 + cpi.applicationInfo.uid + " for provider " 8050 + name + ": launching app became null"); 8051 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8052 UserHandle.getUserId(cpi.applicationInfo.uid), 8053 cpi.applicationInfo.packageName, 8054 cpi.applicationInfo.uid, name); 8055 return null; 8056 } 8057 try { 8058 if (DEBUG_MU) { 8059 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8060 + cpr.launchingApp); 8061 } 8062 if (conn != null) { 8063 conn.waiting = true; 8064 } 8065 cpr.wait(); 8066 } catch (InterruptedException ex) { 8067 } finally { 8068 if (conn != null) { 8069 conn.waiting = false; 8070 } 8071 } 8072 } 8073 } 8074 return cpr != null ? cpr.newHolder(conn) : null; 8075 } 8076 8077 public final ContentProviderHolder getContentProvider( 8078 IApplicationThread caller, String name, int userId, boolean stable) { 8079 enforceNotIsolatedCaller("getContentProvider"); 8080 if (caller == null) { 8081 String msg = "null IApplicationThread when getting content provider " 8082 + name; 8083 Slog.w(TAG, msg); 8084 throw new SecurityException(msg); 8085 } 8086 8087 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8088 false, true, "getContentProvider", null); 8089 return getContentProviderImpl(caller, name, null, stable, userId); 8090 } 8091 8092 public ContentProviderHolder getContentProviderExternal( 8093 String name, int userId, IBinder token) { 8094 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8095 "Do not have permission in call getContentProviderExternal()"); 8096 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8097 false, true, "getContentProvider", null); 8098 return getContentProviderExternalUnchecked(name, token, userId); 8099 } 8100 8101 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8102 IBinder token, int userId) { 8103 return getContentProviderImpl(null, name, token, true, userId); 8104 } 8105 8106 /** 8107 * Drop a content provider from a ProcessRecord's bookkeeping 8108 */ 8109 public void removeContentProvider(IBinder connection, boolean stable) { 8110 enforceNotIsolatedCaller("removeContentProvider"); 8111 long ident = Binder.clearCallingIdentity(); 8112 try { 8113 synchronized (this) { 8114 ContentProviderConnection conn; 8115 try { 8116 conn = (ContentProviderConnection)connection; 8117 } catch (ClassCastException e) { 8118 String msg ="removeContentProvider: " + connection 8119 + " not a ContentProviderConnection"; 8120 Slog.w(TAG, msg); 8121 throw new IllegalArgumentException(msg); 8122 } 8123 if (conn == null) { 8124 throw new NullPointerException("connection is null"); 8125 } 8126 if (decProviderCountLocked(conn, null, null, stable)) { 8127 updateOomAdjLocked(); 8128 } 8129 } 8130 } finally { 8131 Binder.restoreCallingIdentity(ident); 8132 } 8133 } 8134 8135 public void removeContentProviderExternal(String name, IBinder token) { 8136 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8137 "Do not have permission in call removeContentProviderExternal()"); 8138 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8139 } 8140 8141 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8142 synchronized (this) { 8143 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8144 if(cpr == null) { 8145 //remove from mProvidersByClass 8146 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8147 return; 8148 } 8149 8150 //update content provider record entry info 8151 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8152 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8153 if (localCpr.hasExternalProcessHandles()) { 8154 if (localCpr.removeExternalProcessHandleLocked(token)) { 8155 updateOomAdjLocked(); 8156 } else { 8157 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8158 + " with no external reference for token: " 8159 + token + "."); 8160 } 8161 } else { 8162 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8163 + " with no external references."); 8164 } 8165 } 8166 } 8167 8168 public final void publishContentProviders(IApplicationThread caller, 8169 List<ContentProviderHolder> providers) { 8170 if (providers == null) { 8171 return; 8172 } 8173 8174 enforceNotIsolatedCaller("publishContentProviders"); 8175 synchronized (this) { 8176 final ProcessRecord r = getRecordForAppLocked(caller); 8177 if (DEBUG_MU) 8178 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8179 if (r == null) { 8180 throw new SecurityException( 8181 "Unable to find app for caller " + caller 8182 + " (pid=" + Binder.getCallingPid() 8183 + ") when publishing content providers"); 8184 } 8185 8186 final long origId = Binder.clearCallingIdentity(); 8187 8188 final int N = providers.size(); 8189 for (int i=0; i<N; i++) { 8190 ContentProviderHolder src = providers.get(i); 8191 if (src == null || src.info == null || src.provider == null) { 8192 continue; 8193 } 8194 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8195 if (DEBUG_MU) 8196 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8197 if (dst != null) { 8198 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8199 mProviderMap.putProviderByClass(comp, dst); 8200 String names[] = dst.info.authority.split(";"); 8201 for (int j = 0; j < names.length; j++) { 8202 mProviderMap.putProviderByName(names[j], dst); 8203 } 8204 8205 int NL = mLaunchingProviders.size(); 8206 int j; 8207 for (j=0; j<NL; j++) { 8208 if (mLaunchingProviders.get(j) == dst) { 8209 mLaunchingProviders.remove(j); 8210 j--; 8211 NL--; 8212 } 8213 } 8214 synchronized (dst) { 8215 dst.provider = src.provider; 8216 dst.proc = r; 8217 dst.notifyAll(); 8218 } 8219 updateOomAdjLocked(r); 8220 } 8221 } 8222 8223 Binder.restoreCallingIdentity(origId); 8224 } 8225 } 8226 8227 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8228 ContentProviderConnection conn; 8229 try { 8230 conn = (ContentProviderConnection)connection; 8231 } catch (ClassCastException e) { 8232 String msg ="refContentProvider: " + connection 8233 + " not a ContentProviderConnection"; 8234 Slog.w(TAG, msg); 8235 throw new IllegalArgumentException(msg); 8236 } 8237 if (conn == null) { 8238 throw new NullPointerException("connection is null"); 8239 } 8240 8241 synchronized (this) { 8242 if (stable > 0) { 8243 conn.numStableIncs += stable; 8244 } 8245 stable = conn.stableCount + stable; 8246 if (stable < 0) { 8247 throw new IllegalStateException("stableCount < 0: " + stable); 8248 } 8249 8250 if (unstable > 0) { 8251 conn.numUnstableIncs += unstable; 8252 } 8253 unstable = conn.unstableCount + unstable; 8254 if (unstable < 0) { 8255 throw new IllegalStateException("unstableCount < 0: " + unstable); 8256 } 8257 8258 if ((stable+unstable) <= 0) { 8259 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8260 + stable + " unstable=" + unstable); 8261 } 8262 conn.stableCount = stable; 8263 conn.unstableCount = unstable; 8264 return !conn.dead; 8265 } 8266 } 8267 8268 public void unstableProviderDied(IBinder connection) { 8269 ContentProviderConnection conn; 8270 try { 8271 conn = (ContentProviderConnection)connection; 8272 } catch (ClassCastException e) { 8273 String msg ="refContentProvider: " + connection 8274 + " not a ContentProviderConnection"; 8275 Slog.w(TAG, msg); 8276 throw new IllegalArgumentException(msg); 8277 } 8278 if (conn == null) { 8279 throw new NullPointerException("connection is null"); 8280 } 8281 8282 // Safely retrieve the content provider associated with the connection. 8283 IContentProvider provider; 8284 synchronized (this) { 8285 provider = conn.provider.provider; 8286 } 8287 8288 if (provider == null) { 8289 // Um, yeah, we're way ahead of you. 8290 return; 8291 } 8292 8293 // Make sure the caller is being honest with us. 8294 if (provider.asBinder().pingBinder()) { 8295 // Er, no, still looks good to us. 8296 synchronized (this) { 8297 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8298 + " says " + conn + " died, but we don't agree"); 8299 return; 8300 } 8301 } 8302 8303 // Well look at that! It's dead! 8304 synchronized (this) { 8305 if (conn.provider.provider != provider) { 8306 // But something changed... good enough. 8307 return; 8308 } 8309 8310 ProcessRecord proc = conn.provider.proc; 8311 if (proc == null || proc.thread == null) { 8312 // Seems like the process is already cleaned up. 8313 return; 8314 } 8315 8316 // As far as we're concerned, this is just like receiving a 8317 // death notification... just a bit prematurely. 8318 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8319 + ") early provider death"); 8320 final long ident = Binder.clearCallingIdentity(); 8321 try { 8322 appDiedLocked(proc, proc.pid, proc.thread); 8323 } finally { 8324 Binder.restoreCallingIdentity(ident); 8325 } 8326 } 8327 } 8328 8329 @Override 8330 public void appNotRespondingViaProvider(IBinder connection) { 8331 enforceCallingPermission( 8332 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8333 8334 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8335 if (conn == null) { 8336 Slog.w(TAG, "ContentProviderConnection is null"); 8337 return; 8338 } 8339 8340 final ProcessRecord host = conn.provider.proc; 8341 if (host == null) { 8342 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8343 return; 8344 } 8345 8346 final long token = Binder.clearCallingIdentity(); 8347 try { 8348 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8349 } finally { 8350 Binder.restoreCallingIdentity(token); 8351 } 8352 } 8353 8354 public final void installSystemProviders() { 8355 List<ProviderInfo> providers; 8356 synchronized (this) { 8357 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8358 providers = generateApplicationProvidersLocked(app); 8359 if (providers != null) { 8360 for (int i=providers.size()-1; i>=0; i--) { 8361 ProviderInfo pi = (ProviderInfo)providers.get(i); 8362 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8363 Slog.w(TAG, "Not installing system proc provider " + pi.name 8364 + ": not system .apk"); 8365 providers.remove(i); 8366 } 8367 } 8368 } 8369 } 8370 if (providers != null) { 8371 mSystemThread.installSystemProviders(providers); 8372 } 8373 8374 mCoreSettingsObserver = new CoreSettingsObserver(this); 8375 8376 mUsageStatsService.monitorPackages(); 8377 } 8378 8379 /** 8380 * Allows app to retrieve the MIME type of a URI without having permission 8381 * to access its content provider. 8382 * 8383 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8384 * 8385 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8386 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8387 */ 8388 public String getProviderMimeType(Uri uri, int userId) { 8389 enforceNotIsolatedCaller("getProviderMimeType"); 8390 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8391 userId, false, true, "getProviderMimeType", null); 8392 final String name = uri.getAuthority(); 8393 final long ident = Binder.clearCallingIdentity(); 8394 ContentProviderHolder holder = null; 8395 8396 try { 8397 holder = getContentProviderExternalUnchecked(name, null, userId); 8398 if (holder != null) { 8399 return holder.provider.getType(uri); 8400 } 8401 } catch (RemoteException e) { 8402 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8403 return null; 8404 } finally { 8405 if (holder != null) { 8406 removeContentProviderExternalUnchecked(name, null, userId); 8407 } 8408 Binder.restoreCallingIdentity(ident); 8409 } 8410 8411 return null; 8412 } 8413 8414 // ========================================================= 8415 // GLOBAL MANAGEMENT 8416 // ========================================================= 8417 8418 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8419 boolean isolated) { 8420 String proc = customProcess != null ? customProcess : info.processName; 8421 BatteryStatsImpl.Uid.Proc ps = null; 8422 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8423 int uid = info.uid; 8424 if (isolated) { 8425 int userId = UserHandle.getUserId(uid); 8426 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8427 while (true) { 8428 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8429 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8430 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8431 } 8432 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8433 mNextIsolatedProcessUid++; 8434 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8435 // No process for this uid, use it. 8436 break; 8437 } 8438 stepsLeft--; 8439 if (stepsLeft <= 0) { 8440 return null; 8441 } 8442 } 8443 } 8444 return new ProcessRecord(stats, info, proc, uid); 8445 } 8446 8447 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8448 ProcessRecord app; 8449 if (!isolated) { 8450 app = getProcessRecordLocked(info.processName, info.uid, true); 8451 } else { 8452 app = null; 8453 } 8454 8455 if (app == null) { 8456 app = newProcessRecordLocked(info, null, isolated); 8457 mProcessNames.put(info.processName, app.uid, app); 8458 if (isolated) { 8459 mIsolatedProcesses.put(app.uid, app); 8460 } 8461 updateLruProcessLocked(app, false, null); 8462 updateOomAdjLocked(); 8463 } 8464 8465 // This package really, really can not be stopped. 8466 try { 8467 AppGlobals.getPackageManager().setPackageStoppedState( 8468 info.packageName, false, UserHandle.getUserId(app.uid)); 8469 } catch (RemoteException e) { 8470 } catch (IllegalArgumentException e) { 8471 Slog.w(TAG, "Failed trying to unstop package " 8472 + info.packageName + ": " + e); 8473 } 8474 8475 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8476 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8477 app.persistent = true; 8478 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8479 } 8480 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8481 mPersistentStartingProcesses.add(app); 8482 startProcessLocked(app, "added application", app.processName); 8483 } 8484 8485 return app; 8486 } 8487 8488 public void unhandledBack() { 8489 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8490 "unhandledBack()"); 8491 8492 synchronized(this) { 8493 final long origId = Binder.clearCallingIdentity(); 8494 try { 8495 getFocusedStack().unhandledBackLocked(); 8496 } finally { 8497 Binder.restoreCallingIdentity(origId); 8498 } 8499 } 8500 } 8501 8502 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8503 enforceNotIsolatedCaller("openContentUri"); 8504 final int userId = UserHandle.getCallingUserId(); 8505 String name = uri.getAuthority(); 8506 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8507 ParcelFileDescriptor pfd = null; 8508 if (cph != null) { 8509 // We record the binder invoker's uid in thread-local storage before 8510 // going to the content provider to open the file. Later, in the code 8511 // that handles all permissions checks, we look for this uid and use 8512 // that rather than the Activity Manager's own uid. The effect is that 8513 // we do the check against the caller's permissions even though it looks 8514 // to the content provider like the Activity Manager itself is making 8515 // the request. 8516 sCallerIdentity.set(new Identity( 8517 Binder.getCallingPid(), Binder.getCallingUid())); 8518 try { 8519 pfd = cph.provider.openFile(null, uri, "r", null); 8520 } catch (FileNotFoundException e) { 8521 // do nothing; pfd will be returned null 8522 } finally { 8523 // Ensure that whatever happens, we clean up the identity state 8524 sCallerIdentity.remove(); 8525 } 8526 8527 // We've got the fd now, so we're done with the provider. 8528 removeContentProviderExternalUnchecked(name, null, userId); 8529 } else { 8530 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8531 } 8532 return pfd; 8533 } 8534 8535 // Actually is sleeping or shutting down or whatever else in the future 8536 // is an inactive state. 8537 public boolean isSleepingOrShuttingDown() { 8538 return mSleeping || mShuttingDown; 8539 } 8540 8541 public boolean isSleeping() { 8542 return mSleeping; 8543 } 8544 8545 void goingToSleep() { 8546 synchronized(this) { 8547 mWentToSleep = true; 8548 updateEventDispatchingLocked(); 8549 goToSleepIfNeededLocked(); 8550 } 8551 } 8552 8553 void finishRunningVoiceLocked() { 8554 if (mRunningVoice) { 8555 mRunningVoice = false; 8556 goToSleepIfNeededLocked(); 8557 } 8558 } 8559 8560 void goToSleepIfNeededLocked() { 8561 if (mWentToSleep && !mRunningVoice) { 8562 if (!mSleeping) { 8563 mSleeping = true; 8564 mStackSupervisor.goingToSleepLocked(); 8565 8566 // Initialize the wake times of all processes. 8567 checkExcessivePowerUsageLocked(false); 8568 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8569 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8570 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8571 } 8572 } 8573 } 8574 8575 @Override 8576 public boolean shutdown(int timeout) { 8577 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8578 != PackageManager.PERMISSION_GRANTED) { 8579 throw new SecurityException("Requires permission " 8580 + android.Manifest.permission.SHUTDOWN); 8581 } 8582 8583 boolean timedout = false; 8584 8585 synchronized(this) { 8586 mShuttingDown = true; 8587 updateEventDispatchingLocked(); 8588 timedout = mStackSupervisor.shutdownLocked(timeout); 8589 } 8590 8591 mAppOpsService.shutdown(); 8592 mUsageStatsService.shutdown(); 8593 mBatteryStatsService.shutdown(); 8594 synchronized (this) { 8595 mProcessStats.shutdownLocked(); 8596 } 8597 8598 return timedout; 8599 } 8600 8601 public final void activitySlept(IBinder token) { 8602 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8603 8604 final long origId = Binder.clearCallingIdentity(); 8605 8606 synchronized (this) { 8607 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8608 if (r != null) { 8609 mStackSupervisor.activitySleptLocked(r); 8610 } 8611 } 8612 8613 Binder.restoreCallingIdentity(origId); 8614 } 8615 8616 void logLockScreen(String msg) { 8617 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8618 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8619 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8620 mStackSupervisor.mDismissKeyguardOnNextActivity); 8621 } 8622 8623 private void comeOutOfSleepIfNeededLocked() { 8624 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8625 if (mSleeping) { 8626 mSleeping = false; 8627 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8628 } 8629 } 8630 } 8631 8632 void wakingUp() { 8633 synchronized(this) { 8634 mWentToSleep = false; 8635 updateEventDispatchingLocked(); 8636 comeOutOfSleepIfNeededLocked(); 8637 } 8638 } 8639 8640 void startRunningVoiceLocked() { 8641 if (!mRunningVoice) { 8642 mRunningVoice = true; 8643 comeOutOfSleepIfNeededLocked(); 8644 } 8645 } 8646 8647 private void updateEventDispatchingLocked() { 8648 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8649 } 8650 8651 public void setLockScreenShown(boolean shown) { 8652 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8653 != PackageManager.PERMISSION_GRANTED) { 8654 throw new SecurityException("Requires permission " 8655 + android.Manifest.permission.DEVICE_POWER); 8656 } 8657 8658 synchronized(this) { 8659 long ident = Binder.clearCallingIdentity(); 8660 try { 8661 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8662 mLockScreenShown = shown; 8663 comeOutOfSleepIfNeededLocked(); 8664 } finally { 8665 Binder.restoreCallingIdentity(ident); 8666 } 8667 } 8668 } 8669 8670 public void stopAppSwitches() { 8671 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8672 != PackageManager.PERMISSION_GRANTED) { 8673 throw new SecurityException("Requires permission " 8674 + android.Manifest.permission.STOP_APP_SWITCHES); 8675 } 8676 8677 synchronized(this) { 8678 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8679 + APP_SWITCH_DELAY_TIME; 8680 mDidAppSwitch = false; 8681 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8682 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8683 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8684 } 8685 } 8686 8687 public void resumeAppSwitches() { 8688 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8689 != PackageManager.PERMISSION_GRANTED) { 8690 throw new SecurityException("Requires permission " 8691 + android.Manifest.permission.STOP_APP_SWITCHES); 8692 } 8693 8694 synchronized(this) { 8695 // Note that we don't execute any pending app switches... we will 8696 // let those wait until either the timeout, or the next start 8697 // activity request. 8698 mAppSwitchesAllowedTime = 0; 8699 } 8700 } 8701 8702 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8703 String name) { 8704 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8705 return true; 8706 } 8707 8708 final int perm = checkComponentPermission( 8709 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8710 callingUid, -1, true); 8711 if (perm == PackageManager.PERMISSION_GRANTED) { 8712 return true; 8713 } 8714 8715 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8716 return false; 8717 } 8718 8719 public void setDebugApp(String packageName, boolean waitForDebugger, 8720 boolean persistent) { 8721 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8722 "setDebugApp()"); 8723 8724 long ident = Binder.clearCallingIdentity(); 8725 try { 8726 // Note that this is not really thread safe if there are multiple 8727 // callers into it at the same time, but that's not a situation we 8728 // care about. 8729 if (persistent) { 8730 final ContentResolver resolver = mContext.getContentResolver(); 8731 Settings.Global.putString( 8732 resolver, Settings.Global.DEBUG_APP, 8733 packageName); 8734 Settings.Global.putInt( 8735 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8736 waitForDebugger ? 1 : 0); 8737 } 8738 8739 synchronized (this) { 8740 if (!persistent) { 8741 mOrigDebugApp = mDebugApp; 8742 mOrigWaitForDebugger = mWaitForDebugger; 8743 } 8744 mDebugApp = packageName; 8745 mWaitForDebugger = waitForDebugger; 8746 mDebugTransient = !persistent; 8747 if (packageName != null) { 8748 forceStopPackageLocked(packageName, -1, false, false, true, true, 8749 false, UserHandle.USER_ALL, "set debug app"); 8750 } 8751 } 8752 } finally { 8753 Binder.restoreCallingIdentity(ident); 8754 } 8755 } 8756 8757 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8758 synchronized (this) { 8759 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8760 if (!isDebuggable) { 8761 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8762 throw new SecurityException("Process not debuggable: " + app.packageName); 8763 } 8764 } 8765 8766 mOpenGlTraceApp = processName; 8767 } 8768 } 8769 8770 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8771 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8772 synchronized (this) { 8773 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8774 if (!isDebuggable) { 8775 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8776 throw new SecurityException("Process not debuggable: " + app.packageName); 8777 } 8778 } 8779 mProfileApp = processName; 8780 mProfileFile = profileFile; 8781 if (mProfileFd != null) { 8782 try { 8783 mProfileFd.close(); 8784 } catch (IOException e) { 8785 } 8786 mProfileFd = null; 8787 } 8788 mProfileFd = profileFd; 8789 mProfileType = 0; 8790 mAutoStopProfiler = autoStopProfiler; 8791 } 8792 } 8793 8794 @Override 8795 public void setAlwaysFinish(boolean enabled) { 8796 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8797 "setAlwaysFinish()"); 8798 8799 Settings.Global.putInt( 8800 mContext.getContentResolver(), 8801 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8802 8803 synchronized (this) { 8804 mAlwaysFinishActivities = enabled; 8805 } 8806 } 8807 8808 @Override 8809 public void setActivityController(IActivityController controller) { 8810 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8811 "setActivityController()"); 8812 synchronized (this) { 8813 mController = controller; 8814 Watchdog.getInstance().setActivityController(controller); 8815 } 8816 } 8817 8818 @Override 8819 public void setUserIsMonkey(boolean userIsMonkey) { 8820 synchronized (this) { 8821 synchronized (mPidsSelfLocked) { 8822 final int callingPid = Binder.getCallingPid(); 8823 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8824 if (precessRecord == null) { 8825 throw new SecurityException("Unknown process: " + callingPid); 8826 } 8827 if (precessRecord.instrumentationUiAutomationConnection == null) { 8828 throw new SecurityException("Only an instrumentation process " 8829 + "with a UiAutomation can call setUserIsMonkey"); 8830 } 8831 } 8832 mUserIsMonkey = userIsMonkey; 8833 } 8834 } 8835 8836 @Override 8837 public boolean isUserAMonkey() { 8838 synchronized (this) { 8839 // If there is a controller also implies the user is a monkey. 8840 return (mUserIsMonkey || mController != null); 8841 } 8842 } 8843 8844 public void requestBugReport() { 8845 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8846 SystemProperties.set("ctl.start", "bugreport"); 8847 } 8848 8849 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8850 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8851 } 8852 8853 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8854 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8855 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8856 } 8857 return KEY_DISPATCHING_TIMEOUT; 8858 } 8859 8860 @Override 8861 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8862 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8863 != PackageManager.PERMISSION_GRANTED) { 8864 throw new SecurityException("Requires permission " 8865 + android.Manifest.permission.FILTER_EVENTS); 8866 } 8867 ProcessRecord proc; 8868 long timeout; 8869 synchronized (this) { 8870 synchronized (mPidsSelfLocked) { 8871 proc = mPidsSelfLocked.get(pid); 8872 } 8873 timeout = getInputDispatchingTimeoutLocked(proc); 8874 } 8875 8876 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8877 return -1; 8878 } 8879 8880 return timeout; 8881 } 8882 8883 /** 8884 * Handle input dispatching timeouts. 8885 * Returns whether input dispatching should be aborted or not. 8886 */ 8887 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8888 final ActivityRecord activity, final ActivityRecord parent, 8889 final boolean aboveSystem, String reason) { 8890 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8891 != PackageManager.PERMISSION_GRANTED) { 8892 throw new SecurityException("Requires permission " 8893 + android.Manifest.permission.FILTER_EVENTS); 8894 } 8895 8896 final String annotation; 8897 if (reason == null) { 8898 annotation = "Input dispatching timed out"; 8899 } else { 8900 annotation = "Input dispatching timed out (" + reason + ")"; 8901 } 8902 8903 if (proc != null) { 8904 synchronized (this) { 8905 if (proc.debugging) { 8906 return false; 8907 } 8908 8909 if (mDidDexOpt) { 8910 // Give more time since we were dexopting. 8911 mDidDexOpt = false; 8912 return false; 8913 } 8914 8915 if (proc.instrumentationClass != null) { 8916 Bundle info = new Bundle(); 8917 info.putString("shortMsg", "keyDispatchingTimedOut"); 8918 info.putString("longMsg", annotation); 8919 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8920 return true; 8921 } 8922 } 8923 mHandler.post(new Runnable() { 8924 @Override 8925 public void run() { 8926 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8927 } 8928 }); 8929 } 8930 8931 return true; 8932 } 8933 8934 public Bundle getAssistContextExtras(int requestType) { 8935 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8936 "getAssistContextExtras()"); 8937 PendingAssistExtras pae; 8938 Bundle extras = new Bundle(); 8939 synchronized (this) { 8940 ActivityRecord activity = getFocusedStack().mResumedActivity; 8941 if (activity == null) { 8942 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8943 return null; 8944 } 8945 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8946 if (activity.app == null || activity.app.thread == null) { 8947 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8948 return extras; 8949 } 8950 if (activity.app.pid == Binder.getCallingPid()) { 8951 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8952 return extras; 8953 } 8954 pae = new PendingAssistExtras(activity); 8955 try { 8956 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8957 requestType); 8958 mPendingAssistExtras.add(pae); 8959 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8960 } catch (RemoteException e) { 8961 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8962 return extras; 8963 } 8964 } 8965 synchronized (pae) { 8966 while (!pae.haveResult) { 8967 try { 8968 pae.wait(); 8969 } catch (InterruptedException e) { 8970 } 8971 } 8972 if (pae.result != null) { 8973 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8974 } 8975 } 8976 synchronized (this) { 8977 mPendingAssistExtras.remove(pae); 8978 mHandler.removeCallbacks(pae); 8979 } 8980 return extras; 8981 } 8982 8983 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8984 PendingAssistExtras pae = (PendingAssistExtras)token; 8985 synchronized (pae) { 8986 pae.result = extras; 8987 pae.haveResult = true; 8988 pae.notifyAll(); 8989 } 8990 } 8991 8992 public void registerProcessObserver(IProcessObserver observer) { 8993 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8994 "registerProcessObserver()"); 8995 synchronized (this) { 8996 mProcessObservers.register(observer); 8997 } 8998 } 8999 9000 @Override 9001 public void unregisterProcessObserver(IProcessObserver observer) { 9002 synchronized (this) { 9003 mProcessObservers.unregister(observer); 9004 } 9005 } 9006 9007 @Override 9008 public boolean convertFromTranslucent(IBinder token) { 9009 final long origId = Binder.clearCallingIdentity(); 9010 try { 9011 synchronized (this) { 9012 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9013 if (r == null) { 9014 return false; 9015 } 9016 if (r.changeWindowTranslucency(true)) { 9017 mWindowManager.setAppFullscreen(token, true); 9018 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9019 return true; 9020 } 9021 return false; 9022 } 9023 } finally { 9024 Binder.restoreCallingIdentity(origId); 9025 } 9026 } 9027 9028 @Override 9029 public boolean convertToTranslucent(IBinder token) { 9030 final long origId = Binder.clearCallingIdentity(); 9031 try { 9032 synchronized (this) { 9033 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9034 if (r == null) { 9035 return false; 9036 } 9037 if (r.changeWindowTranslucency(false)) { 9038 r.task.stack.convertToTranslucent(r); 9039 mWindowManager.setAppFullscreen(token, false); 9040 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9041 return true; 9042 } 9043 return false; 9044 } 9045 } finally { 9046 Binder.restoreCallingIdentity(origId); 9047 } 9048 } 9049 9050 @Override 9051 public void setImmersive(IBinder token, boolean immersive) { 9052 synchronized(this) { 9053 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9054 if (r == null) { 9055 throw new IllegalArgumentException(); 9056 } 9057 r.immersive = immersive; 9058 9059 // update associated state if we're frontmost 9060 if (r == mFocusedActivity) { 9061 if (DEBUG_IMMERSIVE) { 9062 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9063 } 9064 applyUpdateLockStateLocked(r); 9065 } 9066 } 9067 } 9068 9069 @Override 9070 public boolean isImmersive(IBinder token) { 9071 synchronized (this) { 9072 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9073 if (r == null) { 9074 throw new IllegalArgumentException(); 9075 } 9076 return r.immersive; 9077 } 9078 } 9079 9080 public boolean isTopActivityImmersive() { 9081 enforceNotIsolatedCaller("startActivity"); 9082 synchronized (this) { 9083 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9084 return (r != null) ? r.immersive : false; 9085 } 9086 } 9087 9088 public final void enterSafeMode() { 9089 synchronized(this) { 9090 // It only makes sense to do this before the system is ready 9091 // and started launching other packages. 9092 if (!mSystemReady) { 9093 try { 9094 AppGlobals.getPackageManager().enterSafeMode(); 9095 } catch (RemoteException e) { 9096 } 9097 } 9098 9099 mSafeMode = true; 9100 } 9101 } 9102 9103 public final void showSafeModeOverlay() { 9104 View v = LayoutInflater.from(mContext).inflate( 9105 com.android.internal.R.layout.safe_mode, null); 9106 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9107 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9108 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9109 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9110 lp.gravity = Gravity.BOTTOM | Gravity.START; 9111 lp.format = v.getBackground().getOpacity(); 9112 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9113 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9114 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9115 ((WindowManager)mContext.getSystemService( 9116 Context.WINDOW_SERVICE)).addView(v, lp); 9117 } 9118 9119 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9120 if (!(sender instanceof PendingIntentRecord)) { 9121 return; 9122 } 9123 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9124 synchronized (stats) { 9125 if (mBatteryStatsService.isOnBattery()) { 9126 mBatteryStatsService.enforceCallingPermission(); 9127 PendingIntentRecord rec = (PendingIntentRecord)sender; 9128 int MY_UID = Binder.getCallingUid(); 9129 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9130 BatteryStatsImpl.Uid.Pkg pkg = 9131 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9132 sourcePkg != null ? sourcePkg : rec.key.packageName); 9133 pkg.incWakeupsLocked(); 9134 } 9135 } 9136 } 9137 9138 public boolean killPids(int[] pids, String pReason, boolean secure) { 9139 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9140 throw new SecurityException("killPids only available to the system"); 9141 } 9142 String reason = (pReason == null) ? "Unknown" : pReason; 9143 // XXX Note: don't acquire main activity lock here, because the window 9144 // manager calls in with its locks held. 9145 9146 boolean killed = false; 9147 synchronized (mPidsSelfLocked) { 9148 int[] types = new int[pids.length]; 9149 int worstType = 0; 9150 for (int i=0; i<pids.length; i++) { 9151 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9152 if (proc != null) { 9153 int type = proc.setAdj; 9154 types[i] = type; 9155 if (type > worstType) { 9156 worstType = type; 9157 } 9158 } 9159 } 9160 9161 // If the worst oom_adj is somewhere in the cached proc LRU range, 9162 // then constrain it so we will kill all cached procs. 9163 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9164 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9165 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9166 } 9167 9168 // If this is not a secure call, don't let it kill processes that 9169 // are important. 9170 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9171 worstType = ProcessList.SERVICE_ADJ; 9172 } 9173 9174 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9175 for (int i=0; i<pids.length; i++) { 9176 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9177 if (proc == null) { 9178 continue; 9179 } 9180 int adj = proc.setAdj; 9181 if (adj >= worstType && !proc.killedByAm) { 9182 killUnneededProcessLocked(proc, reason); 9183 killed = true; 9184 } 9185 } 9186 } 9187 return killed; 9188 } 9189 9190 @Override 9191 public void killUid(int uid, String reason) { 9192 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9193 throw new SecurityException("killUid only available to the system"); 9194 } 9195 synchronized (this) { 9196 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9197 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9198 reason != null ? reason : "kill uid"); 9199 } 9200 } 9201 9202 @Override 9203 public boolean killProcessesBelowForeground(String reason) { 9204 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9205 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9206 } 9207 9208 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9209 } 9210 9211 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9212 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9213 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9214 } 9215 9216 boolean killed = false; 9217 synchronized (mPidsSelfLocked) { 9218 final int size = mPidsSelfLocked.size(); 9219 for (int i = 0; i < size; i++) { 9220 final int pid = mPidsSelfLocked.keyAt(i); 9221 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9222 if (proc == null) continue; 9223 9224 final int adj = proc.setAdj; 9225 if (adj > belowAdj && !proc.killedByAm) { 9226 killUnneededProcessLocked(proc, reason); 9227 killed = true; 9228 } 9229 } 9230 } 9231 return killed; 9232 } 9233 9234 @Override 9235 public void hang(final IBinder who, boolean allowRestart) { 9236 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9237 != PackageManager.PERMISSION_GRANTED) { 9238 throw new SecurityException("Requires permission " 9239 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9240 } 9241 9242 final IBinder.DeathRecipient death = new DeathRecipient() { 9243 @Override 9244 public void binderDied() { 9245 synchronized (this) { 9246 notifyAll(); 9247 } 9248 } 9249 }; 9250 9251 try { 9252 who.linkToDeath(death, 0); 9253 } catch (RemoteException e) { 9254 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9255 return; 9256 } 9257 9258 synchronized (this) { 9259 Watchdog.getInstance().setAllowRestart(allowRestart); 9260 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9261 synchronized (death) { 9262 while (who.isBinderAlive()) { 9263 try { 9264 death.wait(); 9265 } catch (InterruptedException e) { 9266 } 9267 } 9268 } 9269 Watchdog.getInstance().setAllowRestart(true); 9270 } 9271 } 9272 9273 @Override 9274 public void restart() { 9275 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9276 != PackageManager.PERMISSION_GRANTED) { 9277 throw new SecurityException("Requires permission " 9278 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9279 } 9280 9281 Log.i(TAG, "Sending shutdown broadcast..."); 9282 9283 BroadcastReceiver br = new BroadcastReceiver() { 9284 @Override public void onReceive(Context context, Intent intent) { 9285 // Now the broadcast is done, finish up the low-level shutdown. 9286 Log.i(TAG, "Shutting down activity manager..."); 9287 shutdown(10000); 9288 Log.i(TAG, "Shutdown complete, restarting!"); 9289 Process.killProcess(Process.myPid()); 9290 System.exit(10); 9291 } 9292 }; 9293 9294 // First send the high-level shut down broadcast. 9295 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9296 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9297 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9298 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9299 mContext.sendOrderedBroadcastAsUser(intent, 9300 UserHandle.ALL, null, br, mHandler, 0, null, null); 9301 */ 9302 br.onReceive(mContext, intent); 9303 } 9304 9305 private long getLowRamTimeSinceIdle(long now) { 9306 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9307 } 9308 9309 @Override 9310 public void performIdleMaintenance() { 9311 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9312 != PackageManager.PERMISSION_GRANTED) { 9313 throw new SecurityException("Requires permission " 9314 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9315 } 9316 9317 synchronized (this) { 9318 final long now = SystemClock.uptimeMillis(); 9319 final long timeSinceLastIdle = now - mLastIdleTime; 9320 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9321 mLastIdleTime = now; 9322 mLowRamTimeSinceLastIdle = 0; 9323 if (mLowRamStartTime != 0) { 9324 mLowRamStartTime = now; 9325 } 9326 9327 StringBuilder sb = new StringBuilder(128); 9328 sb.append("Idle maintenance over "); 9329 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9330 sb.append(" low RAM for "); 9331 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9332 Slog.i(TAG, sb.toString()); 9333 9334 // If at least 1/3 of our time since the last idle period has been spent 9335 // with RAM low, then we want to kill processes. 9336 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9337 9338 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9339 ProcessRecord proc = mLruProcesses.get(i); 9340 if (proc.notCachedSinceIdle) { 9341 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9342 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9343 if (doKilling && proc.initialIdlePss != 0 9344 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9345 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9346 + " from " + proc.initialIdlePss + ")"); 9347 } 9348 } 9349 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9350 proc.notCachedSinceIdle = true; 9351 proc.initialIdlePss = 0; 9352 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9353 isSleeping(), now); 9354 } 9355 } 9356 9357 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9358 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9359 } 9360 } 9361 9362 private void retrieveSettings() { 9363 final ContentResolver resolver = mContext.getContentResolver(); 9364 String debugApp = Settings.Global.getString( 9365 resolver, Settings.Global.DEBUG_APP); 9366 boolean waitForDebugger = Settings.Global.getInt( 9367 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9368 boolean alwaysFinishActivities = Settings.Global.getInt( 9369 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9370 boolean forceRtl = Settings.Global.getInt( 9371 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9372 // Transfer any global setting for forcing RTL layout, into a System Property 9373 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9374 9375 Configuration configuration = new Configuration(); 9376 Settings.System.getConfiguration(resolver, configuration); 9377 if (forceRtl) { 9378 // This will take care of setting the correct layout direction flags 9379 configuration.setLayoutDirection(configuration.locale); 9380 } 9381 9382 synchronized (this) { 9383 mDebugApp = mOrigDebugApp = debugApp; 9384 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9385 mAlwaysFinishActivities = alwaysFinishActivities; 9386 // This happens before any activities are started, so we can 9387 // change mConfiguration in-place. 9388 updateConfigurationLocked(configuration, null, false, true); 9389 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9390 } 9391 } 9392 9393 public boolean testIsSystemReady() { 9394 // no need to synchronize(this) just to read & return the value 9395 return mSystemReady; 9396 } 9397 9398 private static File getCalledPreBootReceiversFile() { 9399 File dataDir = Environment.getDataDirectory(); 9400 File systemDir = new File(dataDir, "system"); 9401 File fname = new File(systemDir, "called_pre_boots.dat"); 9402 return fname; 9403 } 9404 9405 static final int LAST_DONE_VERSION = 10000; 9406 9407 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9408 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9409 File file = getCalledPreBootReceiversFile(); 9410 FileInputStream fis = null; 9411 try { 9412 fis = new FileInputStream(file); 9413 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9414 int fvers = dis.readInt(); 9415 if (fvers == LAST_DONE_VERSION) { 9416 String vers = dis.readUTF(); 9417 String codename = dis.readUTF(); 9418 String build = dis.readUTF(); 9419 if (android.os.Build.VERSION.RELEASE.equals(vers) 9420 && android.os.Build.VERSION.CODENAME.equals(codename) 9421 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9422 int num = dis.readInt(); 9423 while (num > 0) { 9424 num--; 9425 String pkg = dis.readUTF(); 9426 String cls = dis.readUTF(); 9427 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9428 } 9429 } 9430 } 9431 } catch (FileNotFoundException e) { 9432 } catch (IOException e) { 9433 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9434 } finally { 9435 if (fis != null) { 9436 try { 9437 fis.close(); 9438 } catch (IOException e) { 9439 } 9440 } 9441 } 9442 return lastDoneReceivers; 9443 } 9444 9445 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9446 File file = getCalledPreBootReceiversFile(); 9447 FileOutputStream fos = null; 9448 DataOutputStream dos = null; 9449 try { 9450 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9451 fos = new FileOutputStream(file); 9452 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9453 dos.writeInt(LAST_DONE_VERSION); 9454 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9455 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9456 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9457 dos.writeInt(list.size()); 9458 for (int i=0; i<list.size(); i++) { 9459 dos.writeUTF(list.get(i).getPackageName()); 9460 dos.writeUTF(list.get(i).getClassName()); 9461 } 9462 } catch (IOException e) { 9463 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9464 file.delete(); 9465 } finally { 9466 FileUtils.sync(fos); 9467 if (dos != null) { 9468 try { 9469 dos.close(); 9470 } catch (IOException e) { 9471 // TODO Auto-generated catch block 9472 e.printStackTrace(); 9473 } 9474 } 9475 } 9476 } 9477 9478 public void systemReady(final Runnable goingCallback) { 9479 synchronized(this) { 9480 if (mSystemReady) { 9481 if (goingCallback != null) goingCallback.run(); 9482 return; 9483 } 9484 9485 // Check to see if there are any update receivers to run. 9486 if (!mDidUpdate) { 9487 if (mWaitingUpdate) { 9488 return; 9489 } 9490 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9491 List<ResolveInfo> ris = null; 9492 try { 9493 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9494 intent, null, 0, 0); 9495 } catch (RemoteException e) { 9496 } 9497 if (ris != null) { 9498 for (int i=ris.size()-1; i>=0; i--) { 9499 if ((ris.get(i).activityInfo.applicationInfo.flags 9500 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9501 ris.remove(i); 9502 } 9503 } 9504 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9505 9506 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9507 9508 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9509 for (int i=0; i<ris.size(); i++) { 9510 ActivityInfo ai = ris.get(i).activityInfo; 9511 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9512 if (lastDoneReceivers.contains(comp)) { 9513 // We already did the pre boot receiver for this app with the current 9514 // platform version, so don't do it again... 9515 ris.remove(i); 9516 i--; 9517 // ...however, do keep it as one that has been done, so we don't 9518 // forget about it when rewriting the file of last done receivers. 9519 doneReceivers.add(comp); 9520 } 9521 } 9522 9523 final int[] users = getUsersLocked(); 9524 for (int i=0; i<ris.size(); i++) { 9525 ActivityInfo ai = ris.get(i).activityInfo; 9526 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9527 doneReceivers.add(comp); 9528 intent.setComponent(comp); 9529 for (int j=0; j<users.length; j++) { 9530 IIntentReceiver finisher = null; 9531 if (i == ris.size()-1 && j == users.length-1) { 9532 finisher = new IIntentReceiver.Stub() { 9533 public void performReceive(Intent intent, int resultCode, 9534 String data, Bundle extras, boolean ordered, 9535 boolean sticky, int sendingUser) { 9536 // The raw IIntentReceiver interface is called 9537 // with the AM lock held, so redispatch to 9538 // execute our code without the lock. 9539 mHandler.post(new Runnable() { 9540 public void run() { 9541 synchronized (ActivityManagerService.this) { 9542 mDidUpdate = true; 9543 } 9544 writeLastDonePreBootReceivers(doneReceivers); 9545 showBootMessage(mContext.getText( 9546 R.string.android_upgrading_complete), 9547 false); 9548 systemReady(goingCallback); 9549 } 9550 }); 9551 } 9552 }; 9553 } 9554 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9555 + " for user " + users[j]); 9556 broadcastIntentLocked(null, null, intent, null, finisher, 9557 0, null, null, null, AppOpsManager.OP_NONE, 9558 true, false, MY_PID, Process.SYSTEM_UID, 9559 users[j]); 9560 if (finisher != null) { 9561 mWaitingUpdate = true; 9562 } 9563 } 9564 } 9565 } 9566 if (mWaitingUpdate) { 9567 return; 9568 } 9569 mDidUpdate = true; 9570 } 9571 9572 mAppOpsService.systemReady(); 9573 mUsageStatsService.systemReady(); 9574 mSystemReady = true; 9575 } 9576 9577 ArrayList<ProcessRecord> procsToKill = null; 9578 synchronized(mPidsSelfLocked) { 9579 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9580 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9581 if (!isAllowedWhileBooting(proc.info)){ 9582 if (procsToKill == null) { 9583 procsToKill = new ArrayList<ProcessRecord>(); 9584 } 9585 procsToKill.add(proc); 9586 } 9587 } 9588 } 9589 9590 synchronized(this) { 9591 if (procsToKill != null) { 9592 for (int i=procsToKill.size()-1; i>=0; i--) { 9593 ProcessRecord proc = procsToKill.get(i); 9594 Slog.i(TAG, "Removing system update proc: " + proc); 9595 removeProcessLocked(proc, true, false, "system update done"); 9596 } 9597 } 9598 9599 // Now that we have cleaned up any update processes, we 9600 // are ready to start launching real processes and know that 9601 // we won't trample on them any more. 9602 mProcessesReady = true; 9603 } 9604 9605 Slog.i(TAG, "System now ready"); 9606 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9607 SystemClock.uptimeMillis()); 9608 9609 synchronized(this) { 9610 // Make sure we have no pre-ready processes sitting around. 9611 9612 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9613 ResolveInfo ri = mContext.getPackageManager() 9614 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9615 STOCK_PM_FLAGS); 9616 CharSequence errorMsg = null; 9617 if (ri != null) { 9618 ActivityInfo ai = ri.activityInfo; 9619 ApplicationInfo app = ai.applicationInfo; 9620 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9621 mTopAction = Intent.ACTION_FACTORY_TEST; 9622 mTopData = null; 9623 mTopComponent = new ComponentName(app.packageName, 9624 ai.name); 9625 } else { 9626 errorMsg = mContext.getResources().getText( 9627 com.android.internal.R.string.factorytest_not_system); 9628 } 9629 } else { 9630 errorMsg = mContext.getResources().getText( 9631 com.android.internal.R.string.factorytest_no_action); 9632 } 9633 if (errorMsg != null) { 9634 mTopAction = null; 9635 mTopData = null; 9636 mTopComponent = null; 9637 Message msg = Message.obtain(); 9638 msg.what = SHOW_FACTORY_ERROR_MSG; 9639 msg.getData().putCharSequence("msg", errorMsg); 9640 mHandler.sendMessage(msg); 9641 } 9642 } 9643 } 9644 9645 retrieveSettings(); 9646 9647 synchronized (this) { 9648 readGrantedUriPermissionsLocked(); 9649 } 9650 9651 if (goingCallback != null) goingCallback.run(); 9652 9653 mSystemServiceManager.startUser(mCurrentUserId); 9654 9655 synchronized (this) { 9656 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9657 try { 9658 List apps = AppGlobals.getPackageManager(). 9659 getPersistentApplications(STOCK_PM_FLAGS); 9660 if (apps != null) { 9661 int N = apps.size(); 9662 int i; 9663 for (i=0; i<N; i++) { 9664 ApplicationInfo info 9665 = (ApplicationInfo)apps.get(i); 9666 if (info != null && 9667 !info.packageName.equals("android")) { 9668 addAppLocked(info, false); 9669 } 9670 } 9671 } 9672 } catch (RemoteException ex) { 9673 // pm is in same process, this will never happen. 9674 } 9675 } 9676 9677 // Start up initial activity. 9678 mBooting = true; 9679 9680 try { 9681 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9682 Message msg = Message.obtain(); 9683 msg.what = SHOW_UID_ERROR_MSG; 9684 mHandler.sendMessage(msg); 9685 } 9686 } catch (RemoteException e) { 9687 } 9688 9689 long ident = Binder.clearCallingIdentity(); 9690 try { 9691 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9692 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9693 | Intent.FLAG_RECEIVER_FOREGROUND); 9694 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9695 broadcastIntentLocked(null, null, intent, 9696 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9697 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9698 intent = new Intent(Intent.ACTION_USER_STARTING); 9699 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9700 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9701 broadcastIntentLocked(null, null, intent, 9702 null, new IIntentReceiver.Stub() { 9703 @Override 9704 public void performReceive(Intent intent, int resultCode, String data, 9705 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9706 throws RemoteException { 9707 } 9708 }, 0, null, null, 9709 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9710 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9711 } catch (Throwable t) { 9712 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 9713 } finally { 9714 Binder.restoreCallingIdentity(ident); 9715 } 9716 mStackSupervisor.resumeTopActivitiesLocked(); 9717 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9718 } 9719 } 9720 9721 private boolean makeAppCrashingLocked(ProcessRecord app, 9722 String shortMsg, String longMsg, String stackTrace) { 9723 app.crashing = true; 9724 app.crashingReport = generateProcessError(app, 9725 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9726 startAppProblemLocked(app); 9727 app.stopFreezingAllLocked(); 9728 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9729 } 9730 9731 private void makeAppNotRespondingLocked(ProcessRecord app, 9732 String activity, String shortMsg, String longMsg) { 9733 app.notResponding = true; 9734 app.notRespondingReport = generateProcessError(app, 9735 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9736 activity, shortMsg, longMsg, null); 9737 startAppProblemLocked(app); 9738 app.stopFreezingAllLocked(); 9739 } 9740 9741 /** 9742 * Generate a process error record, suitable for attachment to a ProcessRecord. 9743 * 9744 * @param app The ProcessRecord in which the error occurred. 9745 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9746 * ActivityManager.AppErrorStateInfo 9747 * @param activity The activity associated with the crash, if known. 9748 * @param shortMsg Short message describing the crash. 9749 * @param longMsg Long message describing the crash. 9750 * @param stackTrace Full crash stack trace, may be null. 9751 * 9752 * @return Returns a fully-formed AppErrorStateInfo record. 9753 */ 9754 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9755 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9756 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9757 9758 report.condition = condition; 9759 report.processName = app.processName; 9760 report.pid = app.pid; 9761 report.uid = app.info.uid; 9762 report.tag = activity; 9763 report.shortMsg = shortMsg; 9764 report.longMsg = longMsg; 9765 report.stackTrace = stackTrace; 9766 9767 return report; 9768 } 9769 9770 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9771 synchronized (this) { 9772 app.crashing = false; 9773 app.crashingReport = null; 9774 app.notResponding = false; 9775 app.notRespondingReport = null; 9776 if (app.anrDialog == fromDialog) { 9777 app.anrDialog = null; 9778 } 9779 if (app.waitDialog == fromDialog) { 9780 app.waitDialog = null; 9781 } 9782 if (app.pid > 0 && app.pid != MY_PID) { 9783 handleAppCrashLocked(app, null, null, null); 9784 killUnneededProcessLocked(app, "user request after error"); 9785 } 9786 } 9787 } 9788 9789 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9790 String stackTrace) { 9791 long now = SystemClock.uptimeMillis(); 9792 9793 Long crashTime; 9794 if (!app.isolated) { 9795 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9796 } else { 9797 crashTime = null; 9798 } 9799 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9800 // This process loses! 9801 Slog.w(TAG, "Process " + app.info.processName 9802 + " has crashed too many times: killing!"); 9803 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9804 app.userId, app.info.processName, app.uid); 9805 mStackSupervisor.handleAppCrashLocked(app); 9806 if (!app.persistent) { 9807 // We don't want to start this process again until the user 9808 // explicitly does so... but for persistent process, we really 9809 // need to keep it running. If a persistent process is actually 9810 // repeatedly crashing, then badness for everyone. 9811 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9812 app.info.processName); 9813 if (!app.isolated) { 9814 // XXX We don't have a way to mark isolated processes 9815 // as bad, since they don't have a peristent identity. 9816 mBadProcesses.put(app.info.processName, app.uid, 9817 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9818 mProcessCrashTimes.remove(app.info.processName, app.uid); 9819 } 9820 app.bad = true; 9821 app.removed = true; 9822 // Don't let services in this process be restarted and potentially 9823 // annoy the user repeatedly. Unless it is persistent, since those 9824 // processes run critical code. 9825 removeProcessLocked(app, false, false, "crash"); 9826 mStackSupervisor.resumeTopActivitiesLocked(); 9827 return false; 9828 } 9829 mStackSupervisor.resumeTopActivitiesLocked(); 9830 } else { 9831 mStackSupervisor.finishTopRunningActivityLocked(app); 9832 } 9833 9834 // Bump up the crash count of any services currently running in the proc. 9835 for (int i=app.services.size()-1; i>=0; i--) { 9836 // Any services running in the application need to be placed 9837 // back in the pending list. 9838 ServiceRecord sr = app.services.valueAt(i); 9839 sr.crashCount++; 9840 } 9841 9842 // If the crashing process is what we consider to be the "home process" and it has been 9843 // replaced by a third-party app, clear the package preferred activities from packages 9844 // with a home activity running in the process to prevent a repeatedly crashing app 9845 // from blocking the user to manually clear the list. 9846 final ArrayList<ActivityRecord> activities = app.activities; 9847 if (app == mHomeProcess && activities.size() > 0 9848 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9849 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9850 final ActivityRecord r = activities.get(activityNdx); 9851 if (r.isHomeActivity()) { 9852 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9853 try { 9854 ActivityThread.getPackageManager() 9855 .clearPackagePreferredActivities(r.packageName); 9856 } catch (RemoteException c) { 9857 // pm is in same process, this will never happen. 9858 } 9859 } 9860 } 9861 } 9862 9863 if (!app.isolated) { 9864 // XXX Can't keep track of crash times for isolated processes, 9865 // because they don't have a perisistent identity. 9866 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9867 } 9868 9869 return true; 9870 } 9871 9872 void startAppProblemLocked(ProcessRecord app) { 9873 if (app.userId == mCurrentUserId) { 9874 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9875 mContext, app.info.packageName, app.info.flags); 9876 } else { 9877 // If this app is not running under the current user, then we 9878 // can't give it a report button because that would require 9879 // launching the report UI under a different user. 9880 app.errorReportReceiver = null; 9881 } 9882 skipCurrentReceiverLocked(app); 9883 } 9884 9885 void skipCurrentReceiverLocked(ProcessRecord app) { 9886 for (BroadcastQueue queue : mBroadcastQueues) { 9887 queue.skipCurrentReceiverLocked(app); 9888 } 9889 } 9890 9891 /** 9892 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9893 * The application process will exit immediately after this call returns. 9894 * @param app object of the crashing app, null for the system server 9895 * @param crashInfo describing the exception 9896 */ 9897 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9898 ProcessRecord r = findAppProcess(app, "Crash"); 9899 final String processName = app == null ? "system_server" 9900 : (r == null ? "unknown" : r.processName); 9901 9902 handleApplicationCrashInner("crash", r, processName, crashInfo); 9903 } 9904 9905 /* Native crash reporting uses this inner version because it needs to be somewhat 9906 * decoupled from the AM-managed cleanup lifecycle 9907 */ 9908 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9909 ApplicationErrorReport.CrashInfo crashInfo) { 9910 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9911 UserHandle.getUserId(Binder.getCallingUid()), processName, 9912 r == null ? -1 : r.info.flags, 9913 crashInfo.exceptionClassName, 9914 crashInfo.exceptionMessage, 9915 crashInfo.throwFileName, 9916 crashInfo.throwLineNumber); 9917 9918 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9919 9920 crashApplication(r, crashInfo); 9921 } 9922 9923 public void handleApplicationStrictModeViolation( 9924 IBinder app, 9925 int violationMask, 9926 StrictMode.ViolationInfo info) { 9927 ProcessRecord r = findAppProcess(app, "StrictMode"); 9928 if (r == null) { 9929 return; 9930 } 9931 9932 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9933 Integer stackFingerprint = info.hashCode(); 9934 boolean logIt = true; 9935 synchronized (mAlreadyLoggedViolatedStacks) { 9936 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9937 logIt = false; 9938 // TODO: sub-sample into EventLog for these, with 9939 // the info.durationMillis? Then we'd get 9940 // the relative pain numbers, without logging all 9941 // the stack traces repeatedly. We'd want to do 9942 // likewise in the client code, which also does 9943 // dup suppression, before the Binder call. 9944 } else { 9945 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9946 mAlreadyLoggedViolatedStacks.clear(); 9947 } 9948 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9949 } 9950 } 9951 if (logIt) { 9952 logStrictModeViolationToDropBox(r, info); 9953 } 9954 } 9955 9956 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9957 AppErrorResult result = new AppErrorResult(); 9958 synchronized (this) { 9959 final long origId = Binder.clearCallingIdentity(); 9960 9961 Message msg = Message.obtain(); 9962 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9963 HashMap<String, Object> data = new HashMap<String, Object>(); 9964 data.put("result", result); 9965 data.put("app", r); 9966 data.put("violationMask", violationMask); 9967 data.put("info", info); 9968 msg.obj = data; 9969 mHandler.sendMessage(msg); 9970 9971 Binder.restoreCallingIdentity(origId); 9972 } 9973 int res = result.get(); 9974 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9975 } 9976 } 9977 9978 // Depending on the policy in effect, there could be a bunch of 9979 // these in quick succession so we try to batch these together to 9980 // minimize disk writes, number of dropbox entries, and maximize 9981 // compression, by having more fewer, larger records. 9982 private void logStrictModeViolationToDropBox( 9983 ProcessRecord process, 9984 StrictMode.ViolationInfo info) { 9985 if (info == null) { 9986 return; 9987 } 9988 final boolean isSystemApp = process == null || 9989 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9990 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9991 final String processName = process == null ? "unknown" : process.processName; 9992 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9993 final DropBoxManager dbox = (DropBoxManager) 9994 mContext.getSystemService(Context.DROPBOX_SERVICE); 9995 9996 // Exit early if the dropbox isn't configured to accept this report type. 9997 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9998 9999 boolean bufferWasEmpty; 10000 boolean needsFlush; 10001 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10002 synchronized (sb) { 10003 bufferWasEmpty = sb.length() == 0; 10004 appendDropBoxProcessHeaders(process, processName, sb); 10005 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10006 sb.append("System-App: ").append(isSystemApp).append("\n"); 10007 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10008 if (info.violationNumThisLoop != 0) { 10009 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10010 } 10011 if (info.numAnimationsRunning != 0) { 10012 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10013 } 10014 if (info.broadcastIntentAction != null) { 10015 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10016 } 10017 if (info.durationMillis != -1) { 10018 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10019 } 10020 if (info.numInstances != -1) { 10021 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10022 } 10023 if (info.tags != null) { 10024 for (String tag : info.tags) { 10025 sb.append("Span-Tag: ").append(tag).append("\n"); 10026 } 10027 } 10028 sb.append("\n"); 10029 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10030 sb.append(info.crashInfo.stackTrace); 10031 } 10032 sb.append("\n"); 10033 10034 // Only buffer up to ~64k. Various logging bits truncate 10035 // things at 128k. 10036 needsFlush = (sb.length() > 64 * 1024); 10037 } 10038 10039 // Flush immediately if the buffer's grown too large, or this 10040 // is a non-system app. Non-system apps are isolated with a 10041 // different tag & policy and not batched. 10042 // 10043 // Batching is useful during internal testing with 10044 // StrictMode settings turned up high. Without batching, 10045 // thousands of separate files could be created on boot. 10046 if (!isSystemApp || needsFlush) { 10047 new Thread("Error dump: " + dropboxTag) { 10048 @Override 10049 public void run() { 10050 String report; 10051 synchronized (sb) { 10052 report = sb.toString(); 10053 sb.delete(0, sb.length()); 10054 sb.trimToSize(); 10055 } 10056 if (report.length() != 0) { 10057 dbox.addText(dropboxTag, report); 10058 } 10059 } 10060 }.start(); 10061 return; 10062 } 10063 10064 // System app batching: 10065 if (!bufferWasEmpty) { 10066 // An existing dropbox-writing thread is outstanding, so 10067 // we don't need to start it up. The existing thread will 10068 // catch the buffer appends we just did. 10069 return; 10070 } 10071 10072 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10073 // (After this point, we shouldn't access AMS internal data structures.) 10074 new Thread("Error dump: " + dropboxTag) { 10075 @Override 10076 public void run() { 10077 // 5 second sleep to let stacks arrive and be batched together 10078 try { 10079 Thread.sleep(5000); // 5 seconds 10080 } catch (InterruptedException e) {} 10081 10082 String errorReport; 10083 synchronized (mStrictModeBuffer) { 10084 errorReport = mStrictModeBuffer.toString(); 10085 if (errorReport.length() == 0) { 10086 return; 10087 } 10088 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10089 mStrictModeBuffer.trimToSize(); 10090 } 10091 dbox.addText(dropboxTag, errorReport); 10092 } 10093 }.start(); 10094 } 10095 10096 /** 10097 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10098 * @param app object of the crashing app, null for the system server 10099 * @param tag reported by the caller 10100 * @param crashInfo describing the context of the error 10101 * @return true if the process should exit immediately (WTF is fatal) 10102 */ 10103 public boolean handleApplicationWtf(IBinder app, String tag, 10104 ApplicationErrorReport.CrashInfo crashInfo) { 10105 ProcessRecord r = findAppProcess(app, "WTF"); 10106 final String processName = app == null ? "system_server" 10107 : (r == null ? "unknown" : r.processName); 10108 10109 EventLog.writeEvent(EventLogTags.AM_WTF, 10110 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10111 processName, 10112 r == null ? -1 : r.info.flags, 10113 tag, crashInfo.exceptionMessage); 10114 10115 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10116 10117 if (r != null && r.pid != Process.myPid() && 10118 Settings.Global.getInt(mContext.getContentResolver(), 10119 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10120 crashApplication(r, crashInfo); 10121 return true; 10122 } else { 10123 return false; 10124 } 10125 } 10126 10127 /** 10128 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10129 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10130 */ 10131 private ProcessRecord findAppProcess(IBinder app, String reason) { 10132 if (app == null) { 10133 return null; 10134 } 10135 10136 synchronized (this) { 10137 final int NP = mProcessNames.getMap().size(); 10138 for (int ip=0; ip<NP; ip++) { 10139 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10140 final int NA = apps.size(); 10141 for (int ia=0; ia<NA; ia++) { 10142 ProcessRecord p = apps.valueAt(ia); 10143 if (p.thread != null && p.thread.asBinder() == app) { 10144 return p; 10145 } 10146 } 10147 } 10148 10149 Slog.w(TAG, "Can't find mystery application for " + reason 10150 + " from pid=" + Binder.getCallingPid() 10151 + " uid=" + Binder.getCallingUid() + ": " + app); 10152 return null; 10153 } 10154 } 10155 10156 /** 10157 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10158 * to append various headers to the dropbox log text. 10159 */ 10160 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10161 StringBuilder sb) { 10162 // Watchdog thread ends up invoking this function (with 10163 // a null ProcessRecord) to add the stack file to dropbox. 10164 // Do not acquire a lock on this (am) in such cases, as it 10165 // could cause a potential deadlock, if and when watchdog 10166 // is invoked due to unavailability of lock on am and it 10167 // would prevent watchdog from killing system_server. 10168 if (process == null) { 10169 sb.append("Process: ").append(processName).append("\n"); 10170 return; 10171 } 10172 // Note: ProcessRecord 'process' is guarded by the service 10173 // instance. (notably process.pkgList, which could otherwise change 10174 // concurrently during execution of this method) 10175 synchronized (this) { 10176 sb.append("Process: ").append(processName).append("\n"); 10177 int flags = process.info.flags; 10178 IPackageManager pm = AppGlobals.getPackageManager(); 10179 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10180 for (int ip=0; ip<process.pkgList.size(); ip++) { 10181 String pkg = process.pkgList.keyAt(ip); 10182 sb.append("Package: ").append(pkg); 10183 try { 10184 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10185 if (pi != null) { 10186 sb.append(" v").append(pi.versionCode); 10187 if (pi.versionName != null) { 10188 sb.append(" (").append(pi.versionName).append(")"); 10189 } 10190 } 10191 } catch (RemoteException e) { 10192 Slog.e(TAG, "Error getting package info: " + pkg, e); 10193 } 10194 sb.append("\n"); 10195 } 10196 } 10197 } 10198 10199 private static String processClass(ProcessRecord process) { 10200 if (process == null || process.pid == MY_PID) { 10201 return "system_server"; 10202 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10203 return "system_app"; 10204 } else { 10205 return "data_app"; 10206 } 10207 } 10208 10209 /** 10210 * Write a description of an error (crash, WTF, ANR) to the drop box. 10211 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10212 * @param process which caused the error, null means the system server 10213 * @param activity which triggered the error, null if unknown 10214 * @param parent activity related to the error, null if unknown 10215 * @param subject line related to the error, null if absent 10216 * @param report in long form describing the error, null if absent 10217 * @param logFile to include in the report, null if none 10218 * @param crashInfo giving an application stack trace, null if absent 10219 */ 10220 public void addErrorToDropBox(String eventType, 10221 ProcessRecord process, String processName, ActivityRecord activity, 10222 ActivityRecord parent, String subject, 10223 final String report, final File logFile, 10224 final ApplicationErrorReport.CrashInfo crashInfo) { 10225 // NOTE -- this must never acquire the ActivityManagerService lock, 10226 // otherwise the watchdog may be prevented from resetting the system. 10227 10228 final String dropboxTag = processClass(process) + "_" + eventType; 10229 final DropBoxManager dbox = (DropBoxManager) 10230 mContext.getSystemService(Context.DROPBOX_SERVICE); 10231 10232 // Exit early if the dropbox isn't configured to accept this report type. 10233 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10234 10235 final StringBuilder sb = new StringBuilder(1024); 10236 appendDropBoxProcessHeaders(process, processName, sb); 10237 if (activity != null) { 10238 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10239 } 10240 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10241 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10242 } 10243 if (parent != null && parent != activity) { 10244 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10245 } 10246 if (subject != null) { 10247 sb.append("Subject: ").append(subject).append("\n"); 10248 } 10249 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10250 if (Debug.isDebuggerConnected()) { 10251 sb.append("Debugger: Connected\n"); 10252 } 10253 sb.append("\n"); 10254 10255 // Do the rest in a worker thread to avoid blocking the caller on I/O 10256 // (After this point, we shouldn't access AMS internal data structures.) 10257 Thread worker = new Thread("Error dump: " + dropboxTag) { 10258 @Override 10259 public void run() { 10260 if (report != null) { 10261 sb.append(report); 10262 } 10263 if (logFile != null) { 10264 try { 10265 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10266 "\n\n[[TRUNCATED]]")); 10267 } catch (IOException e) { 10268 Slog.e(TAG, "Error reading " + logFile, e); 10269 } 10270 } 10271 if (crashInfo != null && crashInfo.stackTrace != null) { 10272 sb.append(crashInfo.stackTrace); 10273 } 10274 10275 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10276 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10277 if (lines > 0) { 10278 sb.append("\n"); 10279 10280 // Merge several logcat streams, and take the last N lines 10281 InputStreamReader input = null; 10282 try { 10283 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10284 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10285 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10286 10287 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10288 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10289 input = new InputStreamReader(logcat.getInputStream()); 10290 10291 int num; 10292 char[] buf = new char[8192]; 10293 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10294 } catch (IOException e) { 10295 Slog.e(TAG, "Error running logcat", e); 10296 } finally { 10297 if (input != null) try { input.close(); } catch (IOException e) {} 10298 } 10299 } 10300 10301 dbox.addText(dropboxTag, sb.toString()); 10302 } 10303 }; 10304 10305 if (process == null) { 10306 // If process is null, we are being called from some internal code 10307 // and may be about to die -- run this synchronously. 10308 worker.run(); 10309 } else { 10310 worker.start(); 10311 } 10312 } 10313 10314 /** 10315 * Bring up the "unexpected error" dialog box for a crashing app. 10316 * Deal with edge cases (intercepts from instrumented applications, 10317 * ActivityController, error intent receivers, that sort of thing). 10318 * @param r the application crashing 10319 * @param crashInfo describing the failure 10320 */ 10321 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10322 long timeMillis = System.currentTimeMillis(); 10323 String shortMsg = crashInfo.exceptionClassName; 10324 String longMsg = crashInfo.exceptionMessage; 10325 String stackTrace = crashInfo.stackTrace; 10326 if (shortMsg != null && longMsg != null) { 10327 longMsg = shortMsg + ": " + longMsg; 10328 } else if (shortMsg != null) { 10329 longMsg = shortMsg; 10330 } 10331 10332 AppErrorResult result = new AppErrorResult(); 10333 synchronized (this) { 10334 if (mController != null) { 10335 try { 10336 String name = r != null ? r.processName : null; 10337 int pid = r != null ? r.pid : Binder.getCallingPid(); 10338 if (!mController.appCrashed(name, pid, 10339 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10340 Slog.w(TAG, "Force-killing crashed app " + name 10341 + " at watcher's request"); 10342 Process.killProcess(pid); 10343 return; 10344 } 10345 } catch (RemoteException e) { 10346 mController = null; 10347 Watchdog.getInstance().setActivityController(null); 10348 } 10349 } 10350 10351 final long origId = Binder.clearCallingIdentity(); 10352 10353 // If this process is running instrumentation, finish it. 10354 if (r != null && r.instrumentationClass != null) { 10355 Slog.w(TAG, "Error in app " + r.processName 10356 + " running instrumentation " + r.instrumentationClass + ":"); 10357 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10358 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10359 Bundle info = new Bundle(); 10360 info.putString("shortMsg", shortMsg); 10361 info.putString("longMsg", longMsg); 10362 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10363 Binder.restoreCallingIdentity(origId); 10364 return; 10365 } 10366 10367 // If we can't identify the process or it's already exceeded its crash quota, 10368 // quit right away without showing a crash dialog. 10369 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10370 Binder.restoreCallingIdentity(origId); 10371 return; 10372 } 10373 10374 Message msg = Message.obtain(); 10375 msg.what = SHOW_ERROR_MSG; 10376 HashMap data = new HashMap(); 10377 data.put("result", result); 10378 data.put("app", r); 10379 msg.obj = data; 10380 mHandler.sendMessage(msg); 10381 10382 Binder.restoreCallingIdentity(origId); 10383 } 10384 10385 int res = result.get(); 10386 10387 Intent appErrorIntent = null; 10388 synchronized (this) { 10389 if (r != null && !r.isolated) { 10390 // XXX Can't keep track of crash time for isolated processes, 10391 // since they don't have a persistent identity. 10392 mProcessCrashTimes.put(r.info.processName, r.uid, 10393 SystemClock.uptimeMillis()); 10394 } 10395 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10396 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10397 } 10398 } 10399 10400 if (appErrorIntent != null) { 10401 try { 10402 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10403 } catch (ActivityNotFoundException e) { 10404 Slog.w(TAG, "bug report receiver dissappeared", e); 10405 } 10406 } 10407 } 10408 10409 Intent createAppErrorIntentLocked(ProcessRecord r, 10410 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10411 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10412 if (report == null) { 10413 return null; 10414 } 10415 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10416 result.setComponent(r.errorReportReceiver); 10417 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10418 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10419 return result; 10420 } 10421 10422 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10423 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10424 if (r.errorReportReceiver == null) { 10425 return null; 10426 } 10427 10428 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10429 return null; 10430 } 10431 10432 ApplicationErrorReport report = new ApplicationErrorReport(); 10433 report.packageName = r.info.packageName; 10434 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10435 report.processName = r.processName; 10436 report.time = timeMillis; 10437 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10438 10439 if (r.crashing || r.forceCrashReport) { 10440 report.type = ApplicationErrorReport.TYPE_CRASH; 10441 report.crashInfo = crashInfo; 10442 } else if (r.notResponding) { 10443 report.type = ApplicationErrorReport.TYPE_ANR; 10444 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10445 10446 report.anrInfo.activity = r.notRespondingReport.tag; 10447 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10448 report.anrInfo.info = r.notRespondingReport.longMsg; 10449 } 10450 10451 return report; 10452 } 10453 10454 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10455 enforceNotIsolatedCaller("getProcessesInErrorState"); 10456 // assume our apps are happy - lazy create the list 10457 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10458 10459 final boolean allUsers = ActivityManager.checkUidPermission( 10460 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10461 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10462 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10463 10464 synchronized (this) { 10465 10466 // iterate across all processes 10467 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10468 ProcessRecord app = mLruProcesses.get(i); 10469 if (!allUsers && app.userId != userId) { 10470 continue; 10471 } 10472 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10473 // This one's in trouble, so we'll generate a report for it 10474 // crashes are higher priority (in case there's a crash *and* an anr) 10475 ActivityManager.ProcessErrorStateInfo report = null; 10476 if (app.crashing) { 10477 report = app.crashingReport; 10478 } else if (app.notResponding) { 10479 report = app.notRespondingReport; 10480 } 10481 10482 if (report != null) { 10483 if (errList == null) { 10484 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10485 } 10486 errList.add(report); 10487 } else { 10488 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10489 " crashing = " + app.crashing + 10490 " notResponding = " + app.notResponding); 10491 } 10492 } 10493 } 10494 } 10495 10496 return errList; 10497 } 10498 10499 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10500 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10501 if (currApp != null) { 10502 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10503 } 10504 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10505 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10506 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10507 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10508 if (currApp != null) { 10509 currApp.lru = 0; 10510 } 10511 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10512 } else if (adj >= ProcessList.SERVICE_ADJ) { 10513 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10514 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10515 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10516 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10517 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10518 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10519 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10520 } else { 10521 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10522 } 10523 } 10524 10525 private void fillInProcMemInfo(ProcessRecord app, 10526 ActivityManager.RunningAppProcessInfo outInfo) { 10527 outInfo.pid = app.pid; 10528 outInfo.uid = app.info.uid; 10529 if (mHeavyWeightProcess == app) { 10530 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10531 } 10532 if (app.persistent) { 10533 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10534 } 10535 if (app.activities.size() > 0) { 10536 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10537 } 10538 outInfo.lastTrimLevel = app.trimMemoryLevel; 10539 int adj = app.curAdj; 10540 outInfo.importance = oomAdjToImportance(adj, outInfo); 10541 outInfo.importanceReasonCode = app.adjTypeCode; 10542 outInfo.processState = app.curProcState; 10543 } 10544 10545 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10546 enforceNotIsolatedCaller("getRunningAppProcesses"); 10547 // Lazy instantiation of list 10548 List<ActivityManager.RunningAppProcessInfo> runList = null; 10549 final boolean allUsers = ActivityManager.checkUidPermission( 10550 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10551 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10552 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10553 synchronized (this) { 10554 // Iterate across all processes 10555 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10556 ProcessRecord app = mLruProcesses.get(i); 10557 if (!allUsers && app.userId != userId) { 10558 continue; 10559 } 10560 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10561 // Generate process state info for running application 10562 ActivityManager.RunningAppProcessInfo currApp = 10563 new ActivityManager.RunningAppProcessInfo(app.processName, 10564 app.pid, app.getPackageList()); 10565 fillInProcMemInfo(app, currApp); 10566 if (app.adjSource instanceof ProcessRecord) { 10567 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10568 currApp.importanceReasonImportance = oomAdjToImportance( 10569 app.adjSourceOom, null); 10570 } else if (app.adjSource instanceof ActivityRecord) { 10571 ActivityRecord r = (ActivityRecord)app.adjSource; 10572 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10573 } 10574 if (app.adjTarget instanceof ComponentName) { 10575 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10576 } 10577 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10578 // + " lru=" + currApp.lru); 10579 if (runList == null) { 10580 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10581 } 10582 runList.add(currApp); 10583 } 10584 } 10585 } 10586 return runList; 10587 } 10588 10589 public List<ApplicationInfo> getRunningExternalApplications() { 10590 enforceNotIsolatedCaller("getRunningExternalApplications"); 10591 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10592 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10593 if (runningApps != null && runningApps.size() > 0) { 10594 Set<String> extList = new HashSet<String>(); 10595 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10596 if (app.pkgList != null) { 10597 for (String pkg : app.pkgList) { 10598 extList.add(pkg); 10599 } 10600 } 10601 } 10602 IPackageManager pm = AppGlobals.getPackageManager(); 10603 for (String pkg : extList) { 10604 try { 10605 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10606 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10607 retList.add(info); 10608 } 10609 } catch (RemoteException e) { 10610 } 10611 } 10612 } 10613 return retList; 10614 } 10615 10616 @Override 10617 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10618 enforceNotIsolatedCaller("getMyMemoryState"); 10619 synchronized (this) { 10620 ProcessRecord proc; 10621 synchronized (mPidsSelfLocked) { 10622 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10623 } 10624 fillInProcMemInfo(proc, outInfo); 10625 } 10626 } 10627 10628 @Override 10629 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10630 if (checkCallingPermission(android.Manifest.permission.DUMP) 10631 != PackageManager.PERMISSION_GRANTED) { 10632 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10633 + Binder.getCallingPid() 10634 + ", uid=" + Binder.getCallingUid() 10635 + " without permission " 10636 + android.Manifest.permission.DUMP); 10637 return; 10638 } 10639 10640 boolean dumpAll = false; 10641 boolean dumpClient = false; 10642 String dumpPackage = null; 10643 10644 int opti = 0; 10645 while (opti < args.length) { 10646 String opt = args[opti]; 10647 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10648 break; 10649 } 10650 opti++; 10651 if ("-a".equals(opt)) { 10652 dumpAll = true; 10653 } else if ("-c".equals(opt)) { 10654 dumpClient = true; 10655 } else if ("-h".equals(opt)) { 10656 pw.println("Activity manager dump options:"); 10657 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10658 pw.println(" cmd may be one of:"); 10659 pw.println(" a[ctivities]: activity stack state"); 10660 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10661 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10662 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10663 pw.println(" o[om]: out of memory management"); 10664 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10665 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10666 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10667 pw.println(" service [COMP_SPEC]: service client-side state"); 10668 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10669 pw.println(" all: dump all activities"); 10670 pw.println(" top: dump the top activity"); 10671 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10672 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10673 pw.println(" a partial substring in a component name, a"); 10674 pw.println(" hex object identifier."); 10675 pw.println(" -a: include all available server state."); 10676 pw.println(" -c: include client state."); 10677 return; 10678 } else { 10679 pw.println("Unknown argument: " + opt + "; use -h for help"); 10680 } 10681 } 10682 10683 long origId = Binder.clearCallingIdentity(); 10684 boolean more = false; 10685 // Is the caller requesting to dump a particular piece of data? 10686 if (opti < args.length) { 10687 String cmd = args[opti]; 10688 opti++; 10689 if ("activities".equals(cmd) || "a".equals(cmd)) { 10690 synchronized (this) { 10691 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10692 } 10693 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10694 String[] newArgs; 10695 String name; 10696 if (opti >= args.length) { 10697 name = null; 10698 newArgs = EMPTY_STRING_ARRAY; 10699 } else { 10700 name = args[opti]; 10701 opti++; 10702 newArgs = new String[args.length - opti]; 10703 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10704 args.length - opti); 10705 } 10706 synchronized (this) { 10707 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10708 } 10709 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10710 String[] newArgs; 10711 String name; 10712 if (opti >= args.length) { 10713 name = null; 10714 newArgs = EMPTY_STRING_ARRAY; 10715 } else { 10716 name = args[opti]; 10717 opti++; 10718 newArgs = new String[args.length - opti]; 10719 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10720 args.length - opti); 10721 } 10722 synchronized (this) { 10723 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10724 } 10725 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10726 String[] newArgs; 10727 String name; 10728 if (opti >= args.length) { 10729 name = null; 10730 newArgs = EMPTY_STRING_ARRAY; 10731 } else { 10732 name = args[opti]; 10733 opti++; 10734 newArgs = new String[args.length - opti]; 10735 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10736 args.length - opti); 10737 } 10738 synchronized (this) { 10739 dumpProcessesLocked(fd, pw, args, opti, true, name); 10740 } 10741 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10742 synchronized (this) { 10743 dumpOomLocked(fd, pw, args, opti, true); 10744 } 10745 } else if ("provider".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, args.length - opti); 10756 } 10757 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10758 pw.println("No providers match: " + name); 10759 pw.println("Use -h for help."); 10760 } 10761 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10762 synchronized (this) { 10763 dumpProvidersLocked(fd, pw, args, opti, true, null); 10764 } 10765 } else if ("service".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, 10776 args.length - opti); 10777 } 10778 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10779 pw.println("No services match: " + name); 10780 pw.println("Use -h for help."); 10781 } 10782 } else if ("package".equals(cmd)) { 10783 String[] newArgs; 10784 if (opti >= args.length) { 10785 pw.println("package: no package name specified"); 10786 pw.println("Use -h for help."); 10787 } else { 10788 dumpPackage = args[opti]; 10789 opti++; 10790 newArgs = new String[args.length - opti]; 10791 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10792 args.length - opti); 10793 args = newArgs; 10794 opti = 0; 10795 more = true; 10796 } 10797 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10798 synchronized (this) { 10799 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10800 } 10801 } else { 10802 // Dumping a single activity? 10803 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10804 pw.println("Bad activity command, or no activities match: " + cmd); 10805 pw.println("Use -h for help."); 10806 } 10807 } 10808 if (!more) { 10809 Binder.restoreCallingIdentity(origId); 10810 return; 10811 } 10812 } 10813 10814 // No piece of data specified, dump everything. 10815 synchronized (this) { 10816 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10817 pw.println(); 10818 if (dumpAll) { 10819 pw.println("-------------------------------------------------------------------------------"); 10820 } 10821 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10822 pw.println(); 10823 if (dumpAll) { 10824 pw.println("-------------------------------------------------------------------------------"); 10825 } 10826 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10827 pw.println(); 10828 if (dumpAll) { 10829 pw.println("-------------------------------------------------------------------------------"); 10830 } 10831 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10832 pw.println(); 10833 if (dumpAll) { 10834 pw.println("-------------------------------------------------------------------------------"); 10835 } 10836 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10837 pw.println(); 10838 if (dumpAll) { 10839 pw.println("-------------------------------------------------------------------------------"); 10840 } 10841 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10842 } 10843 Binder.restoreCallingIdentity(origId); 10844 } 10845 10846 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10847 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10848 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10849 10850 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10851 dumpPackage); 10852 boolean needSep = printedAnything; 10853 10854 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10855 dumpPackage, needSep, " mFocusedActivity: "); 10856 if (printed) { 10857 printedAnything = true; 10858 needSep = false; 10859 } 10860 10861 if (dumpPackage == null) { 10862 if (needSep) { 10863 pw.println(); 10864 } 10865 needSep = true; 10866 printedAnything = true; 10867 mStackSupervisor.dump(pw, " "); 10868 } 10869 10870 if (mRecentTasks.size() > 0) { 10871 boolean printedHeader = false; 10872 10873 final int N = mRecentTasks.size(); 10874 for (int i=0; i<N; i++) { 10875 TaskRecord tr = mRecentTasks.get(i); 10876 if (dumpPackage != null) { 10877 if (tr.realActivity == null || 10878 !dumpPackage.equals(tr.realActivity)) { 10879 continue; 10880 } 10881 } 10882 if (!printedHeader) { 10883 if (needSep) { 10884 pw.println(); 10885 } 10886 pw.println(" Recent tasks:"); 10887 printedHeader = true; 10888 printedAnything = true; 10889 } 10890 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10891 pw.println(tr); 10892 if (dumpAll) { 10893 mRecentTasks.get(i).dump(pw, " "); 10894 } 10895 } 10896 } 10897 10898 if (!printedAnything) { 10899 pw.println(" (nothing)"); 10900 } 10901 } 10902 10903 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10904 int opti, boolean dumpAll, String dumpPackage) { 10905 boolean needSep = false; 10906 boolean printedAnything = false; 10907 int numPers = 0; 10908 10909 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10910 10911 if (dumpAll) { 10912 final int NP = mProcessNames.getMap().size(); 10913 for (int ip=0; ip<NP; ip++) { 10914 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10915 final int NA = procs.size(); 10916 for (int ia=0; ia<NA; ia++) { 10917 ProcessRecord r = procs.valueAt(ia); 10918 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10919 continue; 10920 } 10921 if (!needSep) { 10922 pw.println(" All known processes:"); 10923 needSep = true; 10924 printedAnything = true; 10925 } 10926 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10927 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10928 pw.print(" "); pw.println(r); 10929 r.dump(pw, " "); 10930 if (r.persistent) { 10931 numPers++; 10932 } 10933 } 10934 } 10935 } 10936 10937 if (mIsolatedProcesses.size() > 0) { 10938 boolean printed = false; 10939 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10940 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10941 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10942 continue; 10943 } 10944 if (!printed) { 10945 if (needSep) { 10946 pw.println(); 10947 } 10948 pw.println(" Isolated process list (sorted by uid):"); 10949 printedAnything = true; 10950 printed = true; 10951 needSep = true; 10952 } 10953 pw.println(String.format("%sIsolated #%2d: %s", 10954 " ", i, r.toString())); 10955 } 10956 } 10957 10958 if (mLruProcesses.size() > 0) { 10959 if (needSep) { 10960 pw.println(); 10961 } 10962 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10963 pw.print(" total, non-act at "); 10964 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10965 pw.print(", non-svc at "); 10966 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10967 pw.println("):"); 10968 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10969 needSep = true; 10970 printedAnything = true; 10971 } 10972 10973 if (dumpAll || dumpPackage != null) { 10974 synchronized (mPidsSelfLocked) { 10975 boolean printed = false; 10976 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10977 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10978 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10979 continue; 10980 } 10981 if (!printed) { 10982 if (needSep) pw.println(); 10983 needSep = true; 10984 pw.println(" PID mappings:"); 10985 printed = true; 10986 printedAnything = true; 10987 } 10988 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10989 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10990 } 10991 } 10992 } 10993 10994 if (mForegroundProcesses.size() > 0) { 10995 synchronized (mPidsSelfLocked) { 10996 boolean printed = false; 10997 for (int i=0; i<mForegroundProcesses.size(); i++) { 10998 ProcessRecord r = mPidsSelfLocked.get( 10999 mForegroundProcesses.valueAt(i).pid); 11000 if (dumpPackage != null && (r == null 11001 || !r.pkgList.containsKey(dumpPackage))) { 11002 continue; 11003 } 11004 if (!printed) { 11005 if (needSep) pw.println(); 11006 needSep = true; 11007 pw.println(" Foreground Processes:"); 11008 printed = true; 11009 printedAnything = true; 11010 } 11011 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11012 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11013 } 11014 } 11015 } 11016 11017 if (mPersistentStartingProcesses.size() > 0) { 11018 if (needSep) pw.println(); 11019 needSep = true; 11020 printedAnything = true; 11021 pw.println(" Persisent processes that are starting:"); 11022 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11023 "Starting Norm", "Restarting PERS", dumpPackage); 11024 } 11025 11026 if (mRemovedProcesses.size() > 0) { 11027 if (needSep) pw.println(); 11028 needSep = true; 11029 printedAnything = true; 11030 pw.println(" Processes that are being removed:"); 11031 dumpProcessList(pw, this, mRemovedProcesses, " ", 11032 "Removed Norm", "Removed PERS", dumpPackage); 11033 } 11034 11035 if (mProcessesOnHold.size() > 0) { 11036 if (needSep) pw.println(); 11037 needSep = true; 11038 printedAnything = true; 11039 pw.println(" Processes that are on old until the system is ready:"); 11040 dumpProcessList(pw, this, mProcessesOnHold, " ", 11041 "OnHold Norm", "OnHold PERS", dumpPackage); 11042 } 11043 11044 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11045 11046 if (mProcessCrashTimes.getMap().size() > 0) { 11047 boolean printed = false; 11048 long now = SystemClock.uptimeMillis(); 11049 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11050 final int NP = pmap.size(); 11051 for (int ip=0; ip<NP; ip++) { 11052 String pname = pmap.keyAt(ip); 11053 SparseArray<Long> uids = pmap.valueAt(ip); 11054 final int N = uids.size(); 11055 for (int i=0; i<N; i++) { 11056 int puid = uids.keyAt(i); 11057 ProcessRecord r = mProcessNames.get(pname, puid); 11058 if (dumpPackage != null && (r == null 11059 || !r.pkgList.containsKey(dumpPackage))) { 11060 continue; 11061 } 11062 if (!printed) { 11063 if (needSep) pw.println(); 11064 needSep = true; 11065 pw.println(" Time since processes crashed:"); 11066 printed = true; 11067 printedAnything = true; 11068 } 11069 pw.print(" Process "); pw.print(pname); 11070 pw.print(" uid "); pw.print(puid); 11071 pw.print(": last crashed "); 11072 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11073 pw.println(" ago"); 11074 } 11075 } 11076 } 11077 11078 if (mBadProcesses.getMap().size() > 0) { 11079 boolean printed = false; 11080 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11081 final int NP = pmap.size(); 11082 for (int ip=0; ip<NP; ip++) { 11083 String pname = pmap.keyAt(ip); 11084 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11085 final int N = uids.size(); 11086 for (int i=0; i<N; i++) { 11087 int puid = uids.keyAt(i); 11088 ProcessRecord r = mProcessNames.get(pname, puid); 11089 if (dumpPackage != null && (r == null 11090 || !r.pkgList.containsKey(dumpPackage))) { 11091 continue; 11092 } 11093 if (!printed) { 11094 if (needSep) pw.println(); 11095 needSep = true; 11096 pw.println(" Bad processes:"); 11097 printedAnything = true; 11098 } 11099 BadProcessInfo info = uids.valueAt(i); 11100 pw.print(" Bad process "); pw.print(pname); 11101 pw.print(" uid "); pw.print(puid); 11102 pw.print(": crashed at time "); pw.println(info.time); 11103 if (info.shortMsg != null) { 11104 pw.print(" Short msg: "); pw.println(info.shortMsg); 11105 } 11106 if (info.longMsg != null) { 11107 pw.print(" Long msg: "); pw.println(info.longMsg); 11108 } 11109 if (info.stack != null) { 11110 pw.println(" Stack:"); 11111 int lastPos = 0; 11112 for (int pos=0; pos<info.stack.length(); pos++) { 11113 if (info.stack.charAt(pos) == '\n') { 11114 pw.print(" "); 11115 pw.write(info.stack, lastPos, pos-lastPos); 11116 pw.println(); 11117 lastPos = pos+1; 11118 } 11119 } 11120 if (lastPos < info.stack.length()) { 11121 pw.print(" "); 11122 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11123 pw.println(); 11124 } 11125 } 11126 } 11127 } 11128 } 11129 11130 if (dumpPackage == null) { 11131 pw.println(); 11132 needSep = false; 11133 pw.println(" mStartedUsers:"); 11134 for (int i=0; i<mStartedUsers.size(); i++) { 11135 UserStartedState uss = mStartedUsers.valueAt(i); 11136 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11137 pw.print(": "); uss.dump("", pw); 11138 } 11139 pw.print(" mStartedUserArray: ["); 11140 for (int i=0; i<mStartedUserArray.length; i++) { 11141 if (i > 0) pw.print(", "); 11142 pw.print(mStartedUserArray[i]); 11143 } 11144 pw.println("]"); 11145 pw.print(" mUserLru: ["); 11146 for (int i=0; i<mUserLru.size(); i++) { 11147 if (i > 0) pw.print(", "); 11148 pw.print(mUserLru.get(i)); 11149 } 11150 pw.println("]"); 11151 if (dumpAll) { 11152 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11153 } 11154 } 11155 if (mHomeProcess != null && (dumpPackage == null 11156 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11157 if (needSep) { 11158 pw.println(); 11159 needSep = false; 11160 } 11161 pw.println(" mHomeProcess: " + mHomeProcess); 11162 } 11163 if (mPreviousProcess != null && (dumpPackage == null 11164 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11165 if (needSep) { 11166 pw.println(); 11167 needSep = false; 11168 } 11169 pw.println(" mPreviousProcess: " + mPreviousProcess); 11170 } 11171 if (dumpAll) { 11172 StringBuilder sb = new StringBuilder(128); 11173 sb.append(" mPreviousProcessVisibleTime: "); 11174 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11175 pw.println(sb); 11176 } 11177 if (mHeavyWeightProcess != null && (dumpPackage == null 11178 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11179 if (needSep) { 11180 pw.println(); 11181 needSep = false; 11182 } 11183 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11184 } 11185 if (dumpPackage == null) { 11186 pw.println(" mConfiguration: " + mConfiguration); 11187 } 11188 if (dumpAll) { 11189 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11190 if (mCompatModePackages.getPackages().size() > 0) { 11191 boolean printed = false; 11192 for (Map.Entry<String, Integer> entry 11193 : mCompatModePackages.getPackages().entrySet()) { 11194 String pkg = entry.getKey(); 11195 int mode = entry.getValue(); 11196 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11197 continue; 11198 } 11199 if (!printed) { 11200 pw.println(" mScreenCompatPackages:"); 11201 printed = true; 11202 } 11203 pw.print(" "); pw.print(pkg); pw.print(": "); 11204 pw.print(mode); pw.println(); 11205 } 11206 } 11207 } 11208 if (dumpPackage == null) { 11209 if (mSleeping || mWentToSleep || mLockScreenShown) { 11210 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11211 + " mLockScreenShown " + mLockScreenShown); 11212 } 11213 if (mShuttingDown || mRunningVoice) { 11214 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11215 } 11216 } 11217 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11218 || mOrigWaitForDebugger) { 11219 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11220 || dumpPackage.equals(mOrigDebugApp)) { 11221 if (needSep) { 11222 pw.println(); 11223 needSep = false; 11224 } 11225 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11226 + " mDebugTransient=" + mDebugTransient 11227 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11228 } 11229 } 11230 if (mOpenGlTraceApp != null) { 11231 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11232 if (needSep) { 11233 pw.println(); 11234 needSep = false; 11235 } 11236 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11237 } 11238 } 11239 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11240 || mProfileFd != null) { 11241 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11242 if (needSep) { 11243 pw.println(); 11244 needSep = false; 11245 } 11246 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11247 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11248 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11249 + mAutoStopProfiler); 11250 } 11251 } 11252 if (dumpPackage == null) { 11253 if (mAlwaysFinishActivities || mController != null) { 11254 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11255 + " mController=" + mController); 11256 } 11257 if (dumpAll) { 11258 pw.println(" Total persistent processes: " + numPers); 11259 pw.println(" mProcessesReady=" + mProcessesReady 11260 + " mSystemReady=" + mSystemReady); 11261 pw.println(" mBooting=" + mBooting 11262 + " mBooted=" + mBooted 11263 + " mFactoryTest=" + mFactoryTest); 11264 pw.print(" mLastPowerCheckRealtime="); 11265 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11266 pw.println(""); 11267 pw.print(" mLastPowerCheckUptime="); 11268 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11269 pw.println(""); 11270 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11271 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11272 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11273 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11274 + " (" + mLruProcesses.size() + " total)" 11275 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11276 + " mNumServiceProcs=" + mNumServiceProcs 11277 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11278 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11279 + " mLastMemoryLevel" + mLastMemoryLevel 11280 + " mLastNumProcesses" + mLastNumProcesses); 11281 long now = SystemClock.uptimeMillis(); 11282 pw.print(" mLastIdleTime="); 11283 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11284 pw.print(" mLowRamSinceLastIdle="); 11285 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11286 pw.println(); 11287 } 11288 } 11289 11290 if (!printedAnything) { 11291 pw.println(" (nothing)"); 11292 } 11293 } 11294 11295 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11296 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11297 if (mProcessesToGc.size() > 0) { 11298 boolean printed = false; 11299 long now = SystemClock.uptimeMillis(); 11300 for (int i=0; i<mProcessesToGc.size(); i++) { 11301 ProcessRecord proc = mProcessesToGc.get(i); 11302 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11303 continue; 11304 } 11305 if (!printed) { 11306 if (needSep) pw.println(); 11307 needSep = true; 11308 pw.println(" Processes that are waiting to GC:"); 11309 printed = true; 11310 } 11311 pw.print(" Process "); pw.println(proc); 11312 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11313 pw.print(", last gced="); 11314 pw.print(now-proc.lastRequestedGc); 11315 pw.print(" ms ago, last lowMem="); 11316 pw.print(now-proc.lastLowMemory); 11317 pw.println(" ms ago"); 11318 11319 } 11320 } 11321 return needSep; 11322 } 11323 11324 void printOomLevel(PrintWriter pw, String name, int adj) { 11325 pw.print(" "); 11326 if (adj >= 0) { 11327 pw.print(' '); 11328 if (adj < 10) pw.print(' '); 11329 } else { 11330 if (adj > -10) pw.print(' '); 11331 } 11332 pw.print(adj); 11333 pw.print(": "); 11334 pw.print(name); 11335 pw.print(" ("); 11336 pw.print(mProcessList.getMemLevel(adj)/1024); 11337 pw.println(" kB)"); 11338 } 11339 11340 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11341 int opti, boolean dumpAll) { 11342 boolean needSep = false; 11343 11344 if (mLruProcesses.size() > 0) { 11345 if (needSep) pw.println(); 11346 needSep = true; 11347 pw.println(" OOM levels:"); 11348 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11349 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11350 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11351 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11352 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11353 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11354 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11355 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11356 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11357 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11358 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11359 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11360 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11361 11362 if (needSep) pw.println(); 11363 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11364 pw.print(" total, non-act at "); 11365 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11366 pw.print(", non-svc at "); 11367 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11368 pw.println("):"); 11369 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11370 needSep = true; 11371 } 11372 11373 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11374 11375 pw.println(); 11376 pw.println(" mHomeProcess: " + mHomeProcess); 11377 pw.println(" mPreviousProcess: " + mPreviousProcess); 11378 if (mHeavyWeightProcess != null) { 11379 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11380 } 11381 11382 return true; 11383 } 11384 11385 /** 11386 * There are three ways to call this: 11387 * - no provider specified: dump all the providers 11388 * - a flattened component name that matched an existing provider was specified as the 11389 * first arg: dump that one provider 11390 * - the first arg isn't the flattened component name of an existing provider: 11391 * dump all providers whose component contains the first arg as a substring 11392 */ 11393 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11394 int opti, boolean dumpAll) { 11395 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11396 } 11397 11398 static class ItemMatcher { 11399 ArrayList<ComponentName> components; 11400 ArrayList<String> strings; 11401 ArrayList<Integer> objects; 11402 boolean all; 11403 11404 ItemMatcher() { 11405 all = true; 11406 } 11407 11408 void build(String name) { 11409 ComponentName componentName = ComponentName.unflattenFromString(name); 11410 if (componentName != null) { 11411 if (components == null) { 11412 components = new ArrayList<ComponentName>(); 11413 } 11414 components.add(componentName); 11415 all = false; 11416 } else { 11417 int objectId = 0; 11418 // Not a '/' separated full component name; maybe an object ID? 11419 try { 11420 objectId = Integer.parseInt(name, 16); 11421 if (objects == null) { 11422 objects = new ArrayList<Integer>(); 11423 } 11424 objects.add(objectId); 11425 all = false; 11426 } catch (RuntimeException e) { 11427 // Not an integer; just do string match. 11428 if (strings == null) { 11429 strings = new ArrayList<String>(); 11430 } 11431 strings.add(name); 11432 all = false; 11433 } 11434 } 11435 } 11436 11437 int build(String[] args, int opti) { 11438 for (; opti<args.length; opti++) { 11439 String name = args[opti]; 11440 if ("--".equals(name)) { 11441 return opti+1; 11442 } 11443 build(name); 11444 } 11445 return opti; 11446 } 11447 11448 boolean match(Object object, ComponentName comp) { 11449 if (all) { 11450 return true; 11451 } 11452 if (components != null) { 11453 for (int i=0; i<components.size(); i++) { 11454 if (components.get(i).equals(comp)) { 11455 return true; 11456 } 11457 } 11458 } 11459 if (objects != null) { 11460 for (int i=0; i<objects.size(); i++) { 11461 if (System.identityHashCode(object) == objects.get(i)) { 11462 return true; 11463 } 11464 } 11465 } 11466 if (strings != null) { 11467 String flat = comp.flattenToString(); 11468 for (int i=0; i<strings.size(); i++) { 11469 if (flat.contains(strings.get(i))) { 11470 return true; 11471 } 11472 } 11473 } 11474 return false; 11475 } 11476 } 11477 11478 /** 11479 * There are three things that cmd can be: 11480 * - a flattened component name that matches an existing activity 11481 * - the cmd arg isn't the flattened component name of an existing activity: 11482 * dump all activity whose component contains the cmd as a substring 11483 * - A hex number of the ActivityRecord object instance. 11484 */ 11485 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11486 int opti, boolean dumpAll) { 11487 ArrayList<ActivityRecord> activities; 11488 11489 synchronized (this) { 11490 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11491 } 11492 11493 if (activities.size() <= 0) { 11494 return false; 11495 } 11496 11497 String[] newArgs = new String[args.length - opti]; 11498 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11499 11500 TaskRecord lastTask = null; 11501 boolean needSep = false; 11502 for (int i=activities.size()-1; i>=0; i--) { 11503 ActivityRecord r = activities.get(i); 11504 if (needSep) { 11505 pw.println(); 11506 } 11507 needSep = true; 11508 synchronized (this) { 11509 if (lastTask != r.task) { 11510 lastTask = r.task; 11511 pw.print("TASK "); pw.print(lastTask.affinity); 11512 pw.print(" id="); pw.println(lastTask.taskId); 11513 if (dumpAll) { 11514 lastTask.dump(pw, " "); 11515 } 11516 } 11517 } 11518 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11519 } 11520 return true; 11521 } 11522 11523 /** 11524 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11525 * there is a thread associated with the activity. 11526 */ 11527 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11528 final ActivityRecord r, String[] args, boolean dumpAll) { 11529 String innerPrefix = prefix + " "; 11530 synchronized (this) { 11531 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11532 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11533 pw.print(" pid="); 11534 if (r.app != null) pw.println(r.app.pid); 11535 else pw.println("(not running)"); 11536 if (dumpAll) { 11537 r.dump(pw, innerPrefix); 11538 } 11539 } 11540 if (r.app != null && r.app.thread != null) { 11541 // flush anything that is already in the PrintWriter since the thread is going 11542 // to write to the file descriptor directly 11543 pw.flush(); 11544 try { 11545 TransferPipe tp = new TransferPipe(); 11546 try { 11547 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11548 r.appToken, innerPrefix, args); 11549 tp.go(fd); 11550 } finally { 11551 tp.kill(); 11552 } 11553 } catch (IOException e) { 11554 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11555 } catch (RemoteException e) { 11556 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11557 } 11558 } 11559 } 11560 11561 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11562 int opti, boolean dumpAll, String dumpPackage) { 11563 boolean needSep = false; 11564 boolean onlyHistory = false; 11565 boolean printedAnything = false; 11566 11567 if ("history".equals(dumpPackage)) { 11568 if (opti < args.length && "-s".equals(args[opti])) { 11569 dumpAll = false; 11570 } 11571 onlyHistory = true; 11572 dumpPackage = null; 11573 } 11574 11575 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11576 if (!onlyHistory && dumpAll) { 11577 if (mRegisteredReceivers.size() > 0) { 11578 boolean printed = false; 11579 Iterator it = mRegisteredReceivers.values().iterator(); 11580 while (it.hasNext()) { 11581 ReceiverList r = (ReceiverList)it.next(); 11582 if (dumpPackage != null && (r.app == null || 11583 !dumpPackage.equals(r.app.info.packageName))) { 11584 continue; 11585 } 11586 if (!printed) { 11587 pw.println(" Registered Receivers:"); 11588 needSep = true; 11589 printed = true; 11590 printedAnything = true; 11591 } 11592 pw.print(" * "); pw.println(r); 11593 r.dump(pw, " "); 11594 } 11595 } 11596 11597 if (mReceiverResolver.dump(pw, needSep ? 11598 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11599 " ", dumpPackage, false)) { 11600 needSep = true; 11601 printedAnything = true; 11602 } 11603 } 11604 11605 for (BroadcastQueue q : mBroadcastQueues) { 11606 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11607 printedAnything |= needSep; 11608 } 11609 11610 needSep = true; 11611 11612 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11613 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11614 if (needSep) { 11615 pw.println(); 11616 } 11617 needSep = true; 11618 printedAnything = true; 11619 pw.print(" Sticky broadcasts for user "); 11620 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11621 StringBuilder sb = new StringBuilder(128); 11622 for (Map.Entry<String, ArrayList<Intent>> ent 11623 : mStickyBroadcasts.valueAt(user).entrySet()) { 11624 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11625 if (dumpAll) { 11626 pw.println(":"); 11627 ArrayList<Intent> intents = ent.getValue(); 11628 final int N = intents.size(); 11629 for (int i=0; i<N; i++) { 11630 sb.setLength(0); 11631 sb.append(" Intent: "); 11632 intents.get(i).toShortString(sb, false, true, false, false); 11633 pw.println(sb.toString()); 11634 Bundle bundle = intents.get(i).getExtras(); 11635 if (bundle != null) { 11636 pw.print(" "); 11637 pw.println(bundle.toString()); 11638 } 11639 } 11640 } else { 11641 pw.println(""); 11642 } 11643 } 11644 } 11645 } 11646 11647 if (!onlyHistory && dumpAll) { 11648 pw.println(); 11649 for (BroadcastQueue queue : mBroadcastQueues) { 11650 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11651 + queue.mBroadcastsScheduled); 11652 } 11653 pw.println(" mHandler:"); 11654 mHandler.dump(new PrintWriterPrinter(pw), " "); 11655 needSep = true; 11656 printedAnything = true; 11657 } 11658 11659 if (!printedAnything) { 11660 pw.println(" (nothing)"); 11661 } 11662 } 11663 11664 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11665 int opti, boolean dumpAll, String dumpPackage) { 11666 boolean needSep; 11667 boolean printedAnything = false; 11668 11669 ItemMatcher matcher = new ItemMatcher(); 11670 matcher.build(args, opti); 11671 11672 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11673 11674 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11675 printedAnything |= needSep; 11676 11677 if (mLaunchingProviders.size() > 0) { 11678 boolean printed = false; 11679 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11680 ContentProviderRecord r = mLaunchingProviders.get(i); 11681 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11682 continue; 11683 } 11684 if (!printed) { 11685 if (needSep) pw.println(); 11686 needSep = true; 11687 pw.println(" Launching content providers:"); 11688 printed = true; 11689 printedAnything = true; 11690 } 11691 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11692 pw.println(r); 11693 } 11694 } 11695 11696 if (mGrantedUriPermissions.size() > 0) { 11697 boolean printed = false; 11698 int dumpUid = -2; 11699 if (dumpPackage != null) { 11700 try { 11701 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11702 } catch (NameNotFoundException e) { 11703 dumpUid = -1; 11704 } 11705 } 11706 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11707 int uid = mGrantedUriPermissions.keyAt(i); 11708 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11709 continue; 11710 } 11711 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11712 if (!printed) { 11713 if (needSep) pw.println(); 11714 needSep = true; 11715 pw.println(" Granted Uri Permissions:"); 11716 printed = true; 11717 printedAnything = true; 11718 } 11719 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11720 for (UriPermission perm : perms.values()) { 11721 pw.print(" "); pw.println(perm); 11722 if (dumpAll) { 11723 perm.dump(pw, " "); 11724 } 11725 } 11726 } 11727 } 11728 11729 if (!printedAnything) { 11730 pw.println(" (nothing)"); 11731 } 11732 } 11733 11734 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11735 int opti, boolean dumpAll, String dumpPackage) { 11736 boolean printed = false; 11737 11738 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11739 11740 if (mIntentSenderRecords.size() > 0) { 11741 Iterator<WeakReference<PendingIntentRecord>> it 11742 = mIntentSenderRecords.values().iterator(); 11743 while (it.hasNext()) { 11744 WeakReference<PendingIntentRecord> ref = it.next(); 11745 PendingIntentRecord rec = ref != null ? ref.get(): null; 11746 if (dumpPackage != null && (rec == null 11747 || !dumpPackage.equals(rec.key.packageName))) { 11748 continue; 11749 } 11750 printed = true; 11751 if (rec != null) { 11752 pw.print(" * "); pw.println(rec); 11753 if (dumpAll) { 11754 rec.dump(pw, " "); 11755 } 11756 } else { 11757 pw.print(" * "); pw.println(ref); 11758 } 11759 } 11760 } 11761 11762 if (!printed) { 11763 pw.println(" (nothing)"); 11764 } 11765 } 11766 11767 private static final int dumpProcessList(PrintWriter pw, 11768 ActivityManagerService service, List list, 11769 String prefix, String normalLabel, String persistentLabel, 11770 String dumpPackage) { 11771 int numPers = 0; 11772 final int N = list.size()-1; 11773 for (int i=N; i>=0; i--) { 11774 ProcessRecord r = (ProcessRecord)list.get(i); 11775 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11776 continue; 11777 } 11778 pw.println(String.format("%s%s #%2d: %s", 11779 prefix, (r.persistent ? persistentLabel : normalLabel), 11780 i, r.toString())); 11781 if (r.persistent) { 11782 numPers++; 11783 } 11784 } 11785 return numPers; 11786 } 11787 11788 private static final boolean dumpProcessOomList(PrintWriter pw, 11789 ActivityManagerService service, List<ProcessRecord> origList, 11790 String prefix, String normalLabel, String persistentLabel, 11791 boolean inclDetails, String dumpPackage) { 11792 11793 ArrayList<Pair<ProcessRecord, Integer>> list 11794 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11795 for (int i=0; i<origList.size(); i++) { 11796 ProcessRecord r = origList.get(i); 11797 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11798 continue; 11799 } 11800 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11801 } 11802 11803 if (list.size() <= 0) { 11804 return false; 11805 } 11806 11807 Comparator<Pair<ProcessRecord, Integer>> comparator 11808 = new Comparator<Pair<ProcessRecord, Integer>>() { 11809 @Override 11810 public int compare(Pair<ProcessRecord, Integer> object1, 11811 Pair<ProcessRecord, Integer> object2) { 11812 if (object1.first.setAdj != object2.first.setAdj) { 11813 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11814 } 11815 if (object1.second.intValue() != object2.second.intValue()) { 11816 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11817 } 11818 return 0; 11819 } 11820 }; 11821 11822 Collections.sort(list, comparator); 11823 11824 final long curRealtime = SystemClock.elapsedRealtime(); 11825 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11826 final long curUptime = SystemClock.uptimeMillis(); 11827 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11828 11829 for (int i=list.size()-1; i>=0; i--) { 11830 ProcessRecord r = list.get(i).first; 11831 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11832 char schedGroup; 11833 switch (r.setSchedGroup) { 11834 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11835 schedGroup = 'B'; 11836 break; 11837 case Process.THREAD_GROUP_DEFAULT: 11838 schedGroup = 'F'; 11839 break; 11840 default: 11841 schedGroup = '?'; 11842 break; 11843 } 11844 char foreground; 11845 if (r.foregroundActivities) { 11846 foreground = 'A'; 11847 } else if (r.foregroundServices) { 11848 foreground = 'S'; 11849 } else { 11850 foreground = ' '; 11851 } 11852 String procState = ProcessList.makeProcStateString(r.curProcState); 11853 pw.print(prefix); 11854 pw.print(r.persistent ? persistentLabel : normalLabel); 11855 pw.print(" #"); 11856 int num = (origList.size()-1)-list.get(i).second; 11857 if (num < 10) pw.print(' '); 11858 pw.print(num); 11859 pw.print(": "); 11860 pw.print(oomAdj); 11861 pw.print(' '); 11862 pw.print(schedGroup); 11863 pw.print('/'); 11864 pw.print(foreground); 11865 pw.print('/'); 11866 pw.print(procState); 11867 pw.print(" trm:"); 11868 if (r.trimMemoryLevel < 10) pw.print(' '); 11869 pw.print(r.trimMemoryLevel); 11870 pw.print(' '); 11871 pw.print(r.toShortString()); 11872 pw.print(" ("); 11873 pw.print(r.adjType); 11874 pw.println(')'); 11875 if (r.adjSource != null || r.adjTarget != null) { 11876 pw.print(prefix); 11877 pw.print(" "); 11878 if (r.adjTarget instanceof ComponentName) { 11879 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11880 } else if (r.adjTarget != null) { 11881 pw.print(r.adjTarget.toString()); 11882 } else { 11883 pw.print("{null}"); 11884 } 11885 pw.print("<="); 11886 if (r.adjSource instanceof ProcessRecord) { 11887 pw.print("Proc{"); 11888 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11889 pw.println("}"); 11890 } else if (r.adjSource != null) { 11891 pw.println(r.adjSource.toString()); 11892 } else { 11893 pw.println("{null}"); 11894 } 11895 } 11896 if (inclDetails) { 11897 pw.print(prefix); 11898 pw.print(" "); 11899 pw.print("oom: max="); pw.print(r.maxAdj); 11900 pw.print(" curRaw="); pw.print(r.curRawAdj); 11901 pw.print(" setRaw="); pw.print(r.setRawAdj); 11902 pw.print(" cur="); pw.print(r.curAdj); 11903 pw.print(" set="); pw.println(r.setAdj); 11904 pw.print(prefix); 11905 pw.print(" "); 11906 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11907 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11908 pw.print(" lastPss="); pw.print(r.lastPss); 11909 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11910 pw.print(prefix); 11911 pw.print(" "); 11912 pw.print("keeping="); pw.print(r.keeping); 11913 pw.print(" cached="); pw.print(r.cached); 11914 pw.print(" empty="); pw.print(r.empty); 11915 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11916 11917 if (!r.keeping) { 11918 if (r.lastWakeTime != 0) { 11919 long wtime; 11920 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11921 synchronized (stats) { 11922 wtime = stats.getProcessWakeTime(r.info.uid, 11923 r.pid, curRealtime); 11924 } 11925 long timeUsed = wtime - r.lastWakeTime; 11926 pw.print(prefix); 11927 pw.print(" "); 11928 pw.print("keep awake over "); 11929 TimeUtils.formatDuration(realtimeSince, pw); 11930 pw.print(" used "); 11931 TimeUtils.formatDuration(timeUsed, pw); 11932 pw.print(" ("); 11933 pw.print((timeUsed*100)/realtimeSince); 11934 pw.println("%)"); 11935 } 11936 if (r.lastCpuTime != 0) { 11937 long timeUsed = r.curCpuTime - r.lastCpuTime; 11938 pw.print(prefix); 11939 pw.print(" "); 11940 pw.print("run cpu over "); 11941 TimeUtils.formatDuration(uptimeSince, pw); 11942 pw.print(" used "); 11943 TimeUtils.formatDuration(timeUsed, pw); 11944 pw.print(" ("); 11945 pw.print((timeUsed*100)/uptimeSince); 11946 pw.println("%)"); 11947 } 11948 } 11949 } 11950 } 11951 return true; 11952 } 11953 11954 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11955 ArrayList<ProcessRecord> procs; 11956 synchronized (this) { 11957 if (args != null && args.length > start 11958 && args[start].charAt(0) != '-') { 11959 procs = new ArrayList<ProcessRecord>(); 11960 int pid = -1; 11961 try { 11962 pid = Integer.parseInt(args[start]); 11963 } catch (NumberFormatException e) { 11964 } 11965 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11966 ProcessRecord proc = mLruProcesses.get(i); 11967 if (proc.pid == pid) { 11968 procs.add(proc); 11969 } else if (proc.processName.equals(args[start])) { 11970 procs.add(proc); 11971 } 11972 } 11973 if (procs.size() <= 0) { 11974 return null; 11975 } 11976 } else { 11977 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11978 } 11979 } 11980 return procs; 11981 } 11982 11983 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11984 PrintWriter pw, String[] args) { 11985 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11986 if (procs == null) { 11987 pw.println("No process found for: " + args[0]); 11988 return; 11989 } 11990 11991 long uptime = SystemClock.uptimeMillis(); 11992 long realtime = SystemClock.elapsedRealtime(); 11993 pw.println("Applications Graphics Acceleration Info:"); 11994 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11995 11996 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11997 ProcessRecord r = procs.get(i); 11998 if (r.thread != null) { 11999 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12000 pw.flush(); 12001 try { 12002 TransferPipe tp = new TransferPipe(); 12003 try { 12004 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12005 tp.go(fd); 12006 } finally { 12007 tp.kill(); 12008 } 12009 } catch (IOException e) { 12010 pw.println("Failure while dumping the app: " + r); 12011 pw.flush(); 12012 } catch (RemoteException e) { 12013 pw.println("Got a RemoteException while dumping the app " + r); 12014 pw.flush(); 12015 } 12016 } 12017 } 12018 } 12019 12020 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12021 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12022 if (procs == null) { 12023 pw.println("No process found for: " + args[0]); 12024 return; 12025 } 12026 12027 pw.println("Applications Database Info:"); 12028 12029 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12030 ProcessRecord r = procs.get(i); 12031 if (r.thread != null) { 12032 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12033 pw.flush(); 12034 try { 12035 TransferPipe tp = new TransferPipe(); 12036 try { 12037 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12038 tp.go(fd); 12039 } finally { 12040 tp.kill(); 12041 } 12042 } catch (IOException e) { 12043 pw.println("Failure while dumping the app: " + r); 12044 pw.flush(); 12045 } catch (RemoteException e) { 12046 pw.println("Got a RemoteException while dumping the app " + r); 12047 pw.flush(); 12048 } 12049 } 12050 } 12051 } 12052 12053 final static class MemItem { 12054 final boolean isProc; 12055 final String label; 12056 final String shortLabel; 12057 final long pss; 12058 final int id; 12059 final boolean hasActivities; 12060 ArrayList<MemItem> subitems; 12061 12062 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12063 boolean _hasActivities) { 12064 isProc = true; 12065 label = _label; 12066 shortLabel = _shortLabel; 12067 pss = _pss; 12068 id = _id; 12069 hasActivities = _hasActivities; 12070 } 12071 12072 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12073 isProc = false; 12074 label = _label; 12075 shortLabel = _shortLabel; 12076 pss = _pss; 12077 id = _id; 12078 hasActivities = false; 12079 } 12080 } 12081 12082 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12083 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12084 if (sort && !isCompact) { 12085 Collections.sort(items, new Comparator<MemItem>() { 12086 @Override 12087 public int compare(MemItem lhs, MemItem rhs) { 12088 if (lhs.pss < rhs.pss) { 12089 return 1; 12090 } else if (lhs.pss > rhs.pss) { 12091 return -1; 12092 } 12093 return 0; 12094 } 12095 }); 12096 } 12097 12098 for (int i=0; i<items.size(); i++) { 12099 MemItem mi = items.get(i); 12100 if (!isCompact) { 12101 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12102 } else if (mi.isProc) { 12103 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12104 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12105 pw.println(mi.hasActivities ? ",a" : ",e"); 12106 } else { 12107 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12108 pw.println(mi.pss); 12109 } 12110 if (mi.subitems != null) { 12111 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12112 true, isCompact); 12113 } 12114 } 12115 } 12116 12117 // These are in KB. 12118 static final long[] DUMP_MEM_BUCKETS = new long[] { 12119 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12120 120*1024, 160*1024, 200*1024, 12121 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12122 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12123 }; 12124 12125 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12126 boolean stackLike) { 12127 int start = label.lastIndexOf('.'); 12128 if (start >= 0) start++; 12129 else start = 0; 12130 int end = label.length(); 12131 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12132 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12133 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12134 out.append(bucket); 12135 out.append(stackLike ? "MB." : "MB "); 12136 out.append(label, start, end); 12137 return; 12138 } 12139 } 12140 out.append(memKB/1024); 12141 out.append(stackLike ? "MB." : "MB "); 12142 out.append(label, start, end); 12143 } 12144 12145 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12146 ProcessList.NATIVE_ADJ, 12147 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12148 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12149 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12150 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12151 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12152 }; 12153 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12154 "Native", 12155 "System", "Persistent", "Foreground", 12156 "Visible", "Perceptible", 12157 "Heavy Weight", "Backup", 12158 "A Services", "Home", 12159 "Previous", "B Services", "Cached" 12160 }; 12161 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12162 "native", 12163 "sys", "pers", "fore", 12164 "vis", "percept", 12165 "heavy", "backup", 12166 "servicea", "home", 12167 "prev", "serviceb", "cached" 12168 }; 12169 12170 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12171 long realtime, boolean isCheckinRequest, boolean isCompact) { 12172 if (isCheckinRequest || isCompact) { 12173 // short checkin version 12174 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12175 } else { 12176 pw.println("Applications Memory Usage (kB):"); 12177 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12178 } 12179 } 12180 12181 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12182 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12183 boolean dumpDetails = false; 12184 boolean dumpFullDetails = false; 12185 boolean dumpDalvik = false; 12186 boolean oomOnly = false; 12187 boolean isCompact = false; 12188 boolean localOnly = false; 12189 12190 int opti = 0; 12191 while (opti < args.length) { 12192 String opt = args[opti]; 12193 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12194 break; 12195 } 12196 opti++; 12197 if ("-a".equals(opt)) { 12198 dumpDetails = true; 12199 dumpFullDetails = true; 12200 dumpDalvik = true; 12201 } else if ("-d".equals(opt)) { 12202 dumpDalvik = true; 12203 } else if ("-c".equals(opt)) { 12204 isCompact = true; 12205 } else if ("--oom".equals(opt)) { 12206 oomOnly = true; 12207 } else if ("--local".equals(opt)) { 12208 localOnly = true; 12209 } else if ("-h".equals(opt)) { 12210 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12211 pw.println(" -a: include all available information for each process."); 12212 pw.println(" -d: include dalvik details when dumping process details."); 12213 pw.println(" -c: dump in a compact machine-parseable representation."); 12214 pw.println(" --oom: only show processes organized by oom adj."); 12215 pw.println(" --local: only collect details locally, don't call process."); 12216 pw.println("If [process] is specified it can be the name or "); 12217 pw.println("pid of a specific process to dump."); 12218 return; 12219 } else { 12220 pw.println("Unknown argument: " + opt + "; use -h for help"); 12221 } 12222 } 12223 12224 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12225 long uptime = SystemClock.uptimeMillis(); 12226 long realtime = SystemClock.elapsedRealtime(); 12227 final long[] tmpLong = new long[1]; 12228 12229 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12230 if (procs == null) { 12231 // No Java processes. Maybe they want to print a native process. 12232 if (args != null && args.length > opti 12233 && args[opti].charAt(0) != '-') { 12234 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12235 = new ArrayList<ProcessCpuTracker.Stats>(); 12236 updateCpuStatsNow(); 12237 int findPid = -1; 12238 try { 12239 findPid = Integer.parseInt(args[opti]); 12240 } catch (NumberFormatException e) { 12241 } 12242 synchronized (mProcessCpuThread) { 12243 final int N = mProcessCpuTracker.countStats(); 12244 for (int i=0; i<N; i++) { 12245 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12246 if (st.pid == findPid || (st.baseName != null 12247 && st.baseName.equals(args[opti]))) { 12248 nativeProcs.add(st); 12249 } 12250 } 12251 } 12252 if (nativeProcs.size() > 0) { 12253 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12254 isCompact); 12255 Debug.MemoryInfo mi = null; 12256 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12257 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12258 final int pid = r.pid; 12259 if (!isCheckinRequest && dumpDetails) { 12260 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12261 } 12262 if (mi == null) { 12263 mi = new Debug.MemoryInfo(); 12264 } 12265 if (dumpDetails || (!brief && !oomOnly)) { 12266 Debug.getMemoryInfo(pid, mi); 12267 } else { 12268 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12269 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12270 } 12271 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12272 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12273 if (isCheckinRequest) { 12274 pw.println(); 12275 } 12276 } 12277 return; 12278 } 12279 } 12280 pw.println("No process found for: " + args[opti]); 12281 return; 12282 } 12283 12284 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12285 dumpDetails = true; 12286 } 12287 12288 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12289 12290 String[] innerArgs = new String[args.length-opti]; 12291 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12292 12293 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12294 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12295 long nativePss=0, dalvikPss=0, otherPss=0; 12296 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12297 12298 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12299 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12300 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12301 12302 long totalPss = 0; 12303 long cachedPss = 0; 12304 12305 Debug.MemoryInfo mi = null; 12306 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12307 final ProcessRecord r = procs.get(i); 12308 final IApplicationThread thread; 12309 final int pid; 12310 final int oomAdj; 12311 final boolean hasActivities; 12312 synchronized (this) { 12313 thread = r.thread; 12314 pid = r.pid; 12315 oomAdj = r.getSetAdjWithServices(); 12316 hasActivities = r.activities.size() > 0; 12317 } 12318 if (thread != null) { 12319 if (!isCheckinRequest && dumpDetails) { 12320 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12321 } 12322 if (mi == null) { 12323 mi = new Debug.MemoryInfo(); 12324 } 12325 if (dumpDetails || (!brief && !oomOnly)) { 12326 Debug.getMemoryInfo(pid, mi); 12327 } else { 12328 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12329 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12330 } 12331 if (dumpDetails) { 12332 if (localOnly) { 12333 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12334 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12335 if (isCheckinRequest) { 12336 pw.println(); 12337 } 12338 } else { 12339 try { 12340 pw.flush(); 12341 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12342 dumpDalvik, innerArgs); 12343 } catch (RemoteException e) { 12344 if (!isCheckinRequest) { 12345 pw.println("Got RemoteException!"); 12346 pw.flush(); 12347 } 12348 } 12349 } 12350 } 12351 12352 final long myTotalPss = mi.getTotalPss(); 12353 final long myTotalUss = mi.getTotalUss(); 12354 12355 synchronized (this) { 12356 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12357 // Record this for posterity if the process has been stable. 12358 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12359 } 12360 } 12361 12362 if (!isCheckinRequest && mi != null) { 12363 totalPss += myTotalPss; 12364 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12365 (hasActivities ? " / activities)" : ")"), 12366 r.processName, myTotalPss, pid, hasActivities); 12367 procMems.add(pssItem); 12368 procMemsMap.put(pid, pssItem); 12369 12370 nativePss += mi.nativePss; 12371 dalvikPss += mi.dalvikPss; 12372 otherPss += mi.otherPss; 12373 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12374 long mem = mi.getOtherPss(j); 12375 miscPss[j] += mem; 12376 otherPss -= mem; 12377 } 12378 12379 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12380 cachedPss += myTotalPss; 12381 } 12382 12383 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12384 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12385 || oomIndex == (oomPss.length-1)) { 12386 oomPss[oomIndex] += myTotalPss; 12387 if (oomProcs[oomIndex] == null) { 12388 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12389 } 12390 oomProcs[oomIndex].add(pssItem); 12391 break; 12392 } 12393 } 12394 } 12395 } 12396 } 12397 12398 if (!isCheckinRequest && procs.size() > 1) { 12399 // If we are showing aggregations, also look for native processes to 12400 // include so that our aggregations are more accurate. 12401 updateCpuStatsNow(); 12402 synchronized (mProcessCpuThread) { 12403 final int N = mProcessCpuTracker.countStats(); 12404 for (int i=0; i<N; i++) { 12405 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12406 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12407 if (mi == null) { 12408 mi = new Debug.MemoryInfo(); 12409 } 12410 if (!brief && !oomOnly) { 12411 Debug.getMemoryInfo(st.pid, mi); 12412 } else { 12413 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12414 mi.nativePrivateDirty = (int)tmpLong[0]; 12415 } 12416 12417 final long myTotalPss = mi.getTotalPss(); 12418 totalPss += myTotalPss; 12419 12420 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12421 st.name, myTotalPss, st.pid, false); 12422 procMems.add(pssItem); 12423 12424 nativePss += mi.nativePss; 12425 dalvikPss += mi.dalvikPss; 12426 otherPss += mi.otherPss; 12427 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12428 long mem = mi.getOtherPss(j); 12429 miscPss[j] += mem; 12430 otherPss -= mem; 12431 } 12432 oomPss[0] += myTotalPss; 12433 if (oomProcs[0] == null) { 12434 oomProcs[0] = new ArrayList<MemItem>(); 12435 } 12436 oomProcs[0].add(pssItem); 12437 } 12438 } 12439 } 12440 12441 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12442 12443 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12444 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12445 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12446 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12447 String label = Debug.MemoryInfo.getOtherLabel(j); 12448 catMems.add(new MemItem(label, label, miscPss[j], j)); 12449 } 12450 12451 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12452 for (int j=0; j<oomPss.length; j++) { 12453 if (oomPss[j] != 0) { 12454 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12455 : DUMP_MEM_OOM_LABEL[j]; 12456 MemItem item = new MemItem(label, label, oomPss[j], 12457 DUMP_MEM_OOM_ADJ[j]); 12458 item.subitems = oomProcs[j]; 12459 oomMems.add(item); 12460 } 12461 } 12462 12463 if (!brief && !oomOnly && !isCompact) { 12464 pw.println(); 12465 pw.println("Total PSS by process:"); 12466 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12467 pw.println(); 12468 } 12469 if (!isCompact) { 12470 pw.println("Total PSS by OOM adjustment:"); 12471 } 12472 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12473 if (!brief && !oomOnly) { 12474 PrintWriter out = categoryPw != null ? categoryPw : pw; 12475 if (!isCompact) { 12476 out.println(); 12477 out.println("Total PSS by category:"); 12478 } 12479 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12480 } 12481 if (!isCompact) { 12482 pw.println(); 12483 } 12484 MemInfoReader memInfo = new MemInfoReader(); 12485 memInfo.readMemInfo(); 12486 if (!brief) { 12487 if (!isCompact) { 12488 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12489 pw.print(" kB (status "); 12490 switch (mLastMemoryLevel) { 12491 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12492 pw.println("normal)"); 12493 break; 12494 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12495 pw.println("moderate)"); 12496 break; 12497 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12498 pw.println("low)"); 12499 break; 12500 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12501 pw.println("critical)"); 12502 break; 12503 default: 12504 pw.print(mLastMemoryLevel); 12505 pw.println(")"); 12506 break; 12507 } 12508 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12509 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12510 pw.print(cachedPss); pw.print(" cached pss + "); 12511 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12512 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12513 } else { 12514 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12515 pw.print(cachedPss + memInfo.getCachedSizeKb() 12516 + memInfo.getFreeSizeKb()); pw.print(","); 12517 pw.println(totalPss - cachedPss); 12518 } 12519 } 12520 if (!isCompact) { 12521 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12522 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12523 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12524 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12525 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12526 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12527 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12528 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12529 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12530 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12531 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12532 } 12533 if (!brief) { 12534 if (memInfo.getZramTotalSizeKb() != 0) { 12535 if (!isCompact) { 12536 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12537 pw.print(" kB physical used for "); 12538 pw.print(memInfo.getSwapTotalSizeKb() 12539 - memInfo.getSwapFreeSizeKb()); 12540 pw.print(" kB in swap ("); 12541 pw.print(memInfo.getSwapTotalSizeKb()); 12542 pw.println(" kB total swap)"); 12543 } else { 12544 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12545 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12546 pw.println(memInfo.getSwapFreeSizeKb()); 12547 } 12548 } 12549 final int[] SINGLE_LONG_FORMAT = new int[] { 12550 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12551 }; 12552 long[] longOut = new long[1]; 12553 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12554 SINGLE_LONG_FORMAT, null, longOut, null); 12555 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12556 longOut[0] = 0; 12557 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12558 SINGLE_LONG_FORMAT, null, longOut, null); 12559 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12560 longOut[0] = 0; 12561 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12562 SINGLE_LONG_FORMAT, null, longOut, null); 12563 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12564 longOut[0] = 0; 12565 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12566 SINGLE_LONG_FORMAT, null, longOut, null); 12567 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12568 if (!isCompact) { 12569 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12570 pw.print(" KSM: "); pw.print(sharing); 12571 pw.print(" kB saved from shared "); 12572 pw.print(shared); pw.println(" kB"); 12573 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12574 pw.print(voltile); pw.println(" kB volatile"); 12575 } 12576 pw.print(" Tuning: "); 12577 pw.print(ActivityManager.staticGetMemoryClass()); 12578 pw.print(" (large "); 12579 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12580 pw.print("), oom "); 12581 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12582 pw.print(" kB"); 12583 pw.print(", restore limit "); 12584 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12585 pw.print(" kB"); 12586 if (ActivityManager.isLowRamDeviceStatic()) { 12587 pw.print(" (low-ram)"); 12588 } 12589 if (ActivityManager.isHighEndGfx()) { 12590 pw.print(" (high-end-gfx)"); 12591 } 12592 pw.println(); 12593 } else { 12594 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12595 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12596 pw.println(voltile); 12597 pw.print("tuning,"); 12598 pw.print(ActivityManager.staticGetMemoryClass()); 12599 pw.print(','); 12600 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12601 pw.print(','); 12602 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12603 if (ActivityManager.isLowRamDeviceStatic()) { 12604 pw.print(",low-ram"); 12605 } 12606 if (ActivityManager.isHighEndGfx()) { 12607 pw.print(",high-end-gfx"); 12608 } 12609 pw.println(); 12610 } 12611 } 12612 } 12613 } 12614 12615 /** 12616 * Searches array of arguments for the specified string 12617 * @param args array of argument strings 12618 * @param value value to search for 12619 * @return true if the value is contained in the array 12620 */ 12621 private static boolean scanArgs(String[] args, String value) { 12622 if (args != null) { 12623 for (String arg : args) { 12624 if (value.equals(arg)) { 12625 return true; 12626 } 12627 } 12628 } 12629 return false; 12630 } 12631 12632 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12633 ContentProviderRecord cpr, boolean always) { 12634 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12635 12636 if (!inLaunching || always) { 12637 synchronized (cpr) { 12638 cpr.launchingApp = null; 12639 cpr.notifyAll(); 12640 } 12641 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12642 String names[] = cpr.info.authority.split(";"); 12643 for (int j = 0; j < names.length; j++) { 12644 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12645 } 12646 } 12647 12648 for (int i=0; i<cpr.connections.size(); i++) { 12649 ContentProviderConnection conn = cpr.connections.get(i); 12650 if (conn.waiting) { 12651 // If this connection is waiting for the provider, then we don't 12652 // need to mess with its process unless we are always removing 12653 // or for some reason the provider is not currently launching. 12654 if (inLaunching && !always) { 12655 continue; 12656 } 12657 } 12658 ProcessRecord capp = conn.client; 12659 conn.dead = true; 12660 if (conn.stableCount > 0) { 12661 if (!capp.persistent && capp.thread != null 12662 && capp.pid != 0 12663 && capp.pid != MY_PID) { 12664 killUnneededProcessLocked(capp, "depends on provider " 12665 + cpr.name.flattenToShortString() 12666 + " in dying proc " + (proc != null ? proc.processName : "??")); 12667 } 12668 } else if (capp.thread != null && conn.provider.provider != null) { 12669 try { 12670 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12671 } catch (RemoteException e) { 12672 } 12673 // In the protocol here, we don't expect the client to correctly 12674 // clean up this connection, we'll just remove it. 12675 cpr.connections.remove(i); 12676 conn.client.conProviders.remove(conn); 12677 } 12678 } 12679 12680 if (inLaunching && always) { 12681 mLaunchingProviders.remove(cpr); 12682 } 12683 return inLaunching; 12684 } 12685 12686 /** 12687 * Main code for cleaning up a process when it has gone away. This is 12688 * called both as a result of the process dying, or directly when stopping 12689 * a process when running in single process mode. 12690 */ 12691 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12692 boolean restarting, boolean allowRestart, int index) { 12693 if (index >= 0) { 12694 removeLruProcessLocked(app); 12695 ProcessList.remove(app.pid); 12696 } 12697 12698 mProcessesToGc.remove(app); 12699 mPendingPssProcesses.remove(app); 12700 12701 // Dismiss any open dialogs. 12702 if (app.crashDialog != null && !app.forceCrashReport) { 12703 app.crashDialog.dismiss(); 12704 app.crashDialog = null; 12705 } 12706 if (app.anrDialog != null) { 12707 app.anrDialog.dismiss(); 12708 app.anrDialog = null; 12709 } 12710 if (app.waitDialog != null) { 12711 app.waitDialog.dismiss(); 12712 app.waitDialog = null; 12713 } 12714 12715 app.crashing = false; 12716 app.notResponding = false; 12717 12718 app.resetPackageList(mProcessStats); 12719 app.unlinkDeathRecipient(); 12720 app.makeInactive(mProcessStats); 12721 app.forcingToForeground = null; 12722 updateProcessForegroundLocked(app, false, false); 12723 app.foregroundActivities = false; 12724 app.hasShownUi = false; 12725 app.treatLikeActivity = false; 12726 app.hasAboveClient = false; 12727 app.hasClientActivities = false; 12728 12729 mServices.killServicesLocked(app, allowRestart); 12730 12731 boolean restart = false; 12732 12733 // Remove published content providers. 12734 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12735 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12736 final boolean always = app.bad || !allowRestart; 12737 if (removeDyingProviderLocked(app, cpr, always) || always) { 12738 // We left the provider in the launching list, need to 12739 // restart it. 12740 restart = true; 12741 } 12742 12743 cpr.provider = null; 12744 cpr.proc = null; 12745 } 12746 app.pubProviders.clear(); 12747 12748 // Take care of any launching providers waiting for this process. 12749 if (checkAppInLaunchingProvidersLocked(app, false)) { 12750 restart = true; 12751 } 12752 12753 // Unregister from connected content providers. 12754 if (!app.conProviders.isEmpty()) { 12755 for (int i=0; i<app.conProviders.size(); i++) { 12756 ContentProviderConnection conn = app.conProviders.get(i); 12757 conn.provider.connections.remove(conn); 12758 } 12759 app.conProviders.clear(); 12760 } 12761 12762 // At this point there may be remaining entries in mLaunchingProviders 12763 // where we were the only one waiting, so they are no longer of use. 12764 // Look for these and clean up if found. 12765 // XXX Commented out for now. Trying to figure out a way to reproduce 12766 // the actual situation to identify what is actually going on. 12767 if (false) { 12768 for (int i=0; i<mLaunchingProviders.size(); i++) { 12769 ContentProviderRecord cpr = (ContentProviderRecord) 12770 mLaunchingProviders.get(i); 12771 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12772 synchronized (cpr) { 12773 cpr.launchingApp = null; 12774 cpr.notifyAll(); 12775 } 12776 } 12777 } 12778 } 12779 12780 skipCurrentReceiverLocked(app); 12781 12782 // Unregister any receivers. 12783 for (int i=app.receivers.size()-1; i>=0; i--) { 12784 removeReceiverLocked(app.receivers.valueAt(i)); 12785 } 12786 app.receivers.clear(); 12787 12788 // If the app is undergoing backup, tell the backup manager about it 12789 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12790 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12791 + mBackupTarget.appInfo + " died during backup"); 12792 try { 12793 IBackupManager bm = IBackupManager.Stub.asInterface( 12794 ServiceManager.getService(Context.BACKUP_SERVICE)); 12795 bm.agentDisconnected(app.info.packageName); 12796 } catch (RemoteException e) { 12797 // can't happen; backup manager is local 12798 } 12799 } 12800 12801 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12802 ProcessChangeItem item = mPendingProcessChanges.get(i); 12803 if (item.pid == app.pid) { 12804 mPendingProcessChanges.remove(i); 12805 mAvailProcessChanges.add(item); 12806 } 12807 } 12808 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12809 12810 // If the caller is restarting this app, then leave it in its 12811 // current lists and let the caller take care of it. 12812 if (restarting) { 12813 return; 12814 } 12815 12816 if (!app.persistent || app.isolated) { 12817 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12818 "Removing non-persistent process during cleanup: " + app); 12819 mProcessNames.remove(app.processName, app.uid); 12820 mIsolatedProcesses.remove(app.uid); 12821 if (mHeavyWeightProcess == app) { 12822 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12823 mHeavyWeightProcess.userId, 0)); 12824 mHeavyWeightProcess = null; 12825 } 12826 } else if (!app.removed) { 12827 // This app is persistent, so we need to keep its record around. 12828 // If it is not already on the pending app list, add it there 12829 // and start a new process for it. 12830 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12831 mPersistentStartingProcesses.add(app); 12832 restart = true; 12833 } 12834 } 12835 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12836 "Clean-up removing on hold: " + app); 12837 mProcessesOnHold.remove(app); 12838 12839 if (app == mHomeProcess) { 12840 mHomeProcess = null; 12841 } 12842 if (app == mPreviousProcess) { 12843 mPreviousProcess = null; 12844 } 12845 12846 if (restart && !app.isolated) { 12847 // We have components that still need to be running in the 12848 // process, so re-launch it. 12849 mProcessNames.put(app.processName, app.uid, app); 12850 startProcessLocked(app, "restart", app.processName); 12851 } else if (app.pid > 0 && app.pid != MY_PID) { 12852 // Goodbye! 12853 boolean removed; 12854 synchronized (mPidsSelfLocked) { 12855 mPidsSelfLocked.remove(app.pid); 12856 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12857 } 12858 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12859 app.processName, app.info.uid); 12860 if (app.isolated) { 12861 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12862 } 12863 app.setPid(0); 12864 } 12865 } 12866 12867 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12868 // Look through the content providers we are waiting to have launched, 12869 // and if any run in this process then either schedule a restart of 12870 // the process or kill the client waiting for it if this process has 12871 // gone bad. 12872 int NL = mLaunchingProviders.size(); 12873 boolean restart = false; 12874 for (int i=0; i<NL; i++) { 12875 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12876 if (cpr.launchingApp == app) { 12877 if (!alwaysBad && !app.bad) { 12878 restart = true; 12879 } else { 12880 removeDyingProviderLocked(app, cpr, true); 12881 // cpr should have been removed from mLaunchingProviders 12882 NL = mLaunchingProviders.size(); 12883 i--; 12884 } 12885 } 12886 } 12887 return restart; 12888 } 12889 12890 // ========================================================= 12891 // SERVICES 12892 // ========================================================= 12893 12894 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12895 int flags) { 12896 enforceNotIsolatedCaller("getServices"); 12897 synchronized (this) { 12898 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12899 } 12900 } 12901 12902 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12903 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12904 synchronized (this) { 12905 return mServices.getRunningServiceControlPanelLocked(name); 12906 } 12907 } 12908 12909 public ComponentName startService(IApplicationThread caller, Intent service, 12910 String resolvedType, int userId) { 12911 enforceNotIsolatedCaller("startService"); 12912 // Refuse possible leaked file descriptors 12913 if (service != null && service.hasFileDescriptors() == true) { 12914 throw new IllegalArgumentException("File descriptors passed in Intent"); 12915 } 12916 12917 if (DEBUG_SERVICE) 12918 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12919 synchronized(this) { 12920 final int callingPid = Binder.getCallingPid(); 12921 final int callingUid = Binder.getCallingUid(); 12922 final long origId = Binder.clearCallingIdentity(); 12923 ComponentName res = mServices.startServiceLocked(caller, service, 12924 resolvedType, callingPid, callingUid, userId); 12925 Binder.restoreCallingIdentity(origId); 12926 return res; 12927 } 12928 } 12929 12930 ComponentName startServiceInPackage(int uid, 12931 Intent service, String resolvedType, int userId) { 12932 synchronized(this) { 12933 if (DEBUG_SERVICE) 12934 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12935 final long origId = Binder.clearCallingIdentity(); 12936 ComponentName res = mServices.startServiceLocked(null, service, 12937 resolvedType, -1, uid, userId); 12938 Binder.restoreCallingIdentity(origId); 12939 return res; 12940 } 12941 } 12942 12943 public int stopService(IApplicationThread caller, Intent service, 12944 String resolvedType, int userId) { 12945 enforceNotIsolatedCaller("stopService"); 12946 // Refuse possible leaked file descriptors 12947 if (service != null && service.hasFileDescriptors() == true) { 12948 throw new IllegalArgumentException("File descriptors passed in Intent"); 12949 } 12950 12951 synchronized(this) { 12952 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12953 } 12954 } 12955 12956 public IBinder peekService(Intent service, String resolvedType) { 12957 enforceNotIsolatedCaller("peekService"); 12958 // Refuse possible leaked file descriptors 12959 if (service != null && service.hasFileDescriptors() == true) { 12960 throw new IllegalArgumentException("File descriptors passed in Intent"); 12961 } 12962 synchronized(this) { 12963 return mServices.peekServiceLocked(service, resolvedType); 12964 } 12965 } 12966 12967 public boolean stopServiceToken(ComponentName className, IBinder token, 12968 int startId) { 12969 synchronized(this) { 12970 return mServices.stopServiceTokenLocked(className, token, startId); 12971 } 12972 } 12973 12974 public void setServiceForeground(ComponentName className, IBinder token, 12975 int id, Notification notification, boolean removeNotification) { 12976 synchronized(this) { 12977 mServices.setServiceForegroundLocked(className, token, id, notification, 12978 removeNotification); 12979 } 12980 } 12981 12982 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12983 boolean requireFull, String name, String callerPackage) { 12984 final int callingUserId = UserHandle.getUserId(callingUid); 12985 if (callingUserId != userId) { 12986 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12987 if ((requireFull || checkComponentPermission( 12988 android.Manifest.permission.INTERACT_ACROSS_USERS, 12989 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12990 && checkComponentPermission( 12991 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12992 callingPid, callingUid, -1, true) 12993 != PackageManager.PERMISSION_GRANTED) { 12994 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12995 // In this case, they would like to just execute as their 12996 // owner user instead of failing. 12997 userId = callingUserId; 12998 } else { 12999 StringBuilder builder = new StringBuilder(128); 13000 builder.append("Permission Denial: "); 13001 builder.append(name); 13002 if (callerPackage != null) { 13003 builder.append(" from "); 13004 builder.append(callerPackage); 13005 } 13006 builder.append(" asks to run as user "); 13007 builder.append(userId); 13008 builder.append(" but is calling from user "); 13009 builder.append(UserHandle.getUserId(callingUid)); 13010 builder.append("; this requires "); 13011 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 13012 if (!requireFull) { 13013 builder.append(" or "); 13014 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13015 } 13016 String msg = builder.toString(); 13017 Slog.w(TAG, msg); 13018 throw new SecurityException(msg); 13019 } 13020 } 13021 } 13022 if (userId == UserHandle.USER_CURRENT 13023 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13024 // Note that we may be accessing this outside of a lock... 13025 // shouldn't be a big deal, if this is being called outside 13026 // of a locked context there is intrinsically a race with 13027 // the value the caller will receive and someone else changing it. 13028 userId = mCurrentUserId; 13029 } 13030 if (!allowAll && userId < 0) { 13031 throw new IllegalArgumentException( 13032 "Call does not support special user #" + userId); 13033 } 13034 } 13035 return userId; 13036 } 13037 13038 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13039 String className, int flags) { 13040 boolean result = false; 13041 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13042 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 13043 if (ActivityManager.checkUidPermission( 13044 android.Manifest.permission.INTERACT_ACROSS_USERS, 13045 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13046 ComponentName comp = new ComponentName(aInfo.packageName, className); 13047 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13048 + " requests FLAG_SINGLE_USER, but app does not hold " 13049 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13050 Slog.w(TAG, msg); 13051 throw new SecurityException(msg); 13052 } 13053 result = true; 13054 } 13055 } else if (componentProcessName == aInfo.packageName) { 13056 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13057 } else if ("system".equals(componentProcessName)) { 13058 result = true; 13059 } 13060 if (DEBUG_MU) { 13061 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13062 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13063 } 13064 return result; 13065 } 13066 13067 public int bindService(IApplicationThread caller, IBinder token, 13068 Intent service, String resolvedType, 13069 IServiceConnection connection, int flags, int userId) { 13070 enforceNotIsolatedCaller("bindService"); 13071 // Refuse possible leaked file descriptors 13072 if (service != null && service.hasFileDescriptors() == true) { 13073 throw new IllegalArgumentException("File descriptors passed in Intent"); 13074 } 13075 13076 synchronized(this) { 13077 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13078 connection, flags, userId); 13079 } 13080 } 13081 13082 public boolean unbindService(IServiceConnection connection) { 13083 synchronized (this) { 13084 return mServices.unbindServiceLocked(connection); 13085 } 13086 } 13087 13088 public void publishService(IBinder token, Intent intent, IBinder service) { 13089 // Refuse possible leaked file descriptors 13090 if (intent != null && intent.hasFileDescriptors() == true) { 13091 throw new IllegalArgumentException("File descriptors passed in Intent"); 13092 } 13093 13094 synchronized(this) { 13095 if (!(token instanceof ServiceRecord)) { 13096 throw new IllegalArgumentException("Invalid service token"); 13097 } 13098 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13099 } 13100 } 13101 13102 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13103 // Refuse possible leaked file descriptors 13104 if (intent != null && intent.hasFileDescriptors() == true) { 13105 throw new IllegalArgumentException("File descriptors passed in Intent"); 13106 } 13107 13108 synchronized(this) { 13109 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13110 } 13111 } 13112 13113 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13114 synchronized(this) { 13115 if (!(token instanceof ServiceRecord)) { 13116 throw new IllegalArgumentException("Invalid service token"); 13117 } 13118 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13119 } 13120 } 13121 13122 // ========================================================= 13123 // BACKUP AND RESTORE 13124 // ========================================================= 13125 13126 // Cause the target app to be launched if necessary and its backup agent 13127 // instantiated. The backup agent will invoke backupAgentCreated() on the 13128 // activity manager to announce its creation. 13129 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13130 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13131 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13132 13133 synchronized(this) { 13134 // !!! TODO: currently no check here that we're already bound 13135 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13136 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13137 synchronized (stats) { 13138 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13139 } 13140 13141 // Backup agent is now in use, its package can't be stopped. 13142 try { 13143 AppGlobals.getPackageManager().setPackageStoppedState( 13144 app.packageName, false, UserHandle.getUserId(app.uid)); 13145 } catch (RemoteException e) { 13146 } catch (IllegalArgumentException e) { 13147 Slog.w(TAG, "Failed trying to unstop package " 13148 + app.packageName + ": " + e); 13149 } 13150 13151 BackupRecord r = new BackupRecord(ss, app, backupMode); 13152 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13153 ? new ComponentName(app.packageName, app.backupAgentName) 13154 : new ComponentName("android", "FullBackupAgent"); 13155 // startProcessLocked() returns existing proc's record if it's already running 13156 ProcessRecord proc = startProcessLocked(app.processName, app, 13157 false, 0, "backup", hostingName, false, false, false); 13158 if (proc == null) { 13159 Slog.e(TAG, "Unable to start backup agent process " + r); 13160 return false; 13161 } 13162 13163 r.app = proc; 13164 mBackupTarget = r; 13165 mBackupAppName = app.packageName; 13166 13167 // Try not to kill the process during backup 13168 updateOomAdjLocked(proc); 13169 13170 // If the process is already attached, schedule the creation of the backup agent now. 13171 // If it is not yet live, this will be done when it attaches to the framework. 13172 if (proc.thread != null) { 13173 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13174 try { 13175 proc.thread.scheduleCreateBackupAgent(app, 13176 compatibilityInfoForPackageLocked(app), backupMode); 13177 } catch (RemoteException e) { 13178 // Will time out on the backup manager side 13179 } 13180 } else { 13181 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13182 } 13183 // Invariants: at this point, the target app process exists and the application 13184 // is either already running or in the process of coming up. mBackupTarget and 13185 // mBackupAppName describe the app, so that when it binds back to the AM we 13186 // know that it's scheduled for a backup-agent operation. 13187 } 13188 13189 return true; 13190 } 13191 13192 @Override 13193 public void clearPendingBackup() { 13194 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13195 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13196 13197 synchronized (this) { 13198 mBackupTarget = null; 13199 mBackupAppName = null; 13200 } 13201 } 13202 13203 // A backup agent has just come up 13204 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13205 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13206 + " = " + agent); 13207 13208 synchronized(this) { 13209 if (!agentPackageName.equals(mBackupAppName)) { 13210 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13211 return; 13212 } 13213 } 13214 13215 long oldIdent = Binder.clearCallingIdentity(); 13216 try { 13217 IBackupManager bm = IBackupManager.Stub.asInterface( 13218 ServiceManager.getService(Context.BACKUP_SERVICE)); 13219 bm.agentConnected(agentPackageName, agent); 13220 } catch (RemoteException e) { 13221 // can't happen; the backup manager service is local 13222 } catch (Exception e) { 13223 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13224 e.printStackTrace(); 13225 } finally { 13226 Binder.restoreCallingIdentity(oldIdent); 13227 } 13228 } 13229 13230 // done with this agent 13231 public void unbindBackupAgent(ApplicationInfo appInfo) { 13232 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13233 if (appInfo == null) { 13234 Slog.w(TAG, "unbind backup agent for null app"); 13235 return; 13236 } 13237 13238 synchronized(this) { 13239 try { 13240 if (mBackupAppName == null) { 13241 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13242 return; 13243 } 13244 13245 if (!mBackupAppName.equals(appInfo.packageName)) { 13246 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13247 return; 13248 } 13249 13250 // Not backing this app up any more; reset its OOM adjustment 13251 final ProcessRecord proc = mBackupTarget.app; 13252 updateOomAdjLocked(proc); 13253 13254 // If the app crashed during backup, 'thread' will be null here 13255 if (proc.thread != null) { 13256 try { 13257 proc.thread.scheduleDestroyBackupAgent(appInfo, 13258 compatibilityInfoForPackageLocked(appInfo)); 13259 } catch (Exception e) { 13260 Slog.e(TAG, "Exception when unbinding backup agent:"); 13261 e.printStackTrace(); 13262 } 13263 } 13264 } finally { 13265 mBackupTarget = null; 13266 mBackupAppName = null; 13267 } 13268 } 13269 } 13270 // ========================================================= 13271 // BROADCASTS 13272 // ========================================================= 13273 13274 private final List getStickiesLocked(String action, IntentFilter filter, 13275 List cur, int userId) { 13276 final ContentResolver resolver = mContext.getContentResolver(); 13277 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13278 if (stickies == null) { 13279 return cur; 13280 } 13281 final ArrayList<Intent> list = stickies.get(action); 13282 if (list == null) { 13283 return cur; 13284 } 13285 int N = list.size(); 13286 for (int i=0; i<N; i++) { 13287 Intent intent = list.get(i); 13288 if (filter.match(resolver, intent, true, TAG) >= 0) { 13289 if (cur == null) { 13290 cur = new ArrayList<Intent>(); 13291 } 13292 cur.add(intent); 13293 } 13294 } 13295 return cur; 13296 } 13297 13298 boolean isPendingBroadcastProcessLocked(int pid) { 13299 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13300 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13301 } 13302 13303 void skipPendingBroadcastLocked(int pid) { 13304 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13305 for (BroadcastQueue queue : mBroadcastQueues) { 13306 queue.skipPendingBroadcastLocked(pid); 13307 } 13308 } 13309 13310 // The app just attached; send any pending broadcasts that it should receive 13311 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13312 boolean didSomething = false; 13313 for (BroadcastQueue queue : mBroadcastQueues) { 13314 didSomething |= queue.sendPendingBroadcastsLocked(app); 13315 } 13316 return didSomething; 13317 } 13318 13319 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13320 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13321 enforceNotIsolatedCaller("registerReceiver"); 13322 int callingUid; 13323 int callingPid; 13324 synchronized(this) { 13325 ProcessRecord callerApp = null; 13326 if (caller != null) { 13327 callerApp = getRecordForAppLocked(caller); 13328 if (callerApp == null) { 13329 throw new SecurityException( 13330 "Unable to find app for caller " + caller 13331 + " (pid=" + Binder.getCallingPid() 13332 + ") when registering receiver " + receiver); 13333 } 13334 if (callerApp.info.uid != Process.SYSTEM_UID && 13335 !callerApp.pkgList.containsKey(callerPackage) && 13336 !"android".equals(callerPackage)) { 13337 throw new SecurityException("Given caller package " + callerPackage 13338 + " is not running in process " + callerApp); 13339 } 13340 callingUid = callerApp.info.uid; 13341 callingPid = callerApp.pid; 13342 } else { 13343 callerPackage = null; 13344 callingUid = Binder.getCallingUid(); 13345 callingPid = Binder.getCallingPid(); 13346 } 13347 13348 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13349 true, true, "registerReceiver", callerPackage); 13350 13351 List allSticky = null; 13352 13353 // Look for any matching sticky broadcasts... 13354 Iterator actions = filter.actionsIterator(); 13355 if (actions != null) { 13356 while (actions.hasNext()) { 13357 String action = (String)actions.next(); 13358 allSticky = getStickiesLocked(action, filter, allSticky, 13359 UserHandle.USER_ALL); 13360 allSticky = getStickiesLocked(action, filter, allSticky, 13361 UserHandle.getUserId(callingUid)); 13362 } 13363 } else { 13364 allSticky = getStickiesLocked(null, filter, allSticky, 13365 UserHandle.USER_ALL); 13366 allSticky = getStickiesLocked(null, filter, allSticky, 13367 UserHandle.getUserId(callingUid)); 13368 } 13369 13370 // The first sticky in the list is returned directly back to 13371 // the client. 13372 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13373 13374 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13375 + ": " + sticky); 13376 13377 if (receiver == null) { 13378 return sticky; 13379 } 13380 13381 ReceiverList rl 13382 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13383 if (rl == null) { 13384 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13385 userId, receiver); 13386 if (rl.app != null) { 13387 rl.app.receivers.add(rl); 13388 } else { 13389 try { 13390 receiver.asBinder().linkToDeath(rl, 0); 13391 } catch (RemoteException e) { 13392 return sticky; 13393 } 13394 rl.linkedToDeath = true; 13395 } 13396 mRegisteredReceivers.put(receiver.asBinder(), rl); 13397 } else if (rl.uid != callingUid) { 13398 throw new IllegalArgumentException( 13399 "Receiver requested to register for uid " + callingUid 13400 + " was previously registered for uid " + rl.uid); 13401 } else if (rl.pid != callingPid) { 13402 throw new IllegalArgumentException( 13403 "Receiver requested to register for pid " + callingPid 13404 + " was previously registered for pid " + rl.pid); 13405 } else if (rl.userId != userId) { 13406 throw new IllegalArgumentException( 13407 "Receiver requested to register for user " + userId 13408 + " was previously registered for user " + rl.userId); 13409 } 13410 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13411 permission, callingUid, userId); 13412 rl.add(bf); 13413 if (!bf.debugCheck()) { 13414 Slog.w(TAG, "==> For Dynamic broadast"); 13415 } 13416 mReceiverResolver.addFilter(bf); 13417 13418 // Enqueue broadcasts for all existing stickies that match 13419 // this filter. 13420 if (allSticky != null) { 13421 ArrayList receivers = new ArrayList(); 13422 receivers.add(bf); 13423 13424 int N = allSticky.size(); 13425 for (int i=0; i<N; i++) { 13426 Intent intent = (Intent)allSticky.get(i); 13427 BroadcastQueue queue = broadcastQueueForIntent(intent); 13428 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13429 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13430 null, null, false, true, true, -1); 13431 queue.enqueueParallelBroadcastLocked(r); 13432 queue.scheduleBroadcastsLocked(); 13433 } 13434 } 13435 13436 return sticky; 13437 } 13438 } 13439 13440 public void unregisterReceiver(IIntentReceiver receiver) { 13441 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13442 13443 final long origId = Binder.clearCallingIdentity(); 13444 try { 13445 boolean doTrim = false; 13446 13447 synchronized(this) { 13448 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13449 if (rl != null) { 13450 if (rl.curBroadcast != null) { 13451 BroadcastRecord r = rl.curBroadcast; 13452 final boolean doNext = finishReceiverLocked( 13453 receiver.asBinder(), r.resultCode, r.resultData, 13454 r.resultExtras, r.resultAbort); 13455 if (doNext) { 13456 doTrim = true; 13457 r.queue.processNextBroadcast(false); 13458 } 13459 } 13460 13461 if (rl.app != null) { 13462 rl.app.receivers.remove(rl); 13463 } 13464 removeReceiverLocked(rl); 13465 if (rl.linkedToDeath) { 13466 rl.linkedToDeath = false; 13467 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13468 } 13469 } 13470 } 13471 13472 // If we actually concluded any broadcasts, we might now be able 13473 // to trim the recipients' apps from our working set 13474 if (doTrim) { 13475 trimApplications(); 13476 return; 13477 } 13478 13479 } finally { 13480 Binder.restoreCallingIdentity(origId); 13481 } 13482 } 13483 13484 void removeReceiverLocked(ReceiverList rl) { 13485 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13486 int N = rl.size(); 13487 for (int i=0; i<N; i++) { 13488 mReceiverResolver.removeFilter(rl.get(i)); 13489 } 13490 } 13491 13492 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13493 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13494 ProcessRecord r = mLruProcesses.get(i); 13495 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13496 try { 13497 r.thread.dispatchPackageBroadcast(cmd, packages); 13498 } catch (RemoteException ex) { 13499 } 13500 } 13501 } 13502 } 13503 13504 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13505 int[] users) { 13506 List<ResolveInfo> receivers = null; 13507 try { 13508 HashSet<ComponentName> singleUserReceivers = null; 13509 boolean scannedFirstReceivers = false; 13510 for (int user : users) { 13511 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13512 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13513 if (user != 0 && newReceivers != null) { 13514 // If this is not the primary user, we need to check for 13515 // any receivers that should be filtered out. 13516 for (int i=0; i<newReceivers.size(); i++) { 13517 ResolveInfo ri = newReceivers.get(i); 13518 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13519 newReceivers.remove(i); 13520 i--; 13521 } 13522 } 13523 } 13524 if (newReceivers != null && newReceivers.size() == 0) { 13525 newReceivers = null; 13526 } 13527 if (receivers == null) { 13528 receivers = newReceivers; 13529 } else if (newReceivers != null) { 13530 // We need to concatenate the additional receivers 13531 // found with what we have do far. This would be easy, 13532 // but we also need to de-dup any receivers that are 13533 // singleUser. 13534 if (!scannedFirstReceivers) { 13535 // Collect any single user receivers we had already retrieved. 13536 scannedFirstReceivers = true; 13537 for (int i=0; i<receivers.size(); i++) { 13538 ResolveInfo ri = receivers.get(i); 13539 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13540 ComponentName cn = new ComponentName( 13541 ri.activityInfo.packageName, ri.activityInfo.name); 13542 if (singleUserReceivers == null) { 13543 singleUserReceivers = new HashSet<ComponentName>(); 13544 } 13545 singleUserReceivers.add(cn); 13546 } 13547 } 13548 } 13549 // Add the new results to the existing results, tracking 13550 // and de-dupping single user receivers. 13551 for (int i=0; i<newReceivers.size(); i++) { 13552 ResolveInfo ri = newReceivers.get(i); 13553 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13554 ComponentName cn = new ComponentName( 13555 ri.activityInfo.packageName, ri.activityInfo.name); 13556 if (singleUserReceivers == null) { 13557 singleUserReceivers = new HashSet<ComponentName>(); 13558 } 13559 if (!singleUserReceivers.contains(cn)) { 13560 singleUserReceivers.add(cn); 13561 receivers.add(ri); 13562 } 13563 } else { 13564 receivers.add(ri); 13565 } 13566 } 13567 } 13568 } 13569 } catch (RemoteException ex) { 13570 // pm is in same process, this will never happen. 13571 } 13572 return receivers; 13573 } 13574 13575 private final int broadcastIntentLocked(ProcessRecord callerApp, 13576 String callerPackage, Intent intent, String resolvedType, 13577 IIntentReceiver resultTo, int resultCode, String resultData, 13578 Bundle map, String requiredPermission, int appOp, 13579 boolean ordered, boolean sticky, int callingPid, int callingUid, 13580 int userId) { 13581 intent = new Intent(intent); 13582 13583 // By default broadcasts do not go to stopped apps. 13584 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13585 13586 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13587 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13588 + " ordered=" + ordered + " userid=" + userId); 13589 if ((resultTo != null) && !ordered) { 13590 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13591 } 13592 13593 userId = handleIncomingUser(callingPid, callingUid, userId, 13594 true, false, "broadcast", callerPackage); 13595 13596 // Make sure that the user who is receiving this broadcast is started. 13597 // If not, we will just skip it. 13598 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13599 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13600 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13601 Slog.w(TAG, "Skipping broadcast of " + intent 13602 + ": user " + userId + " is stopped"); 13603 return ActivityManager.BROADCAST_SUCCESS; 13604 } 13605 } 13606 13607 /* 13608 * Prevent non-system code (defined here to be non-persistent 13609 * processes) from sending protected broadcasts. 13610 */ 13611 int callingAppId = UserHandle.getAppId(callingUid); 13612 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13613 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13614 callingUid == 0) { 13615 // Always okay. 13616 } else if (callerApp == null || !callerApp.persistent) { 13617 try { 13618 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13619 intent.getAction())) { 13620 String msg = "Permission Denial: not allowed to send broadcast " 13621 + intent.getAction() + " from pid=" 13622 + callingPid + ", uid=" + callingUid; 13623 Slog.w(TAG, msg); 13624 throw new SecurityException(msg); 13625 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13626 // Special case for compatibility: we don't want apps to send this, 13627 // but historically it has not been protected and apps may be using it 13628 // to poke their own app widget. So, instead of making it protected, 13629 // just limit it to the caller. 13630 if (callerApp == null) { 13631 String msg = "Permission Denial: not allowed to send broadcast " 13632 + intent.getAction() + " from unknown caller."; 13633 Slog.w(TAG, msg); 13634 throw new SecurityException(msg); 13635 } else if (intent.getComponent() != null) { 13636 // They are good enough to send to an explicit component... verify 13637 // it is being sent to the calling app. 13638 if (!intent.getComponent().getPackageName().equals( 13639 callerApp.info.packageName)) { 13640 String msg = "Permission Denial: not allowed to send broadcast " 13641 + intent.getAction() + " to " 13642 + intent.getComponent().getPackageName() + " from " 13643 + callerApp.info.packageName; 13644 Slog.w(TAG, msg); 13645 throw new SecurityException(msg); 13646 } 13647 } else { 13648 // Limit broadcast to their own package. 13649 intent.setPackage(callerApp.info.packageName); 13650 } 13651 } 13652 } catch (RemoteException e) { 13653 Slog.w(TAG, "Remote exception", e); 13654 return ActivityManager.BROADCAST_SUCCESS; 13655 } 13656 } 13657 13658 // Handle special intents: if this broadcast is from the package 13659 // manager about a package being removed, we need to remove all of 13660 // its activities from the history stack. 13661 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13662 intent.getAction()); 13663 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13664 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13665 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13666 || uidRemoved) { 13667 if (checkComponentPermission( 13668 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13669 callingPid, callingUid, -1, true) 13670 == PackageManager.PERMISSION_GRANTED) { 13671 if (uidRemoved) { 13672 final Bundle intentExtras = intent.getExtras(); 13673 final int uid = intentExtras != null 13674 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13675 if (uid >= 0) { 13676 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13677 synchronized (bs) { 13678 bs.removeUidStatsLocked(uid); 13679 } 13680 mAppOpsService.uidRemoved(uid); 13681 } 13682 } else { 13683 // If resources are unavailable just force stop all 13684 // those packages and flush the attribute cache as well. 13685 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13686 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13687 if (list != null && (list.length > 0)) { 13688 for (String pkg : list) { 13689 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13690 "storage unmount"); 13691 } 13692 sendPackageBroadcastLocked( 13693 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13694 } 13695 } else { 13696 Uri data = intent.getData(); 13697 String ssp; 13698 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13699 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13700 intent.getAction()); 13701 boolean fullUninstall = removed && 13702 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13703 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13704 forceStopPackageLocked(ssp, UserHandle.getAppId( 13705 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13706 false, fullUninstall, userId, 13707 removed ? "pkg removed" : "pkg changed"); 13708 } 13709 if (removed) { 13710 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13711 new String[] {ssp}, userId); 13712 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13713 mAppOpsService.packageRemoved( 13714 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13715 13716 // Remove all permissions granted from/to this package 13717 removeUriPermissionsForPackageLocked(ssp, userId, true); 13718 } 13719 } 13720 } 13721 } 13722 } 13723 } else { 13724 String msg = "Permission Denial: " + intent.getAction() 13725 + " broadcast from " + callerPackage + " (pid=" + callingPid 13726 + ", uid=" + callingUid + ")" 13727 + " requires " 13728 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13729 Slog.w(TAG, msg); 13730 throw new SecurityException(msg); 13731 } 13732 13733 // Special case for adding a package: by default turn on compatibility 13734 // mode. 13735 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13736 Uri data = intent.getData(); 13737 String ssp; 13738 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13739 mCompatModePackages.handlePackageAddedLocked(ssp, 13740 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13741 } 13742 } 13743 13744 /* 13745 * If this is the time zone changed action, queue up a message that will reset the timezone 13746 * of all currently running processes. This message will get queued up before the broadcast 13747 * happens. 13748 */ 13749 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13750 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13751 } 13752 13753 /* 13754 * If the user set the time, let all running processes know. 13755 */ 13756 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13757 final int is24Hour = intent.getBooleanExtra( 13758 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13759 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13760 } 13761 13762 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13763 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13764 } 13765 13766 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13767 ProxyInfo proxy = intent.getParcelableExtra("proxy"); 13768 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13769 } 13770 13771 // Add to the sticky list if requested. 13772 if (sticky) { 13773 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13774 callingPid, callingUid) 13775 != PackageManager.PERMISSION_GRANTED) { 13776 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13777 + callingPid + ", uid=" + callingUid 13778 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13779 Slog.w(TAG, msg); 13780 throw new SecurityException(msg); 13781 } 13782 if (requiredPermission != null) { 13783 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13784 + " and enforce permission " + requiredPermission); 13785 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13786 } 13787 if (intent.getComponent() != null) { 13788 throw new SecurityException( 13789 "Sticky broadcasts can't target a specific component"); 13790 } 13791 // We use userId directly here, since the "all" target is maintained 13792 // as a separate set of sticky broadcasts. 13793 if (userId != UserHandle.USER_ALL) { 13794 // But first, if this is not a broadcast to all users, then 13795 // make sure it doesn't conflict with an existing broadcast to 13796 // all users. 13797 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13798 UserHandle.USER_ALL); 13799 if (stickies != null) { 13800 ArrayList<Intent> list = stickies.get(intent.getAction()); 13801 if (list != null) { 13802 int N = list.size(); 13803 int i; 13804 for (i=0; i<N; i++) { 13805 if (intent.filterEquals(list.get(i))) { 13806 throw new IllegalArgumentException( 13807 "Sticky broadcast " + intent + " for user " 13808 + userId + " conflicts with existing global broadcast"); 13809 } 13810 } 13811 } 13812 } 13813 } 13814 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13815 if (stickies == null) { 13816 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13817 mStickyBroadcasts.put(userId, stickies); 13818 } 13819 ArrayList<Intent> list = stickies.get(intent.getAction()); 13820 if (list == null) { 13821 list = new ArrayList<Intent>(); 13822 stickies.put(intent.getAction(), list); 13823 } 13824 int N = list.size(); 13825 int i; 13826 for (i=0; i<N; i++) { 13827 if (intent.filterEquals(list.get(i))) { 13828 // This sticky already exists, replace it. 13829 list.set(i, new Intent(intent)); 13830 break; 13831 } 13832 } 13833 if (i >= N) { 13834 list.add(new Intent(intent)); 13835 } 13836 } 13837 13838 int[] users; 13839 if (userId == UserHandle.USER_ALL) { 13840 // Caller wants broadcast to go to all started users. 13841 users = mStartedUserArray; 13842 } else { 13843 // Caller wants broadcast to go to one specific user. 13844 users = new int[] {userId}; 13845 } 13846 13847 // Figure out who all will receive this broadcast. 13848 List receivers = null; 13849 List<BroadcastFilter> registeredReceivers = null; 13850 // Need to resolve the intent to interested receivers... 13851 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13852 == 0) { 13853 receivers = collectReceiverComponents(intent, resolvedType, users); 13854 } 13855 if (intent.getComponent() == null) { 13856 registeredReceivers = mReceiverResolver.queryIntent(intent, 13857 resolvedType, false, userId); 13858 } 13859 13860 final boolean replacePending = 13861 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13862 13863 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13864 + " replacePending=" + replacePending); 13865 13866 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13867 if (!ordered && NR > 0) { 13868 // If we are not serializing this broadcast, then send the 13869 // registered receivers separately so they don't wait for the 13870 // components to be launched. 13871 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13872 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13873 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13874 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13875 ordered, sticky, false, userId); 13876 if (DEBUG_BROADCAST) Slog.v( 13877 TAG, "Enqueueing parallel broadcast " + r); 13878 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13879 if (!replaced) { 13880 queue.enqueueParallelBroadcastLocked(r); 13881 queue.scheduleBroadcastsLocked(); 13882 } 13883 registeredReceivers = null; 13884 NR = 0; 13885 } 13886 13887 // Merge into one list. 13888 int ir = 0; 13889 if (receivers != null) { 13890 // A special case for PACKAGE_ADDED: do not allow the package 13891 // being added to see this broadcast. This prevents them from 13892 // using this as a back door to get run as soon as they are 13893 // installed. Maybe in the future we want to have a special install 13894 // broadcast or such for apps, but we'd like to deliberately make 13895 // this decision. 13896 String skipPackages[] = null; 13897 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13898 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13899 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13900 Uri data = intent.getData(); 13901 if (data != null) { 13902 String pkgName = data.getSchemeSpecificPart(); 13903 if (pkgName != null) { 13904 skipPackages = new String[] { pkgName }; 13905 } 13906 } 13907 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13908 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13909 } 13910 if (skipPackages != null && (skipPackages.length > 0)) { 13911 for (String skipPackage : skipPackages) { 13912 if (skipPackage != null) { 13913 int NT = receivers.size(); 13914 for (int it=0; it<NT; it++) { 13915 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13916 if (curt.activityInfo.packageName.equals(skipPackage)) { 13917 receivers.remove(it); 13918 it--; 13919 NT--; 13920 } 13921 } 13922 } 13923 } 13924 } 13925 13926 int NT = receivers != null ? receivers.size() : 0; 13927 int it = 0; 13928 ResolveInfo curt = null; 13929 BroadcastFilter curr = null; 13930 while (it < NT && ir < NR) { 13931 if (curt == null) { 13932 curt = (ResolveInfo)receivers.get(it); 13933 } 13934 if (curr == null) { 13935 curr = registeredReceivers.get(ir); 13936 } 13937 if (curr.getPriority() >= curt.priority) { 13938 // Insert this broadcast record into the final list. 13939 receivers.add(it, curr); 13940 ir++; 13941 curr = null; 13942 it++; 13943 NT++; 13944 } else { 13945 // Skip to the next ResolveInfo in the final list. 13946 it++; 13947 curt = null; 13948 } 13949 } 13950 } 13951 while (ir < NR) { 13952 if (receivers == null) { 13953 receivers = new ArrayList(); 13954 } 13955 receivers.add(registeredReceivers.get(ir)); 13956 ir++; 13957 } 13958 13959 if ((receivers != null && receivers.size() > 0) 13960 || resultTo != null) { 13961 BroadcastQueue queue = broadcastQueueForIntent(intent); 13962 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13963 callerPackage, callingPid, callingUid, resolvedType, 13964 requiredPermission, appOp, receivers, resultTo, resultCode, 13965 resultData, map, ordered, sticky, false, userId); 13966 if (DEBUG_BROADCAST) Slog.v( 13967 TAG, "Enqueueing ordered broadcast " + r 13968 + ": prev had " + queue.mOrderedBroadcasts.size()); 13969 if (DEBUG_BROADCAST) { 13970 int seq = r.intent.getIntExtra("seq", -1); 13971 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13972 } 13973 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13974 if (!replaced) { 13975 queue.enqueueOrderedBroadcastLocked(r); 13976 queue.scheduleBroadcastsLocked(); 13977 } 13978 } 13979 13980 return ActivityManager.BROADCAST_SUCCESS; 13981 } 13982 13983 final Intent verifyBroadcastLocked(Intent intent) { 13984 // Refuse possible leaked file descriptors 13985 if (intent != null && intent.hasFileDescriptors() == true) { 13986 throw new IllegalArgumentException("File descriptors passed in Intent"); 13987 } 13988 13989 int flags = intent.getFlags(); 13990 13991 if (!mProcessesReady) { 13992 // if the caller really truly claims to know what they're doing, go 13993 // ahead and allow the broadcast without launching any receivers 13994 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13995 intent = new Intent(intent); 13996 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13997 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13998 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13999 + " before boot completion"); 14000 throw new IllegalStateException("Cannot broadcast before boot completed"); 14001 } 14002 } 14003 14004 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14005 throw new IllegalArgumentException( 14006 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14007 } 14008 14009 return intent; 14010 } 14011 14012 public final int broadcastIntent(IApplicationThread caller, 14013 Intent intent, String resolvedType, IIntentReceiver resultTo, 14014 int resultCode, String resultData, Bundle map, 14015 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14016 enforceNotIsolatedCaller("broadcastIntent"); 14017 synchronized(this) { 14018 intent = verifyBroadcastLocked(intent); 14019 14020 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14021 final int callingPid = Binder.getCallingPid(); 14022 final int callingUid = Binder.getCallingUid(); 14023 final long origId = Binder.clearCallingIdentity(); 14024 int res = broadcastIntentLocked(callerApp, 14025 callerApp != null ? callerApp.info.packageName : null, 14026 intent, resolvedType, resultTo, 14027 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14028 callingPid, callingUid, userId); 14029 Binder.restoreCallingIdentity(origId); 14030 return res; 14031 } 14032 } 14033 14034 int broadcastIntentInPackage(String packageName, int uid, 14035 Intent intent, String resolvedType, IIntentReceiver resultTo, 14036 int resultCode, String resultData, Bundle map, 14037 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14038 synchronized(this) { 14039 intent = verifyBroadcastLocked(intent); 14040 14041 final long origId = Binder.clearCallingIdentity(); 14042 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14043 resultTo, resultCode, resultData, map, requiredPermission, 14044 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14045 Binder.restoreCallingIdentity(origId); 14046 return res; 14047 } 14048 } 14049 14050 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14051 // Refuse possible leaked file descriptors 14052 if (intent != null && intent.hasFileDescriptors() == true) { 14053 throw new IllegalArgumentException("File descriptors passed in Intent"); 14054 } 14055 14056 userId = handleIncomingUser(Binder.getCallingPid(), 14057 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14058 14059 synchronized(this) { 14060 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14061 != PackageManager.PERMISSION_GRANTED) { 14062 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14063 + Binder.getCallingPid() 14064 + ", uid=" + Binder.getCallingUid() 14065 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14066 Slog.w(TAG, msg); 14067 throw new SecurityException(msg); 14068 } 14069 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14070 if (stickies != null) { 14071 ArrayList<Intent> list = stickies.get(intent.getAction()); 14072 if (list != null) { 14073 int N = list.size(); 14074 int i; 14075 for (i=0; i<N; i++) { 14076 if (intent.filterEquals(list.get(i))) { 14077 list.remove(i); 14078 break; 14079 } 14080 } 14081 if (list.size() <= 0) { 14082 stickies.remove(intent.getAction()); 14083 } 14084 } 14085 if (stickies.size() <= 0) { 14086 mStickyBroadcasts.remove(userId); 14087 } 14088 } 14089 } 14090 } 14091 14092 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14093 String resultData, Bundle resultExtras, boolean resultAbort) { 14094 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14095 if (r == null) { 14096 Slog.w(TAG, "finishReceiver called but not found on queue"); 14097 return false; 14098 } 14099 14100 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14101 } 14102 14103 void backgroundServicesFinishedLocked(int userId) { 14104 for (BroadcastQueue queue : mBroadcastQueues) { 14105 queue.backgroundServicesFinishedLocked(userId); 14106 } 14107 } 14108 14109 public void finishReceiver(IBinder who, int resultCode, String resultData, 14110 Bundle resultExtras, boolean resultAbort) { 14111 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14112 14113 // Refuse possible leaked file descriptors 14114 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14115 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14116 } 14117 14118 final long origId = Binder.clearCallingIdentity(); 14119 try { 14120 boolean doNext = false; 14121 BroadcastRecord r; 14122 14123 synchronized(this) { 14124 r = broadcastRecordForReceiverLocked(who); 14125 if (r != null) { 14126 doNext = r.queue.finishReceiverLocked(r, resultCode, 14127 resultData, resultExtras, resultAbort, true); 14128 } 14129 } 14130 14131 if (doNext) { 14132 r.queue.processNextBroadcast(false); 14133 } 14134 trimApplications(); 14135 } finally { 14136 Binder.restoreCallingIdentity(origId); 14137 } 14138 } 14139 14140 // ========================================================= 14141 // INSTRUMENTATION 14142 // ========================================================= 14143 14144 public boolean startInstrumentation(ComponentName className, 14145 String profileFile, int flags, Bundle arguments, 14146 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14147 int userId) { 14148 enforceNotIsolatedCaller("startInstrumentation"); 14149 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14150 userId, false, true, "startInstrumentation", null); 14151 // Refuse possible leaked file descriptors 14152 if (arguments != null && arguments.hasFileDescriptors()) { 14153 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14154 } 14155 14156 synchronized(this) { 14157 InstrumentationInfo ii = null; 14158 ApplicationInfo ai = null; 14159 try { 14160 ii = mContext.getPackageManager().getInstrumentationInfo( 14161 className, STOCK_PM_FLAGS); 14162 ai = AppGlobals.getPackageManager().getApplicationInfo( 14163 ii.targetPackage, STOCK_PM_FLAGS, userId); 14164 } catch (PackageManager.NameNotFoundException e) { 14165 } catch (RemoteException e) { 14166 } 14167 if (ii == null) { 14168 reportStartInstrumentationFailure(watcher, className, 14169 "Unable to find instrumentation info for: " + className); 14170 return false; 14171 } 14172 if (ai == null) { 14173 reportStartInstrumentationFailure(watcher, className, 14174 "Unable to find instrumentation target package: " + ii.targetPackage); 14175 return false; 14176 } 14177 14178 int match = mContext.getPackageManager().checkSignatures( 14179 ii.targetPackage, ii.packageName); 14180 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14181 String msg = "Permission Denial: starting instrumentation " 14182 + className + " from pid=" 14183 + Binder.getCallingPid() 14184 + ", uid=" + Binder.getCallingPid() 14185 + " not allowed because package " + ii.packageName 14186 + " does not have a signature matching the target " 14187 + ii.targetPackage; 14188 reportStartInstrumentationFailure(watcher, className, msg); 14189 throw new SecurityException(msg); 14190 } 14191 14192 final long origId = Binder.clearCallingIdentity(); 14193 // Instrumentation can kill and relaunch even persistent processes 14194 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14195 "start instr"); 14196 ProcessRecord app = addAppLocked(ai, false); 14197 app.instrumentationClass = className; 14198 app.instrumentationInfo = ai; 14199 app.instrumentationProfileFile = profileFile; 14200 app.instrumentationArguments = arguments; 14201 app.instrumentationWatcher = watcher; 14202 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14203 app.instrumentationResultClass = className; 14204 Binder.restoreCallingIdentity(origId); 14205 } 14206 14207 return true; 14208 } 14209 14210 /** 14211 * Report errors that occur while attempting to start Instrumentation. Always writes the 14212 * error to the logs, but if somebody is watching, send the report there too. This enables 14213 * the "am" command to report errors with more information. 14214 * 14215 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14216 * @param cn The component name of the instrumentation. 14217 * @param report The error report. 14218 */ 14219 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14220 ComponentName cn, String report) { 14221 Slog.w(TAG, report); 14222 try { 14223 if (watcher != null) { 14224 Bundle results = new Bundle(); 14225 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14226 results.putString("Error", report); 14227 watcher.instrumentationStatus(cn, -1, results); 14228 } 14229 } catch (RemoteException e) { 14230 Slog.w(TAG, e); 14231 } 14232 } 14233 14234 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14235 if (app.instrumentationWatcher != null) { 14236 try { 14237 // NOTE: IInstrumentationWatcher *must* be oneway here 14238 app.instrumentationWatcher.instrumentationFinished( 14239 app.instrumentationClass, 14240 resultCode, 14241 results); 14242 } catch (RemoteException e) { 14243 } 14244 } 14245 if (app.instrumentationUiAutomationConnection != null) { 14246 try { 14247 app.instrumentationUiAutomationConnection.shutdown(); 14248 } catch (RemoteException re) { 14249 /* ignore */ 14250 } 14251 // Only a UiAutomation can set this flag and now that 14252 // it is finished we make sure it is reset to its default. 14253 mUserIsMonkey = false; 14254 } 14255 app.instrumentationWatcher = null; 14256 app.instrumentationUiAutomationConnection = null; 14257 app.instrumentationClass = null; 14258 app.instrumentationInfo = null; 14259 app.instrumentationProfileFile = null; 14260 app.instrumentationArguments = null; 14261 14262 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14263 "finished inst"); 14264 } 14265 14266 public void finishInstrumentation(IApplicationThread target, 14267 int resultCode, Bundle results) { 14268 int userId = UserHandle.getCallingUserId(); 14269 // Refuse possible leaked file descriptors 14270 if (results != null && results.hasFileDescriptors()) { 14271 throw new IllegalArgumentException("File descriptors passed in Intent"); 14272 } 14273 14274 synchronized(this) { 14275 ProcessRecord app = getRecordForAppLocked(target); 14276 if (app == null) { 14277 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14278 return; 14279 } 14280 final long origId = Binder.clearCallingIdentity(); 14281 finishInstrumentationLocked(app, resultCode, results); 14282 Binder.restoreCallingIdentity(origId); 14283 } 14284 } 14285 14286 // ========================================================= 14287 // CONFIGURATION 14288 // ========================================================= 14289 14290 public ConfigurationInfo getDeviceConfigurationInfo() { 14291 ConfigurationInfo config = new ConfigurationInfo(); 14292 synchronized (this) { 14293 config.reqTouchScreen = mConfiguration.touchscreen; 14294 config.reqKeyboardType = mConfiguration.keyboard; 14295 config.reqNavigation = mConfiguration.navigation; 14296 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14297 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14298 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14299 } 14300 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14301 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14302 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14303 } 14304 config.reqGlEsVersion = GL_ES_VERSION; 14305 } 14306 return config; 14307 } 14308 14309 ActivityStack getFocusedStack() { 14310 return mStackSupervisor.getFocusedStack(); 14311 } 14312 14313 public Configuration getConfiguration() { 14314 Configuration ci; 14315 synchronized(this) { 14316 ci = new Configuration(mConfiguration); 14317 } 14318 return ci; 14319 } 14320 14321 public void updatePersistentConfiguration(Configuration values) { 14322 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14323 "updateConfiguration()"); 14324 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14325 "updateConfiguration()"); 14326 if (values == null) { 14327 throw new NullPointerException("Configuration must not be null"); 14328 } 14329 14330 synchronized(this) { 14331 final long origId = Binder.clearCallingIdentity(); 14332 updateConfigurationLocked(values, null, true, false); 14333 Binder.restoreCallingIdentity(origId); 14334 } 14335 } 14336 14337 public void updateConfiguration(Configuration values) { 14338 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14339 "updateConfiguration()"); 14340 14341 synchronized(this) { 14342 if (values == null && mWindowManager != null) { 14343 // sentinel: fetch the current configuration from the window manager 14344 values = mWindowManager.computeNewConfiguration(); 14345 } 14346 14347 if (mWindowManager != null) { 14348 mProcessList.applyDisplaySize(mWindowManager); 14349 } 14350 14351 final long origId = Binder.clearCallingIdentity(); 14352 if (values != null) { 14353 Settings.System.clearConfiguration(values); 14354 } 14355 updateConfigurationLocked(values, null, false, false); 14356 Binder.restoreCallingIdentity(origId); 14357 } 14358 } 14359 14360 /** 14361 * Do either or both things: (1) change the current configuration, and (2) 14362 * make sure the given activity is running with the (now) current 14363 * configuration. Returns true if the activity has been left running, or 14364 * false if <var>starting</var> is being destroyed to match the new 14365 * configuration. 14366 * @param persistent TODO 14367 */ 14368 boolean updateConfigurationLocked(Configuration values, 14369 ActivityRecord starting, boolean persistent, boolean initLocale) { 14370 int changes = 0; 14371 14372 if (values != null) { 14373 Configuration newConfig = new Configuration(mConfiguration); 14374 changes = newConfig.updateFrom(values); 14375 if (changes != 0) { 14376 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14377 Slog.i(TAG, "Updating configuration to: " + values); 14378 } 14379 14380 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14381 14382 if (values.locale != null && !initLocale) { 14383 saveLocaleLocked(values.locale, 14384 !values.locale.equals(mConfiguration.locale), 14385 values.userSetLocale); 14386 } 14387 14388 mConfigurationSeq++; 14389 if (mConfigurationSeq <= 0) { 14390 mConfigurationSeq = 1; 14391 } 14392 newConfig.seq = mConfigurationSeq; 14393 mConfiguration = newConfig; 14394 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14395 mUsageStatsService.noteStartConfig(newConfig); 14396 14397 final Configuration configCopy = new Configuration(mConfiguration); 14398 14399 // TODO: If our config changes, should we auto dismiss any currently 14400 // showing dialogs? 14401 mShowDialogs = shouldShowDialogs(newConfig); 14402 14403 AttributeCache ac = AttributeCache.instance(); 14404 if (ac != null) { 14405 ac.updateConfiguration(configCopy); 14406 } 14407 14408 // Make sure all resources in our process are updated 14409 // right now, so that anyone who is going to retrieve 14410 // resource values after we return will be sure to get 14411 // the new ones. This is especially important during 14412 // boot, where the first config change needs to guarantee 14413 // all resources have that config before following boot 14414 // code is executed. 14415 mSystemThread.applyConfigurationToResources(configCopy); 14416 14417 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14418 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14419 msg.obj = new Configuration(configCopy); 14420 mHandler.sendMessage(msg); 14421 } 14422 14423 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14424 ProcessRecord app = mLruProcesses.get(i); 14425 try { 14426 if (app.thread != null) { 14427 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14428 + app.processName + " new config " + mConfiguration); 14429 app.thread.scheduleConfigurationChanged(configCopy); 14430 } 14431 } catch (Exception e) { 14432 } 14433 } 14434 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14435 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14436 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14437 | Intent.FLAG_RECEIVER_FOREGROUND); 14438 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14439 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14440 Process.SYSTEM_UID, UserHandle.USER_ALL); 14441 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14442 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14443 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14444 broadcastIntentLocked(null, null, intent, 14445 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14446 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14447 } 14448 } 14449 } 14450 14451 boolean kept = true; 14452 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14453 // mainStack is null during startup. 14454 if (mainStack != null) { 14455 if (changes != 0 && starting == null) { 14456 // If the configuration changed, and the caller is not already 14457 // in the process of starting an activity, then find the top 14458 // activity to check if its configuration needs to change. 14459 starting = mainStack.topRunningActivityLocked(null); 14460 } 14461 14462 if (starting != null) { 14463 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14464 // And we need to make sure at this point that all other activities 14465 // are made visible with the correct configuration. 14466 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14467 } 14468 } 14469 14470 if (values != null && mWindowManager != null) { 14471 mWindowManager.setNewConfiguration(mConfiguration); 14472 } 14473 14474 return kept; 14475 } 14476 14477 /** 14478 * Decide based on the configuration whether we should shouw the ANR, 14479 * crash, etc dialogs. The idea is that if there is no affordnace to 14480 * press the on-screen buttons, we shouldn't show the dialog. 14481 * 14482 * A thought: SystemUI might also want to get told about this, the Power 14483 * dialog / global actions also might want different behaviors. 14484 */ 14485 private static final boolean shouldShowDialogs(Configuration config) { 14486 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14487 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14488 } 14489 14490 /** 14491 * Save the locale. You must be inside a synchronized (this) block. 14492 */ 14493 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14494 if(isDiff) { 14495 SystemProperties.set("user.language", l.getLanguage()); 14496 SystemProperties.set("user.region", l.getCountry()); 14497 } 14498 14499 if(isPersist) { 14500 SystemProperties.set("persist.sys.language", l.getLanguage()); 14501 SystemProperties.set("persist.sys.country", l.getCountry()); 14502 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14503 } 14504 } 14505 14506 @Override 14507 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14508 ActivityRecord srec = ActivityRecord.forToken(token); 14509 return srec != null && srec.task.affinity != null && 14510 srec.task.affinity.equals(destAffinity); 14511 } 14512 14513 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14514 Intent resultData) { 14515 14516 synchronized (this) { 14517 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14518 if (stack != null) { 14519 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14520 } 14521 return false; 14522 } 14523 } 14524 14525 public int getLaunchedFromUid(IBinder activityToken) { 14526 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14527 if (srec == null) { 14528 return -1; 14529 } 14530 return srec.launchedFromUid; 14531 } 14532 14533 public String getLaunchedFromPackage(IBinder activityToken) { 14534 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14535 if (srec == null) { 14536 return null; 14537 } 14538 return srec.launchedFromPackage; 14539 } 14540 14541 // ========================================================= 14542 // LIFETIME MANAGEMENT 14543 // ========================================================= 14544 14545 // Returns which broadcast queue the app is the current [or imminent] receiver 14546 // on, or 'null' if the app is not an active broadcast recipient. 14547 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14548 BroadcastRecord r = app.curReceiver; 14549 if (r != null) { 14550 return r.queue; 14551 } 14552 14553 // It's not the current receiver, but it might be starting up to become one 14554 synchronized (this) { 14555 for (BroadcastQueue queue : mBroadcastQueues) { 14556 r = queue.mPendingBroadcast; 14557 if (r != null && r.curApp == app) { 14558 // found it; report which queue it's in 14559 return queue; 14560 } 14561 } 14562 } 14563 14564 return null; 14565 } 14566 14567 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14568 boolean doingAll, long now) { 14569 if (mAdjSeq == app.adjSeq) { 14570 // This adjustment has already been computed. 14571 return app.curRawAdj; 14572 } 14573 14574 if (app.thread == null) { 14575 app.adjSeq = mAdjSeq; 14576 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14577 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14578 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14579 } 14580 14581 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14582 app.adjSource = null; 14583 app.adjTarget = null; 14584 app.empty = false; 14585 app.cached = false; 14586 14587 final int activitiesSize = app.activities.size(); 14588 14589 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14590 // The max adjustment doesn't allow this app to be anything 14591 // below foreground, so it is not worth doing work for it. 14592 app.adjType = "fixed"; 14593 app.adjSeq = mAdjSeq; 14594 app.curRawAdj = app.maxAdj; 14595 app.foregroundActivities = false; 14596 app.keeping = true; 14597 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14598 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14599 // System processes can do UI, and when they do we want to have 14600 // them trim their memory after the user leaves the UI. To 14601 // facilitate this, here we need to determine whether or not it 14602 // is currently showing UI. 14603 app.systemNoUi = true; 14604 if (app == TOP_APP) { 14605 app.systemNoUi = false; 14606 } else if (activitiesSize > 0) { 14607 for (int j = 0; j < activitiesSize; j++) { 14608 final ActivityRecord r = app.activities.get(j); 14609 if (r.visible) { 14610 app.systemNoUi = false; 14611 } 14612 } 14613 } 14614 if (!app.systemNoUi) { 14615 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14616 } 14617 return (app.curAdj=app.maxAdj); 14618 } 14619 14620 app.keeping = false; 14621 app.systemNoUi = false; 14622 14623 // Determine the importance of the process, starting with most 14624 // important to least, and assign an appropriate OOM adjustment. 14625 int adj; 14626 int schedGroup; 14627 int procState; 14628 boolean foregroundActivities = false; 14629 boolean interesting = false; 14630 BroadcastQueue queue; 14631 if (app == TOP_APP) { 14632 // The last app on the list is the foreground app. 14633 adj = ProcessList.FOREGROUND_APP_ADJ; 14634 schedGroup = Process.THREAD_GROUP_DEFAULT; 14635 app.adjType = "top-activity"; 14636 foregroundActivities = true; 14637 interesting = true; 14638 procState = ActivityManager.PROCESS_STATE_TOP; 14639 } else if (app.instrumentationClass != null) { 14640 // Don't want to kill running instrumentation. 14641 adj = ProcessList.FOREGROUND_APP_ADJ; 14642 schedGroup = Process.THREAD_GROUP_DEFAULT; 14643 app.adjType = "instrumentation"; 14644 interesting = true; 14645 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14646 } else if ((queue = isReceivingBroadcast(app)) != null) { 14647 // An app that is currently receiving a broadcast also 14648 // counts as being in the foreground for OOM killer purposes. 14649 // It's placed in a sched group based on the nature of the 14650 // broadcast as reflected by which queue it's active in. 14651 adj = ProcessList.FOREGROUND_APP_ADJ; 14652 schedGroup = (queue == mFgBroadcastQueue) 14653 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14654 app.adjType = "broadcast"; 14655 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14656 } else if (app.executingServices.size() > 0) { 14657 // An app that is currently executing a service callback also 14658 // counts as being in the foreground. 14659 adj = ProcessList.FOREGROUND_APP_ADJ; 14660 schedGroup = app.execServicesFg ? 14661 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14662 app.adjType = "exec-service"; 14663 procState = ActivityManager.PROCESS_STATE_SERVICE; 14664 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14665 } else { 14666 // As far as we know the process is empty. We may change our mind later. 14667 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14668 // At this point we don't actually know the adjustment. Use the cached adj 14669 // value that the caller wants us to. 14670 adj = cachedAdj; 14671 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14672 app.cached = true; 14673 app.empty = true; 14674 app.adjType = "cch-empty"; 14675 } 14676 14677 // Examine all activities if not already foreground. 14678 if (!foregroundActivities && activitiesSize > 0) { 14679 for (int j = 0; j < activitiesSize; j++) { 14680 final ActivityRecord r = app.activities.get(j); 14681 if (r.app != app) { 14682 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14683 + app + "?!?"); 14684 continue; 14685 } 14686 if (r.visible) { 14687 // App has a visible activity; only upgrade adjustment. 14688 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14689 adj = ProcessList.VISIBLE_APP_ADJ; 14690 app.adjType = "visible"; 14691 } 14692 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14693 procState = ActivityManager.PROCESS_STATE_TOP; 14694 } 14695 schedGroup = Process.THREAD_GROUP_DEFAULT; 14696 app.cached = false; 14697 app.empty = false; 14698 foregroundActivities = true; 14699 break; 14700 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14701 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14702 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14703 app.adjType = "pausing"; 14704 } 14705 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14706 procState = ActivityManager.PROCESS_STATE_TOP; 14707 } 14708 schedGroup = Process.THREAD_GROUP_DEFAULT; 14709 app.cached = false; 14710 app.empty = false; 14711 foregroundActivities = true; 14712 } else if (r.state == ActivityState.STOPPING) { 14713 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14714 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14715 app.adjType = "stopping"; 14716 } 14717 // For the process state, we will at this point consider the 14718 // process to be cached. It will be cached either as an activity 14719 // or empty depending on whether the activity is finishing. We do 14720 // this so that we can treat the process as cached for purposes of 14721 // memory trimming (determing current memory level, trim command to 14722 // send to process) since there can be an arbitrary number of stopping 14723 // processes and they should soon all go into the cached state. 14724 if (!r.finishing) { 14725 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14726 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14727 } 14728 } 14729 app.cached = false; 14730 app.empty = false; 14731 foregroundActivities = true; 14732 } else { 14733 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14734 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14735 app.adjType = "cch-act"; 14736 } 14737 } 14738 } 14739 } 14740 14741 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14742 if (app.foregroundServices) { 14743 // The user is aware of this app, so make it visible. 14744 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14745 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14746 app.cached = false; 14747 app.adjType = "fg-service"; 14748 schedGroup = Process.THREAD_GROUP_DEFAULT; 14749 } else if (app.forcingToForeground != null) { 14750 // The user is aware of this app, so make it visible. 14751 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14752 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14753 app.cached = false; 14754 app.adjType = "force-fg"; 14755 app.adjSource = app.forcingToForeground; 14756 schedGroup = Process.THREAD_GROUP_DEFAULT; 14757 } 14758 } 14759 14760 if (app.foregroundServices) { 14761 interesting = true; 14762 } 14763 14764 if (app == mHeavyWeightProcess) { 14765 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14766 // We don't want to kill the current heavy-weight process. 14767 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14768 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14769 app.cached = false; 14770 app.adjType = "heavy"; 14771 } 14772 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14773 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14774 } 14775 } 14776 14777 if (app == mHomeProcess) { 14778 if (adj > ProcessList.HOME_APP_ADJ) { 14779 // This process is hosting what we currently consider to be the 14780 // home app, so we don't want to let it go into the background. 14781 adj = ProcessList.HOME_APP_ADJ; 14782 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14783 app.cached = false; 14784 app.adjType = "home"; 14785 } 14786 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14787 procState = ActivityManager.PROCESS_STATE_HOME; 14788 } 14789 } 14790 14791 if (app == mPreviousProcess && app.activities.size() > 0) { 14792 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14793 // This was the previous process that showed UI to the user. 14794 // We want to try to keep it around more aggressively, to give 14795 // a good experience around switching between two apps. 14796 adj = ProcessList.PREVIOUS_APP_ADJ; 14797 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14798 app.cached = false; 14799 app.adjType = "previous"; 14800 } 14801 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14802 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14803 } 14804 } 14805 14806 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14807 + " reason=" + app.adjType); 14808 14809 // By default, we use the computed adjustment. It may be changed if 14810 // there are applications dependent on our services or providers, but 14811 // this gives us a baseline and makes sure we don't get into an 14812 // infinite recursion. 14813 app.adjSeq = mAdjSeq; 14814 app.curRawAdj = adj; 14815 app.hasStartedServices = false; 14816 14817 if (mBackupTarget != null && app == mBackupTarget.app) { 14818 // If possible we want to avoid killing apps while they're being backed up 14819 if (adj > ProcessList.BACKUP_APP_ADJ) { 14820 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14821 adj = ProcessList.BACKUP_APP_ADJ; 14822 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14823 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14824 } 14825 app.adjType = "backup"; 14826 app.cached = false; 14827 } 14828 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14829 procState = ActivityManager.PROCESS_STATE_BACKUP; 14830 } 14831 } 14832 14833 boolean mayBeTop = false; 14834 14835 for (int is = app.services.size()-1; 14836 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14837 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14838 || procState > ActivityManager.PROCESS_STATE_TOP); 14839 is--) { 14840 ServiceRecord s = app.services.valueAt(is); 14841 if (s.startRequested) { 14842 app.hasStartedServices = true; 14843 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14844 procState = ActivityManager.PROCESS_STATE_SERVICE; 14845 } 14846 if (app.hasShownUi && app != mHomeProcess) { 14847 // If this process has shown some UI, let it immediately 14848 // go to the LRU list because it may be pretty heavy with 14849 // UI stuff. We'll tag it with a label just to help 14850 // debug and understand what is going on. 14851 if (adj > ProcessList.SERVICE_ADJ) { 14852 app.adjType = "cch-started-ui-services"; 14853 } 14854 } else { 14855 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14856 // This service has seen some activity within 14857 // recent memory, so we will keep its process ahead 14858 // of the background processes. 14859 if (adj > ProcessList.SERVICE_ADJ) { 14860 adj = ProcessList.SERVICE_ADJ; 14861 app.adjType = "started-services"; 14862 app.cached = false; 14863 } 14864 } 14865 // If we have let the service slide into the background 14866 // state, still have some text describing what it is doing 14867 // even though the service no longer has an impact. 14868 if (adj > ProcessList.SERVICE_ADJ) { 14869 app.adjType = "cch-started-services"; 14870 } 14871 } 14872 // Don't kill this process because it is doing work; it 14873 // has said it is doing work. 14874 app.keeping = true; 14875 } 14876 for (int conni = s.connections.size()-1; 14877 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14878 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14879 || procState > ActivityManager.PROCESS_STATE_TOP); 14880 conni--) { 14881 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14882 for (int i = 0; 14883 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14884 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14885 || procState > ActivityManager.PROCESS_STATE_TOP); 14886 i++) { 14887 // XXX should compute this based on the max of 14888 // all connected clients. 14889 ConnectionRecord cr = clist.get(i); 14890 if (cr.binding.client == app) { 14891 // Binding to ourself is not interesting. 14892 continue; 14893 } 14894 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14895 ProcessRecord client = cr.binding.client; 14896 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14897 TOP_APP, doingAll, now); 14898 int clientProcState = client.curProcState; 14899 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14900 // If the other app is cached for any reason, for purposes here 14901 // we are going to consider it empty. The specific cached state 14902 // doesn't propagate except under certain conditions. 14903 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14904 } 14905 String adjType = null; 14906 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14907 // Not doing bind OOM management, so treat 14908 // this guy more like a started service. 14909 if (app.hasShownUi && app != mHomeProcess) { 14910 // If this process has shown some UI, let it immediately 14911 // go to the LRU list because it may be pretty heavy with 14912 // UI stuff. We'll tag it with a label just to help 14913 // debug and understand what is going on. 14914 if (adj > clientAdj) { 14915 adjType = "cch-bound-ui-services"; 14916 } 14917 app.cached = false; 14918 clientAdj = adj; 14919 clientProcState = procState; 14920 } else { 14921 if (now >= (s.lastActivity 14922 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14923 // This service has not seen activity within 14924 // recent memory, so allow it to drop to the 14925 // LRU list if there is no other reason to keep 14926 // it around. We'll also tag it with a label just 14927 // to help debug and undertand what is going on. 14928 if (adj > clientAdj) { 14929 adjType = "cch-bound-services"; 14930 } 14931 clientAdj = adj; 14932 } 14933 } 14934 } 14935 if (adj > clientAdj) { 14936 // If this process has recently shown UI, and 14937 // the process that is binding to it is less 14938 // important than being visible, then we don't 14939 // care about the binding as much as we care 14940 // about letting this process get into the LRU 14941 // list to be killed and restarted if needed for 14942 // memory. 14943 if (app.hasShownUi && app != mHomeProcess 14944 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14945 adjType = "cch-bound-ui-services"; 14946 } else { 14947 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14948 |Context.BIND_IMPORTANT)) != 0) { 14949 adj = clientAdj; 14950 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14951 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14952 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14953 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14954 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14955 adj = clientAdj; 14956 } else { 14957 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14958 adj = ProcessList.VISIBLE_APP_ADJ; 14959 } 14960 } 14961 if (!client.cached) { 14962 app.cached = false; 14963 } 14964 if (client.keeping) { 14965 app.keeping = true; 14966 } 14967 adjType = "service"; 14968 } 14969 } 14970 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14971 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14972 schedGroup = Process.THREAD_GROUP_DEFAULT; 14973 } 14974 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14975 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14976 // Special handling of clients who are in the top state. 14977 // We *may* want to consider this process to be in the 14978 // top state as well, but only if there is not another 14979 // reason for it to be running. Being on the top is a 14980 // special state, meaning you are specifically running 14981 // for the current top app. If the process is already 14982 // running in the background for some other reason, it 14983 // is more important to continue considering it to be 14984 // in the background state. 14985 mayBeTop = true; 14986 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14987 } else { 14988 // Special handling for above-top states (persistent 14989 // processes). These should not bring the current process 14990 // into the top state, since they are not on top. Instead 14991 // give them the best state after that. 14992 clientProcState = 14993 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14994 } 14995 } 14996 } else { 14997 if (clientProcState < 14998 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14999 clientProcState = 15000 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15001 } 15002 } 15003 if (procState > clientProcState) { 15004 procState = clientProcState; 15005 } 15006 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15007 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15008 app.pendingUiClean = true; 15009 } 15010 if (adjType != null) { 15011 app.adjType = adjType; 15012 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15013 .REASON_SERVICE_IN_USE; 15014 app.adjSource = cr.binding.client; 15015 app.adjSourceOom = clientAdj; 15016 app.adjTarget = s.name; 15017 } 15018 } 15019 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15020 app.treatLikeActivity = true; 15021 } 15022 final ActivityRecord a = cr.activity; 15023 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15024 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15025 (a.visible || a.state == ActivityState.RESUMED 15026 || a.state == ActivityState.PAUSING)) { 15027 adj = ProcessList.FOREGROUND_APP_ADJ; 15028 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15029 schedGroup = Process.THREAD_GROUP_DEFAULT; 15030 } 15031 app.cached = false; 15032 app.adjType = "service"; 15033 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15034 .REASON_SERVICE_IN_USE; 15035 app.adjSource = a; 15036 app.adjSourceOom = adj; 15037 app.adjTarget = s.name; 15038 } 15039 } 15040 } 15041 } 15042 } 15043 15044 for (int provi = app.pubProviders.size()-1; 15045 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15046 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15047 || procState > ActivityManager.PROCESS_STATE_TOP); 15048 provi--) { 15049 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15050 for (int i = cpr.connections.size()-1; 15051 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15052 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15053 || procState > ActivityManager.PROCESS_STATE_TOP); 15054 i--) { 15055 ContentProviderConnection conn = cpr.connections.get(i); 15056 ProcessRecord client = conn.client; 15057 if (client == app) { 15058 // Being our own client is not interesting. 15059 continue; 15060 } 15061 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15062 int clientProcState = client.curProcState; 15063 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15064 // If the other app is cached for any reason, for purposes here 15065 // we are going to consider it empty. 15066 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15067 } 15068 if (adj > clientAdj) { 15069 if (app.hasShownUi && app != mHomeProcess 15070 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15071 app.adjType = "cch-ui-provider"; 15072 } else { 15073 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15074 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15075 app.adjType = "provider"; 15076 } 15077 app.cached &= client.cached; 15078 app.keeping |= client.keeping; 15079 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15080 .REASON_PROVIDER_IN_USE; 15081 app.adjSource = client; 15082 app.adjSourceOom = clientAdj; 15083 app.adjTarget = cpr.name; 15084 } 15085 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15086 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15087 // Special handling of clients who are in the top state. 15088 // We *may* want to consider this process to be in the 15089 // top state as well, but only if there is not another 15090 // reason for it to be running. Being on the top is a 15091 // special state, meaning you are specifically running 15092 // for the current top app. If the process is already 15093 // running in the background for some other reason, it 15094 // is more important to continue considering it to be 15095 // in the background state. 15096 mayBeTop = true; 15097 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15098 } else { 15099 // Special handling for above-top states (persistent 15100 // processes). These should not bring the current process 15101 // into the top state, since they are not on top. Instead 15102 // give them the best state after that. 15103 clientProcState = 15104 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15105 } 15106 } 15107 if (procState > clientProcState) { 15108 procState = clientProcState; 15109 } 15110 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15111 schedGroup = Process.THREAD_GROUP_DEFAULT; 15112 } 15113 } 15114 // If the provider has external (non-framework) process 15115 // dependencies, ensure that its adjustment is at least 15116 // FOREGROUND_APP_ADJ. 15117 if (cpr.hasExternalProcessHandles()) { 15118 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15119 adj = ProcessList.FOREGROUND_APP_ADJ; 15120 schedGroup = Process.THREAD_GROUP_DEFAULT; 15121 app.cached = false; 15122 app.keeping = true; 15123 app.adjType = "provider"; 15124 app.adjTarget = cpr.name; 15125 } 15126 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15127 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15128 } 15129 } 15130 } 15131 15132 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15133 // A client of one of our services or providers is in the top state. We 15134 // *may* want to be in the top state, but not if we are already running in 15135 // the background for some other reason. For the decision here, we are going 15136 // to pick out a few specific states that we want to remain in when a client 15137 // is top (states that tend to be longer-term) and otherwise allow it to go 15138 // to the top state. 15139 switch (procState) { 15140 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15141 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15142 case ActivityManager.PROCESS_STATE_SERVICE: 15143 // These all are longer-term states, so pull them up to the top 15144 // of the background states, but not all the way to the top state. 15145 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15146 break; 15147 default: 15148 // Otherwise, top is a better choice, so take it. 15149 procState = ActivityManager.PROCESS_STATE_TOP; 15150 break; 15151 } 15152 } 15153 15154 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15155 if (app.hasClientActivities) { 15156 // This is a cached process, but with client activities. Mark it so. 15157 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15158 app.adjType = "cch-client-act"; 15159 } else if (app.treatLikeActivity) { 15160 // This is a cached process, but somebody wants us to treat it like it has 15161 // an activity, okay! 15162 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15163 app.adjType = "cch-as-act"; 15164 } 15165 } 15166 15167 if (adj == ProcessList.SERVICE_ADJ) { 15168 if (doingAll) { 15169 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15170 mNewNumServiceProcs++; 15171 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15172 if (!app.serviceb) { 15173 // This service isn't far enough down on the LRU list to 15174 // normally be a B service, but if we are low on RAM and it 15175 // is large we want to force it down since we would prefer to 15176 // keep launcher over it. 15177 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15178 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15179 app.serviceHighRam = true; 15180 app.serviceb = true; 15181 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15182 } else { 15183 mNewNumAServiceProcs++; 15184 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15185 } 15186 } else { 15187 app.serviceHighRam = false; 15188 } 15189 } 15190 if (app.serviceb) { 15191 adj = ProcessList.SERVICE_B_ADJ; 15192 } 15193 } 15194 15195 app.curRawAdj = adj; 15196 15197 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15198 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15199 if (adj > app.maxAdj) { 15200 adj = app.maxAdj; 15201 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15202 schedGroup = Process.THREAD_GROUP_DEFAULT; 15203 } 15204 } 15205 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15206 app.keeping = true; 15207 } 15208 15209 // Do final modification to adj. Everything we do between here and applying 15210 // the final setAdj must be done in this function, because we will also use 15211 // it when computing the final cached adj later. Note that we don't need to 15212 // worry about this for max adj above, since max adj will always be used to 15213 // keep it out of the cached vaues. 15214 app.curAdj = app.modifyRawOomAdj(adj); 15215 app.curSchedGroup = schedGroup; 15216 app.curProcState = procState; 15217 app.foregroundActivities = foregroundActivities; 15218 15219 return app.curRawAdj; 15220 } 15221 15222 /** 15223 * Schedule PSS collection of a process. 15224 */ 15225 void requestPssLocked(ProcessRecord proc, int procState) { 15226 if (mPendingPssProcesses.contains(proc)) { 15227 return; 15228 } 15229 if (mPendingPssProcesses.size() == 0) { 15230 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15231 } 15232 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15233 proc.pssProcState = procState; 15234 mPendingPssProcesses.add(proc); 15235 } 15236 15237 /** 15238 * Schedule PSS collection of all processes. 15239 */ 15240 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15241 if (!always) { 15242 if (now < (mLastFullPssTime + 15243 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15244 return; 15245 } 15246 } 15247 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15248 mLastFullPssTime = now; 15249 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15250 mPendingPssProcesses.clear(); 15251 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15252 ProcessRecord app = mLruProcesses.get(i); 15253 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15254 app.pssProcState = app.setProcState; 15255 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15256 isSleeping(), now); 15257 mPendingPssProcesses.add(app); 15258 } 15259 } 15260 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15261 } 15262 15263 /** 15264 * Ask a given process to GC right now. 15265 */ 15266 final void performAppGcLocked(ProcessRecord app) { 15267 try { 15268 app.lastRequestedGc = SystemClock.uptimeMillis(); 15269 if (app.thread != null) { 15270 if (app.reportLowMemory) { 15271 app.reportLowMemory = false; 15272 app.thread.scheduleLowMemory(); 15273 } else { 15274 app.thread.processInBackground(); 15275 } 15276 } 15277 } catch (Exception e) { 15278 // whatever. 15279 } 15280 } 15281 15282 /** 15283 * Returns true if things are idle enough to perform GCs. 15284 */ 15285 private final boolean canGcNowLocked() { 15286 boolean processingBroadcasts = false; 15287 for (BroadcastQueue q : mBroadcastQueues) { 15288 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15289 processingBroadcasts = true; 15290 } 15291 } 15292 return !processingBroadcasts 15293 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15294 } 15295 15296 /** 15297 * Perform GCs on all processes that are waiting for it, but only 15298 * if things are idle. 15299 */ 15300 final void performAppGcsLocked() { 15301 final int N = mProcessesToGc.size(); 15302 if (N <= 0) { 15303 return; 15304 } 15305 if (canGcNowLocked()) { 15306 while (mProcessesToGc.size() > 0) { 15307 ProcessRecord proc = mProcessesToGc.remove(0); 15308 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15309 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15310 <= SystemClock.uptimeMillis()) { 15311 // To avoid spamming the system, we will GC processes one 15312 // at a time, waiting a few seconds between each. 15313 performAppGcLocked(proc); 15314 scheduleAppGcsLocked(); 15315 return; 15316 } else { 15317 // It hasn't been long enough since we last GCed this 15318 // process... put it in the list to wait for its time. 15319 addProcessToGcListLocked(proc); 15320 break; 15321 } 15322 } 15323 } 15324 15325 scheduleAppGcsLocked(); 15326 } 15327 } 15328 15329 /** 15330 * If all looks good, perform GCs on all processes waiting for them. 15331 */ 15332 final void performAppGcsIfAppropriateLocked() { 15333 if (canGcNowLocked()) { 15334 performAppGcsLocked(); 15335 return; 15336 } 15337 // Still not idle, wait some more. 15338 scheduleAppGcsLocked(); 15339 } 15340 15341 /** 15342 * Schedule the execution of all pending app GCs. 15343 */ 15344 final void scheduleAppGcsLocked() { 15345 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15346 15347 if (mProcessesToGc.size() > 0) { 15348 // Schedule a GC for the time to the next process. 15349 ProcessRecord proc = mProcessesToGc.get(0); 15350 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15351 15352 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15353 long now = SystemClock.uptimeMillis(); 15354 if (when < (now+GC_TIMEOUT)) { 15355 when = now + GC_TIMEOUT; 15356 } 15357 mHandler.sendMessageAtTime(msg, when); 15358 } 15359 } 15360 15361 /** 15362 * Add a process to the array of processes waiting to be GCed. Keeps the 15363 * list in sorted order by the last GC time. The process can't already be 15364 * on the list. 15365 */ 15366 final void addProcessToGcListLocked(ProcessRecord proc) { 15367 boolean added = false; 15368 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15369 if (mProcessesToGc.get(i).lastRequestedGc < 15370 proc.lastRequestedGc) { 15371 added = true; 15372 mProcessesToGc.add(i+1, proc); 15373 break; 15374 } 15375 } 15376 if (!added) { 15377 mProcessesToGc.add(0, proc); 15378 } 15379 } 15380 15381 /** 15382 * Set up to ask a process to GC itself. This will either do it 15383 * immediately, or put it on the list of processes to gc the next 15384 * time things are idle. 15385 */ 15386 final void scheduleAppGcLocked(ProcessRecord app) { 15387 long now = SystemClock.uptimeMillis(); 15388 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15389 return; 15390 } 15391 if (!mProcessesToGc.contains(app)) { 15392 addProcessToGcListLocked(app); 15393 scheduleAppGcsLocked(); 15394 } 15395 } 15396 15397 final void checkExcessivePowerUsageLocked(boolean doKills) { 15398 updateCpuStatsNow(); 15399 15400 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15401 boolean doWakeKills = doKills; 15402 boolean doCpuKills = doKills; 15403 if (mLastPowerCheckRealtime == 0) { 15404 doWakeKills = false; 15405 } 15406 if (mLastPowerCheckUptime == 0) { 15407 doCpuKills = false; 15408 } 15409 if (stats.isScreenOn()) { 15410 doWakeKills = false; 15411 } 15412 final long curRealtime = SystemClock.elapsedRealtime(); 15413 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15414 final long curUptime = SystemClock.uptimeMillis(); 15415 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15416 mLastPowerCheckRealtime = curRealtime; 15417 mLastPowerCheckUptime = curUptime; 15418 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15419 doWakeKills = false; 15420 } 15421 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15422 doCpuKills = false; 15423 } 15424 int i = mLruProcesses.size(); 15425 while (i > 0) { 15426 i--; 15427 ProcessRecord app = mLruProcesses.get(i); 15428 if (!app.keeping) { 15429 long wtime; 15430 synchronized (stats) { 15431 wtime = stats.getProcessWakeTime(app.info.uid, 15432 app.pid, curRealtime); 15433 } 15434 long wtimeUsed = wtime - app.lastWakeTime; 15435 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15436 if (DEBUG_POWER) { 15437 StringBuilder sb = new StringBuilder(128); 15438 sb.append("Wake for "); 15439 app.toShortString(sb); 15440 sb.append(": over "); 15441 TimeUtils.formatDuration(realtimeSince, sb); 15442 sb.append(" used "); 15443 TimeUtils.formatDuration(wtimeUsed, sb); 15444 sb.append(" ("); 15445 sb.append((wtimeUsed*100)/realtimeSince); 15446 sb.append("%)"); 15447 Slog.i(TAG, sb.toString()); 15448 sb.setLength(0); 15449 sb.append("CPU for "); 15450 app.toShortString(sb); 15451 sb.append(": over "); 15452 TimeUtils.formatDuration(uptimeSince, sb); 15453 sb.append(" used "); 15454 TimeUtils.formatDuration(cputimeUsed, sb); 15455 sb.append(" ("); 15456 sb.append((cputimeUsed*100)/uptimeSince); 15457 sb.append("%)"); 15458 Slog.i(TAG, sb.toString()); 15459 } 15460 // If a process has held a wake lock for more 15461 // than 50% of the time during this period, 15462 // that sounds bad. Kill! 15463 if (doWakeKills && realtimeSince > 0 15464 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15465 synchronized (stats) { 15466 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15467 realtimeSince, wtimeUsed); 15468 } 15469 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15470 + " during " + realtimeSince); 15471 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15472 } else if (doCpuKills && uptimeSince > 0 15473 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15474 synchronized (stats) { 15475 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15476 uptimeSince, cputimeUsed); 15477 } 15478 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15479 + " during " + uptimeSince); 15480 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15481 } else { 15482 app.lastWakeTime = wtime; 15483 app.lastCpuTime = app.curCpuTime; 15484 } 15485 } 15486 } 15487 } 15488 15489 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15490 ProcessRecord TOP_APP, boolean doingAll, long now) { 15491 boolean success = true; 15492 15493 if (app.curRawAdj != app.setRawAdj) { 15494 if (wasKeeping && !app.keeping) { 15495 // This app is no longer something we want to keep. Note 15496 // its current wake lock time to later know to kill it if 15497 // it is not behaving well. 15498 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15499 synchronized (stats) { 15500 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15501 app.pid, SystemClock.elapsedRealtime()); 15502 } 15503 app.lastCpuTime = app.curCpuTime; 15504 } 15505 15506 app.setRawAdj = app.curRawAdj; 15507 } 15508 15509 int changes = 0; 15510 15511 if (app.curAdj != app.setAdj) { 15512 ProcessList.setOomAdj(app.pid, app.curAdj); 15513 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15514 TAG, "Set " + app.pid + " " + app.processName + 15515 " adj " + app.curAdj + ": " + app.adjType); 15516 app.setAdj = app.curAdj; 15517 } 15518 15519 if (app.setSchedGroup != app.curSchedGroup) { 15520 app.setSchedGroup = app.curSchedGroup; 15521 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15522 "Setting process group of " + app.processName 15523 + " to " + app.curSchedGroup); 15524 if (app.waitingToKill != null && 15525 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15526 killUnneededProcessLocked(app, app.waitingToKill); 15527 success = false; 15528 } else { 15529 if (true) { 15530 long oldId = Binder.clearCallingIdentity(); 15531 try { 15532 Process.setProcessGroup(app.pid, app.curSchedGroup); 15533 } catch (Exception e) { 15534 Slog.w(TAG, "Failed setting process group of " + app.pid 15535 + " to " + app.curSchedGroup); 15536 e.printStackTrace(); 15537 } finally { 15538 Binder.restoreCallingIdentity(oldId); 15539 } 15540 } else { 15541 if (app.thread != null) { 15542 try { 15543 app.thread.setSchedulingGroup(app.curSchedGroup); 15544 } catch (RemoteException e) { 15545 } 15546 } 15547 } 15548 Process.setSwappiness(app.pid, 15549 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15550 } 15551 } 15552 if (app.repForegroundActivities != app.foregroundActivities) { 15553 app.repForegroundActivities = app.foregroundActivities; 15554 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15555 } 15556 if (app.repProcState != app.curProcState) { 15557 app.repProcState = app.curProcState; 15558 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15559 if (app.thread != null) { 15560 try { 15561 if (false) { 15562 //RuntimeException h = new RuntimeException("here"); 15563 Slog.i(TAG, "Sending new process state " + app.repProcState 15564 + " to " + app /*, h*/); 15565 } 15566 app.thread.setProcessState(app.repProcState); 15567 } catch (RemoteException e) { 15568 } 15569 } 15570 } 15571 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15572 app.setProcState)) { 15573 app.lastStateTime = now; 15574 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15575 isSleeping(), now); 15576 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15577 + ProcessList.makeProcStateString(app.setProcState) + " to " 15578 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15579 + (app.nextPssTime-now) + ": " + app); 15580 } else { 15581 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15582 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15583 requestPssLocked(app, app.setProcState); 15584 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15585 isSleeping(), now); 15586 } else if (false && DEBUG_PSS) { 15587 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15588 } 15589 } 15590 if (app.setProcState != app.curProcState) { 15591 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15592 "Proc state change of " + app.processName 15593 + " to " + app.curProcState); 15594 app.setProcState = app.curProcState; 15595 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15596 app.notCachedSinceIdle = false; 15597 } 15598 if (!doingAll) { 15599 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15600 } else { 15601 app.procStateChanged = true; 15602 } 15603 } 15604 15605 if (changes != 0) { 15606 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15607 int i = mPendingProcessChanges.size()-1; 15608 ProcessChangeItem item = null; 15609 while (i >= 0) { 15610 item = mPendingProcessChanges.get(i); 15611 if (item.pid == app.pid) { 15612 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15613 break; 15614 } 15615 i--; 15616 } 15617 if (i < 0) { 15618 // No existing item in pending changes; need a new one. 15619 final int NA = mAvailProcessChanges.size(); 15620 if (NA > 0) { 15621 item = mAvailProcessChanges.remove(NA-1); 15622 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15623 } else { 15624 item = new ProcessChangeItem(); 15625 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15626 } 15627 item.changes = 0; 15628 item.pid = app.pid; 15629 item.uid = app.info.uid; 15630 if (mPendingProcessChanges.size() == 0) { 15631 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15632 "*** Enqueueing dispatch processes changed!"); 15633 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15634 } 15635 mPendingProcessChanges.add(item); 15636 } 15637 item.changes |= changes; 15638 item.processState = app.repProcState; 15639 item.foregroundActivities = app.repForegroundActivities; 15640 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15641 + Integer.toHexString(System.identityHashCode(item)) 15642 + " " + app.toShortString() + ": changes=" + item.changes 15643 + " procState=" + item.processState 15644 + " foreground=" + item.foregroundActivities 15645 + " type=" + app.adjType + " source=" + app.adjSource 15646 + " target=" + app.adjTarget); 15647 } 15648 15649 return success; 15650 } 15651 15652 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15653 if (proc.thread != null && proc.baseProcessTracker != null) { 15654 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15655 } 15656 } 15657 15658 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15659 ProcessRecord TOP_APP, boolean doingAll, long now) { 15660 if (app.thread == null) { 15661 return false; 15662 } 15663 15664 final boolean wasKeeping = app.keeping; 15665 15666 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15667 15668 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 15669 } 15670 15671 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15672 boolean oomAdj) { 15673 if (isForeground != proc.foregroundServices) { 15674 proc.foregroundServices = isForeground; 15675 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15676 proc.info.uid); 15677 if (isForeground) { 15678 if (curProcs == null) { 15679 curProcs = new ArrayList<ProcessRecord>(); 15680 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15681 } 15682 if (!curProcs.contains(proc)) { 15683 curProcs.add(proc); 15684 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15685 proc.info.packageName, proc.info.uid); 15686 } 15687 } else { 15688 if (curProcs != null) { 15689 if (curProcs.remove(proc)) { 15690 mBatteryStatsService.noteEvent( 15691 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15692 proc.info.packageName, proc.info.uid); 15693 if (curProcs.size() <= 0) { 15694 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15695 } 15696 } 15697 } 15698 } 15699 if (oomAdj) { 15700 updateOomAdjLocked(); 15701 } 15702 } 15703 } 15704 15705 private final ActivityRecord resumedAppLocked() { 15706 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15707 String pkg; 15708 int uid; 15709 if (act != null && !act.sleeping) { 15710 pkg = act.packageName; 15711 uid = act.info.applicationInfo.uid; 15712 } else { 15713 pkg = null; 15714 uid = -1; 15715 } 15716 // Has the UID or resumed package name changed? 15717 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15718 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15719 if (mCurResumedPackage != null) { 15720 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15721 mCurResumedPackage, mCurResumedUid); 15722 } 15723 mCurResumedPackage = pkg; 15724 mCurResumedUid = uid; 15725 if (mCurResumedPackage != null) { 15726 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15727 mCurResumedPackage, mCurResumedUid); 15728 } 15729 } 15730 return act; 15731 } 15732 15733 final boolean updateOomAdjLocked(ProcessRecord app) { 15734 final ActivityRecord TOP_ACT = resumedAppLocked(); 15735 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15736 final boolean wasCached = app.cached; 15737 15738 mAdjSeq++; 15739 15740 // This is the desired cached adjusment we want to tell it to use. 15741 // If our app is currently cached, we know it, and that is it. Otherwise, 15742 // we don't know it yet, and it needs to now be cached we will then 15743 // need to do a complete oom adj. 15744 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15745 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15746 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 15747 SystemClock.uptimeMillis()); 15748 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15749 // Changed to/from cached state, so apps after it in the LRU 15750 // list may also be changed. 15751 updateOomAdjLocked(); 15752 } 15753 return success; 15754 } 15755 15756 final void updateOomAdjLocked() { 15757 final ActivityRecord TOP_ACT = resumedAppLocked(); 15758 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15759 final long now = SystemClock.uptimeMillis(); 15760 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15761 final int N = mLruProcesses.size(); 15762 15763 if (false) { 15764 RuntimeException e = new RuntimeException(); 15765 e.fillInStackTrace(); 15766 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15767 } 15768 15769 mAdjSeq++; 15770 mNewNumServiceProcs = 0; 15771 mNewNumAServiceProcs = 0; 15772 15773 final int emptyProcessLimit; 15774 final int cachedProcessLimit; 15775 if (mProcessLimit <= 0) { 15776 emptyProcessLimit = cachedProcessLimit = 0; 15777 } else if (mProcessLimit == 1) { 15778 emptyProcessLimit = 1; 15779 cachedProcessLimit = 0; 15780 } else { 15781 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15782 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15783 } 15784 15785 // Let's determine how many processes we have running vs. 15786 // how many slots we have for background processes; we may want 15787 // to put multiple processes in a slot of there are enough of 15788 // them. 15789 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15790 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15791 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15792 if (numEmptyProcs > cachedProcessLimit) { 15793 // If there are more empty processes than our limit on cached 15794 // processes, then use the cached process limit for the factor. 15795 // This ensures that the really old empty processes get pushed 15796 // down to the bottom, so if we are running low on memory we will 15797 // have a better chance at keeping around more cached processes 15798 // instead of a gazillion empty processes. 15799 numEmptyProcs = cachedProcessLimit; 15800 } 15801 int emptyFactor = numEmptyProcs/numSlots; 15802 if (emptyFactor < 1) emptyFactor = 1; 15803 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15804 if (cachedFactor < 1) cachedFactor = 1; 15805 int stepCached = 0; 15806 int stepEmpty = 0; 15807 int numCached = 0; 15808 int numEmpty = 0; 15809 int numTrimming = 0; 15810 15811 mNumNonCachedProcs = 0; 15812 mNumCachedHiddenProcs = 0; 15813 15814 // First update the OOM adjustment for each of the 15815 // application processes based on their current state. 15816 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15817 int nextCachedAdj = curCachedAdj+1; 15818 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15819 int nextEmptyAdj = curEmptyAdj+2; 15820 for (int i=N-1; i>=0; i--) { 15821 ProcessRecord app = mLruProcesses.get(i); 15822 if (!app.killedByAm && app.thread != null) { 15823 app.procStateChanged = false; 15824 final boolean wasKeeping = app.keeping; 15825 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15826 15827 // If we haven't yet assigned the final cached adj 15828 // to the process, do that now. 15829 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15830 switch (app.curProcState) { 15831 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15832 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15833 // This process is a cached process holding activities... 15834 // assign it the next cached value for that type, and then 15835 // step that cached level. 15836 app.curRawAdj = curCachedAdj; 15837 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15838 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15839 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15840 + ")"); 15841 if (curCachedAdj != nextCachedAdj) { 15842 stepCached++; 15843 if (stepCached >= cachedFactor) { 15844 stepCached = 0; 15845 curCachedAdj = nextCachedAdj; 15846 nextCachedAdj += 2; 15847 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15848 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15849 } 15850 } 15851 } 15852 break; 15853 default: 15854 // For everything else, assign next empty cached process 15855 // level and bump that up. Note that this means that 15856 // long-running services that have dropped down to the 15857 // cached level will be treated as empty (since their process 15858 // state is still as a service), which is what we want. 15859 app.curRawAdj = curEmptyAdj; 15860 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15861 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15862 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15863 + ")"); 15864 if (curEmptyAdj != nextEmptyAdj) { 15865 stepEmpty++; 15866 if (stepEmpty >= emptyFactor) { 15867 stepEmpty = 0; 15868 curEmptyAdj = nextEmptyAdj; 15869 nextEmptyAdj += 2; 15870 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15871 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15872 } 15873 } 15874 } 15875 break; 15876 } 15877 } 15878 15879 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 15880 15881 // Count the number of process types. 15882 switch (app.curProcState) { 15883 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15884 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15885 mNumCachedHiddenProcs++; 15886 numCached++; 15887 if (numCached > cachedProcessLimit) { 15888 killUnneededProcessLocked(app, "cached #" + numCached); 15889 } 15890 break; 15891 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15892 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15893 && app.lastActivityTime < oldTime) { 15894 killUnneededProcessLocked(app, "empty for " 15895 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15896 / 1000) + "s"); 15897 } else { 15898 numEmpty++; 15899 if (numEmpty > emptyProcessLimit) { 15900 killUnneededProcessLocked(app, "empty #" + numEmpty); 15901 } 15902 } 15903 break; 15904 default: 15905 mNumNonCachedProcs++; 15906 break; 15907 } 15908 15909 if (app.isolated && app.services.size() <= 0) { 15910 // If this is an isolated process, and there are no 15911 // services running in it, then the process is no longer 15912 // needed. We agressively kill these because we can by 15913 // definition not re-use the same process again, and it is 15914 // good to avoid having whatever code was running in them 15915 // left sitting around after no longer needed. 15916 killUnneededProcessLocked(app, "isolated not needed"); 15917 } 15918 15919 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15920 && !app.killedByAm) { 15921 numTrimming++; 15922 } 15923 } 15924 } 15925 15926 mNumServiceProcs = mNewNumServiceProcs; 15927 15928 // Now determine the memory trimming level of background processes. 15929 // Unfortunately we need to start at the back of the list to do this 15930 // properly. We only do this if the number of background apps we 15931 // are managing to keep around is less than half the maximum we desire; 15932 // if we are keeping a good number around, we'll let them use whatever 15933 // memory they want. 15934 final int numCachedAndEmpty = numCached + numEmpty; 15935 int memFactor; 15936 if (numCached <= ProcessList.TRIM_CACHED_APPS 15937 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15938 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15939 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15940 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15941 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15942 } else { 15943 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15944 } 15945 } else { 15946 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15947 } 15948 // We always allow the memory level to go up (better). We only allow it to go 15949 // down if we are in a state where that is allowed, *and* the total number of processes 15950 // has gone down since last time. 15951 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15952 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15953 + " last=" + mLastNumProcesses); 15954 if (memFactor > mLastMemoryLevel) { 15955 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15956 memFactor = mLastMemoryLevel; 15957 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15958 } 15959 } 15960 mLastMemoryLevel = memFactor; 15961 mLastNumProcesses = mLruProcesses.size(); 15962 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 15963 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15964 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15965 if (mLowRamStartTime == 0) { 15966 mLowRamStartTime = now; 15967 } 15968 int step = 0; 15969 int fgTrimLevel; 15970 switch (memFactor) { 15971 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15972 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15973 break; 15974 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15975 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15976 break; 15977 default: 15978 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15979 break; 15980 } 15981 int factor = numTrimming/3; 15982 int minFactor = 2; 15983 if (mHomeProcess != null) minFactor++; 15984 if (mPreviousProcess != null) minFactor++; 15985 if (factor < minFactor) factor = minFactor; 15986 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15987 for (int i=N-1; i>=0; i--) { 15988 ProcessRecord app = mLruProcesses.get(i); 15989 if (allChanged || app.procStateChanged) { 15990 setProcessTrackerState(app, trackerMemFactor, now); 15991 app.procStateChanged = false; 15992 } 15993 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15994 && !app.killedByAm) { 15995 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15996 try { 15997 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15998 "Trimming memory of " + app.processName 15999 + " to " + curLevel); 16000 app.thread.scheduleTrimMemory(curLevel); 16001 } catch (RemoteException e) { 16002 } 16003 if (false) { 16004 // For now we won't do this; our memory trimming seems 16005 // to be good enough at this point that destroying 16006 // activities causes more harm than good. 16007 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16008 && app != mHomeProcess && app != mPreviousProcess) { 16009 // Need to do this on its own message because the stack may not 16010 // be in a consistent state at this point. 16011 // For these apps we will also finish their activities 16012 // to help them free memory. 16013 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16014 } 16015 } 16016 } 16017 app.trimMemoryLevel = curLevel; 16018 step++; 16019 if (step >= factor) { 16020 step = 0; 16021 switch (curLevel) { 16022 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16023 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16024 break; 16025 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16026 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16027 break; 16028 } 16029 } 16030 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16031 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16032 && app.thread != null) { 16033 try { 16034 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16035 "Trimming memory of heavy-weight " + app.processName 16036 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16037 app.thread.scheduleTrimMemory( 16038 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16039 } catch (RemoteException e) { 16040 } 16041 } 16042 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16043 } else { 16044 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16045 || app.systemNoUi) && app.pendingUiClean) { 16046 // If this application is now in the background and it 16047 // had done UI, then give it the special trim level to 16048 // have it free UI resources. 16049 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16050 if (app.trimMemoryLevel < level && app.thread != null) { 16051 try { 16052 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16053 "Trimming memory of bg-ui " + app.processName 16054 + " to " + level); 16055 app.thread.scheduleTrimMemory(level); 16056 } catch (RemoteException e) { 16057 } 16058 } 16059 app.pendingUiClean = false; 16060 } 16061 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16062 try { 16063 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16064 "Trimming memory of fg " + app.processName 16065 + " to " + fgTrimLevel); 16066 app.thread.scheduleTrimMemory(fgTrimLevel); 16067 } catch (RemoteException e) { 16068 } 16069 } 16070 app.trimMemoryLevel = fgTrimLevel; 16071 } 16072 } 16073 } else { 16074 if (mLowRamStartTime != 0) { 16075 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16076 mLowRamStartTime = 0; 16077 } 16078 for (int i=N-1; i>=0; i--) { 16079 ProcessRecord app = mLruProcesses.get(i); 16080 if (allChanged || app.procStateChanged) { 16081 setProcessTrackerState(app, trackerMemFactor, now); 16082 app.procStateChanged = false; 16083 } 16084 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16085 || app.systemNoUi) && app.pendingUiClean) { 16086 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16087 && app.thread != null) { 16088 try { 16089 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16090 "Trimming memory of ui hidden " + app.processName 16091 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16092 app.thread.scheduleTrimMemory( 16093 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16094 } catch (RemoteException e) { 16095 } 16096 } 16097 app.pendingUiClean = false; 16098 } 16099 app.trimMemoryLevel = 0; 16100 } 16101 } 16102 16103 if (mAlwaysFinishActivities) { 16104 // Need to do this on its own message because the stack may not 16105 // be in a consistent state at this point. 16106 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16107 } 16108 16109 if (allChanged) { 16110 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16111 } 16112 16113 if (mProcessStats.shouldWriteNowLocked(now)) { 16114 mHandler.post(new Runnable() { 16115 @Override public void run() { 16116 synchronized (ActivityManagerService.this) { 16117 mProcessStats.writeStateAsyncLocked(); 16118 } 16119 } 16120 }); 16121 } 16122 16123 if (DEBUG_OOM_ADJ) { 16124 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16125 } 16126 } 16127 16128 final void trimApplications() { 16129 synchronized (this) { 16130 int i; 16131 16132 // First remove any unused application processes whose package 16133 // has been removed. 16134 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16135 final ProcessRecord app = mRemovedProcesses.get(i); 16136 if (app.activities.size() == 0 16137 && app.curReceiver == null && app.services.size() == 0) { 16138 Slog.i( 16139 TAG, "Exiting empty application process " 16140 + app.processName + " (" 16141 + (app.thread != null ? app.thread.asBinder() : null) 16142 + ")\n"); 16143 if (app.pid > 0 && app.pid != MY_PID) { 16144 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16145 app.processName, app.setAdj, "empty"); 16146 app.killedByAm = true; 16147 Process.killProcessQuiet(app.pid); 16148 } else { 16149 try { 16150 app.thread.scheduleExit(); 16151 } catch (Exception e) { 16152 // Ignore exceptions. 16153 } 16154 } 16155 cleanUpApplicationRecordLocked(app, false, true, -1); 16156 mRemovedProcesses.remove(i); 16157 16158 if (app.persistent) { 16159 if (app.persistent) { 16160 addAppLocked(app.info, false); 16161 } 16162 } 16163 } 16164 } 16165 16166 // Now update the oom adj for all processes. 16167 updateOomAdjLocked(); 16168 } 16169 } 16170 16171 /** This method sends the specified signal to each of the persistent apps */ 16172 public void signalPersistentProcesses(int sig) throws RemoteException { 16173 if (sig != Process.SIGNAL_USR1) { 16174 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16175 } 16176 16177 synchronized (this) { 16178 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16179 != PackageManager.PERMISSION_GRANTED) { 16180 throw new SecurityException("Requires permission " 16181 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16182 } 16183 16184 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16185 ProcessRecord r = mLruProcesses.get(i); 16186 if (r.thread != null && r.persistent) { 16187 Process.sendSignal(r.pid, sig); 16188 } 16189 } 16190 } 16191 } 16192 16193 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16194 if (proc == null || proc == mProfileProc) { 16195 proc = mProfileProc; 16196 path = mProfileFile; 16197 profileType = mProfileType; 16198 clearProfilerLocked(); 16199 } 16200 if (proc == null) { 16201 return; 16202 } 16203 try { 16204 proc.thread.profilerControl(false, path, null, profileType); 16205 } catch (RemoteException e) { 16206 throw new IllegalStateException("Process disappeared"); 16207 } 16208 } 16209 16210 private void clearProfilerLocked() { 16211 if (mProfileFd != null) { 16212 try { 16213 mProfileFd.close(); 16214 } catch (IOException e) { 16215 } 16216 } 16217 mProfileApp = null; 16218 mProfileProc = null; 16219 mProfileFile = null; 16220 mProfileType = 0; 16221 mAutoStopProfiler = false; 16222 } 16223 16224 public boolean profileControl(String process, int userId, boolean start, 16225 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16226 16227 try { 16228 synchronized (this) { 16229 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16230 // its own permission. 16231 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16232 != PackageManager.PERMISSION_GRANTED) { 16233 throw new SecurityException("Requires permission " 16234 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16235 } 16236 16237 if (start && fd == null) { 16238 throw new IllegalArgumentException("null fd"); 16239 } 16240 16241 ProcessRecord proc = null; 16242 if (process != null) { 16243 proc = findProcessLocked(process, userId, "profileControl"); 16244 } 16245 16246 if (start && (proc == null || proc.thread == null)) { 16247 throw new IllegalArgumentException("Unknown process: " + process); 16248 } 16249 16250 if (start) { 16251 stopProfilerLocked(null, null, 0); 16252 setProfileApp(proc.info, proc.processName, path, fd, false); 16253 mProfileProc = proc; 16254 mProfileType = profileType; 16255 try { 16256 fd = fd.dup(); 16257 } catch (IOException e) { 16258 fd = null; 16259 } 16260 proc.thread.profilerControl(start, path, fd, profileType); 16261 fd = null; 16262 mProfileFd = null; 16263 } else { 16264 stopProfilerLocked(proc, path, profileType); 16265 if (fd != null) { 16266 try { 16267 fd.close(); 16268 } catch (IOException e) { 16269 } 16270 } 16271 } 16272 16273 return true; 16274 } 16275 } catch (RemoteException e) { 16276 throw new IllegalStateException("Process disappeared"); 16277 } finally { 16278 if (fd != null) { 16279 try { 16280 fd.close(); 16281 } catch (IOException e) { 16282 } 16283 } 16284 } 16285 } 16286 16287 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16288 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16289 userId, true, true, callName, null); 16290 ProcessRecord proc = null; 16291 try { 16292 int pid = Integer.parseInt(process); 16293 synchronized (mPidsSelfLocked) { 16294 proc = mPidsSelfLocked.get(pid); 16295 } 16296 } catch (NumberFormatException e) { 16297 } 16298 16299 if (proc == null) { 16300 ArrayMap<String, SparseArray<ProcessRecord>> all 16301 = mProcessNames.getMap(); 16302 SparseArray<ProcessRecord> procs = all.get(process); 16303 if (procs != null && procs.size() > 0) { 16304 proc = procs.valueAt(0); 16305 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16306 for (int i=1; i<procs.size(); i++) { 16307 ProcessRecord thisProc = procs.valueAt(i); 16308 if (thisProc.userId == userId) { 16309 proc = thisProc; 16310 break; 16311 } 16312 } 16313 } 16314 } 16315 } 16316 16317 return proc; 16318 } 16319 16320 public boolean dumpHeap(String process, int userId, boolean managed, 16321 String path, ParcelFileDescriptor fd) throws RemoteException { 16322 16323 try { 16324 synchronized (this) { 16325 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16326 // its own permission (same as profileControl). 16327 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16328 != PackageManager.PERMISSION_GRANTED) { 16329 throw new SecurityException("Requires permission " 16330 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16331 } 16332 16333 if (fd == null) { 16334 throw new IllegalArgumentException("null fd"); 16335 } 16336 16337 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16338 if (proc == null || proc.thread == null) { 16339 throw new IllegalArgumentException("Unknown process: " + process); 16340 } 16341 16342 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16343 if (!isDebuggable) { 16344 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16345 throw new SecurityException("Process not debuggable: " + proc); 16346 } 16347 } 16348 16349 proc.thread.dumpHeap(managed, path, fd); 16350 fd = null; 16351 return true; 16352 } 16353 } catch (RemoteException e) { 16354 throw new IllegalStateException("Process disappeared"); 16355 } finally { 16356 if (fd != null) { 16357 try { 16358 fd.close(); 16359 } catch (IOException e) { 16360 } 16361 } 16362 } 16363 } 16364 16365 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16366 public void monitor() { 16367 synchronized (this) { } 16368 } 16369 16370 void onCoreSettingsChange(Bundle settings) { 16371 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16372 ProcessRecord processRecord = mLruProcesses.get(i); 16373 try { 16374 if (processRecord.thread != null) { 16375 processRecord.thread.setCoreSettings(settings); 16376 } 16377 } catch (RemoteException re) { 16378 /* ignore */ 16379 } 16380 } 16381 } 16382 16383 // Multi-user methods 16384 16385 /** 16386 * Start user, if its not already running, but don't bring it to foreground. 16387 */ 16388 @Override 16389 public boolean startUserInBackground(final int userId) { 16390 return startUser(userId, /* foreground */ false); 16391 } 16392 16393 /** 16394 * Refreshes the list of users related to the current user when either a 16395 * user switch happens or when a new related user is started in the 16396 * background. 16397 */ 16398 private void updateCurrentProfileIdsLocked() { 16399 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16400 mCurrentUserId, false /* enabledOnly */); 16401 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16402 for (int i = 0; i < currentProfileIds.length; i++) { 16403 currentProfileIds[i] = profiles.get(i).id; 16404 } 16405 mCurrentProfileIds = currentProfileIds; 16406 } 16407 16408 private Set getProfileIdsLocked(int userId) { 16409 Set userIds = new HashSet<Integer>(); 16410 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16411 userId, false /* enabledOnly */); 16412 for (UserInfo user : profiles) { 16413 userIds.add(Integer.valueOf(user.id)); 16414 } 16415 return userIds; 16416 } 16417 16418 @Override 16419 public boolean switchUser(final int userId) { 16420 return startUser(userId, /* foregound */ true); 16421 } 16422 16423 private boolean startUser(final int userId, boolean foreground) { 16424 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16425 != PackageManager.PERMISSION_GRANTED) { 16426 String msg = "Permission Denial: switchUser() from pid=" 16427 + Binder.getCallingPid() 16428 + ", uid=" + Binder.getCallingUid() 16429 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16430 Slog.w(TAG, msg); 16431 throw new SecurityException(msg); 16432 } 16433 16434 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16435 16436 final long ident = Binder.clearCallingIdentity(); 16437 try { 16438 synchronized (this) { 16439 final int oldUserId = mCurrentUserId; 16440 if (oldUserId == userId) { 16441 return true; 16442 } 16443 16444 mStackSupervisor.setLockTaskModeLocked(null); 16445 16446 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16447 if (userInfo == null) { 16448 Slog.w(TAG, "No user info for user #" + userId); 16449 return false; 16450 } 16451 16452 if (foreground) { 16453 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16454 R.anim.screen_user_enter); 16455 } 16456 16457 boolean needStart = false; 16458 16459 // If the user we are switching to is not currently started, then 16460 // we need to start it now. 16461 if (mStartedUsers.get(userId) == null) { 16462 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16463 updateStartedUserArrayLocked(); 16464 needStart = true; 16465 } 16466 16467 final Integer userIdInt = Integer.valueOf(userId); 16468 mUserLru.remove(userIdInt); 16469 mUserLru.add(userIdInt); 16470 16471 if (foreground) { 16472 mCurrentUserId = userId; 16473 updateCurrentProfileIdsLocked(); 16474 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16475 // Once the internal notion of the active user has switched, we lock the device 16476 // with the option to show the user switcher on the keyguard. 16477 mWindowManager.lockNow(null); 16478 } else { 16479 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16480 updateCurrentProfileIdsLocked(); 16481 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16482 mUserLru.remove(currentUserIdInt); 16483 mUserLru.add(currentUserIdInt); 16484 } 16485 16486 final UserStartedState uss = mStartedUsers.get(userId); 16487 16488 // Make sure user is in the started state. If it is currently 16489 // stopping, we need to knock that off. 16490 if (uss.mState == UserStartedState.STATE_STOPPING) { 16491 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16492 // so we can just fairly silently bring the user back from 16493 // the almost-dead. 16494 uss.mState = UserStartedState.STATE_RUNNING; 16495 updateStartedUserArrayLocked(); 16496 needStart = true; 16497 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16498 // This means ACTION_SHUTDOWN has been sent, so we will 16499 // need to treat this as a new boot of the user. 16500 uss.mState = UserStartedState.STATE_BOOTING; 16501 updateStartedUserArrayLocked(); 16502 needStart = true; 16503 } 16504 16505 if (uss.mState == UserStartedState.STATE_BOOTING) { 16506 // Booting up a new user, need to tell system services about it. 16507 // Note that this is on the same handler as scheduling of broadcasts, 16508 // which is important because it needs to go first. 16509 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16510 } 16511 16512 if (foreground) { 16513 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16514 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16515 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16516 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16517 oldUserId, userId, uss)); 16518 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16519 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16520 } 16521 16522 if (needStart) { 16523 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16524 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16525 | Intent.FLAG_RECEIVER_FOREGROUND); 16526 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16527 broadcastIntentLocked(null, null, intent, 16528 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16529 false, false, MY_PID, Process.SYSTEM_UID, userId); 16530 } 16531 16532 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16533 if (userId != UserHandle.USER_OWNER) { 16534 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16535 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16536 broadcastIntentLocked(null, null, intent, null, 16537 new IIntentReceiver.Stub() { 16538 public void performReceive(Intent intent, int resultCode, 16539 String data, Bundle extras, boolean ordered, 16540 boolean sticky, int sendingUser) { 16541 userInitialized(uss, userId); 16542 } 16543 }, 0, null, null, null, AppOpsManager.OP_NONE, 16544 true, false, MY_PID, Process.SYSTEM_UID, 16545 userId); 16546 uss.initializing = true; 16547 } else { 16548 getUserManagerLocked().makeInitialized(userInfo.id); 16549 } 16550 } 16551 16552 if (foreground) { 16553 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16554 if (homeInFront) { 16555 startHomeActivityLocked(userId); 16556 } else { 16557 mStackSupervisor.resumeTopActivitiesLocked(); 16558 } 16559 EventLogTags.writeAmSwitchUser(userId); 16560 getUserManagerLocked().userForeground(userId); 16561 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16562 } else { 16563 mStackSupervisor.startBackgroundUserLocked(userId, uss); 16564 } 16565 16566 if (needStart) { 16567 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16568 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16569 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16570 broadcastIntentLocked(null, null, intent, 16571 null, new IIntentReceiver.Stub() { 16572 @Override 16573 public void performReceive(Intent intent, int resultCode, String data, 16574 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16575 throws RemoteException { 16576 } 16577 }, 0, null, null, 16578 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16579 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16580 } 16581 } 16582 } finally { 16583 Binder.restoreCallingIdentity(ident); 16584 } 16585 16586 return true; 16587 } 16588 16589 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16590 long ident = Binder.clearCallingIdentity(); 16591 try { 16592 Intent intent; 16593 if (oldUserId >= 0) { 16594 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16595 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16596 | Intent.FLAG_RECEIVER_FOREGROUND); 16597 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16598 broadcastIntentLocked(null, null, intent, 16599 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16600 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16601 } 16602 if (newUserId >= 0) { 16603 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16604 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16605 | Intent.FLAG_RECEIVER_FOREGROUND); 16606 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16607 broadcastIntentLocked(null, null, intent, 16608 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16609 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16610 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16611 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16612 | Intent.FLAG_RECEIVER_FOREGROUND); 16613 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16614 broadcastIntentLocked(null, null, intent, 16615 null, null, 0, null, null, 16616 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16617 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16618 } 16619 } finally { 16620 Binder.restoreCallingIdentity(ident); 16621 } 16622 } 16623 16624 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16625 final int newUserId) { 16626 final int N = mUserSwitchObservers.beginBroadcast(); 16627 if (N > 0) { 16628 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16629 int mCount = 0; 16630 @Override 16631 public void sendResult(Bundle data) throws RemoteException { 16632 synchronized (ActivityManagerService.this) { 16633 if (mCurUserSwitchCallback == this) { 16634 mCount++; 16635 if (mCount == N) { 16636 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16637 } 16638 } 16639 } 16640 } 16641 }; 16642 synchronized (this) { 16643 uss.switching = true; 16644 mCurUserSwitchCallback = callback; 16645 } 16646 for (int i=0; i<N; i++) { 16647 try { 16648 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16649 newUserId, callback); 16650 } catch (RemoteException e) { 16651 } 16652 } 16653 } else { 16654 synchronized (this) { 16655 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16656 } 16657 } 16658 mUserSwitchObservers.finishBroadcast(); 16659 } 16660 16661 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16662 synchronized (this) { 16663 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16664 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16665 } 16666 } 16667 16668 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16669 mCurUserSwitchCallback = null; 16670 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16671 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16672 oldUserId, newUserId, uss)); 16673 } 16674 16675 void userInitialized(UserStartedState uss, int newUserId) { 16676 completeSwitchAndInitalize(uss, newUserId, true, false); 16677 } 16678 16679 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16680 completeSwitchAndInitalize(uss, newUserId, false, true); 16681 } 16682 16683 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16684 boolean clearInitializing, boolean clearSwitching) { 16685 boolean unfrozen = false; 16686 synchronized (this) { 16687 if (clearInitializing) { 16688 uss.initializing = false; 16689 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16690 } 16691 if (clearSwitching) { 16692 uss.switching = false; 16693 } 16694 if (!uss.switching && !uss.initializing) { 16695 mWindowManager.stopFreezingScreen(); 16696 unfrozen = true; 16697 } 16698 } 16699 if (unfrozen) { 16700 final int N = mUserSwitchObservers.beginBroadcast(); 16701 for (int i=0; i<N; i++) { 16702 try { 16703 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16704 } catch (RemoteException e) { 16705 } 16706 } 16707 mUserSwitchObservers.finishBroadcast(); 16708 } 16709 } 16710 16711 void scheduleStartProfilesLocked() { 16712 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16713 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16714 DateUtils.SECOND_IN_MILLIS); 16715 } 16716 } 16717 16718 void startProfilesLocked() { 16719 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16720 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16721 mCurrentUserId, false /* enabledOnly */); 16722 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16723 for (UserInfo user : profiles) { 16724 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16725 && user.id != mCurrentUserId) { 16726 toStart.add(user); 16727 } 16728 } 16729 final int n = toStart.size(); 16730 int i = 0; 16731 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16732 startUserInBackground(toStart.get(i).id); 16733 } 16734 if (i < n) { 16735 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16736 } 16737 } 16738 16739 void finishUserBoot(UserStartedState uss) { 16740 synchronized (this) { 16741 if (uss.mState == UserStartedState.STATE_BOOTING 16742 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16743 uss.mState = UserStartedState.STATE_RUNNING; 16744 final int userId = uss.mHandle.getIdentifier(); 16745 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16746 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16747 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16748 broadcastIntentLocked(null, null, intent, 16749 null, null, 0, null, null, 16750 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16751 true, false, MY_PID, Process.SYSTEM_UID, userId); 16752 } 16753 } 16754 } 16755 16756 void finishUserSwitch(UserStartedState uss) { 16757 synchronized (this) { 16758 finishUserBoot(uss); 16759 16760 startProfilesLocked(); 16761 16762 int num = mUserLru.size(); 16763 int i = 0; 16764 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16765 Integer oldUserId = mUserLru.get(i); 16766 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16767 if (oldUss == null) { 16768 // Shouldn't happen, but be sane if it does. 16769 mUserLru.remove(i); 16770 num--; 16771 continue; 16772 } 16773 if (oldUss.mState == UserStartedState.STATE_STOPPING 16774 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16775 // This user is already stopping, doesn't count. 16776 num--; 16777 i++; 16778 continue; 16779 } 16780 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16781 // Owner and current can't be stopped, but count as running. 16782 i++; 16783 continue; 16784 } 16785 // This is a user to be stopped. 16786 stopUserLocked(oldUserId, null); 16787 num--; 16788 i++; 16789 } 16790 } 16791 } 16792 16793 @Override 16794 public int stopUser(final int userId, final IStopUserCallback callback) { 16795 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16796 != PackageManager.PERMISSION_GRANTED) { 16797 String msg = "Permission Denial: switchUser() from pid=" 16798 + Binder.getCallingPid() 16799 + ", uid=" + Binder.getCallingUid() 16800 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16801 Slog.w(TAG, msg); 16802 throw new SecurityException(msg); 16803 } 16804 if (userId <= 0) { 16805 throw new IllegalArgumentException("Can't stop primary user " + userId); 16806 } 16807 synchronized (this) { 16808 return stopUserLocked(userId, callback); 16809 } 16810 } 16811 16812 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16813 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16814 if (mCurrentUserId == userId) { 16815 return ActivityManager.USER_OP_IS_CURRENT; 16816 } 16817 16818 final UserStartedState uss = mStartedUsers.get(userId); 16819 if (uss == null) { 16820 // User is not started, nothing to do... but we do need to 16821 // callback if requested. 16822 if (callback != null) { 16823 mHandler.post(new Runnable() { 16824 @Override 16825 public void run() { 16826 try { 16827 callback.userStopped(userId); 16828 } catch (RemoteException e) { 16829 } 16830 } 16831 }); 16832 } 16833 return ActivityManager.USER_OP_SUCCESS; 16834 } 16835 16836 if (callback != null) { 16837 uss.mStopCallbacks.add(callback); 16838 } 16839 16840 if (uss.mState != UserStartedState.STATE_STOPPING 16841 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16842 uss.mState = UserStartedState.STATE_STOPPING; 16843 updateStartedUserArrayLocked(); 16844 16845 long ident = Binder.clearCallingIdentity(); 16846 try { 16847 // We are going to broadcast ACTION_USER_STOPPING and then 16848 // once that is done send a final ACTION_SHUTDOWN and then 16849 // stop the user. 16850 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16851 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16852 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16853 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16854 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16855 // This is the result receiver for the final shutdown broadcast. 16856 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16857 @Override 16858 public void performReceive(Intent intent, int resultCode, String data, 16859 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16860 finishUserStop(uss); 16861 } 16862 }; 16863 // This is the result receiver for the initial stopping broadcast. 16864 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16865 @Override 16866 public void performReceive(Intent intent, int resultCode, String data, 16867 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16868 // On to the next. 16869 synchronized (ActivityManagerService.this) { 16870 if (uss.mState != UserStartedState.STATE_STOPPING) { 16871 // Whoops, we are being started back up. Abort, abort! 16872 return; 16873 } 16874 uss.mState = UserStartedState.STATE_SHUTDOWN; 16875 } 16876 mSystemServiceManager.stopUser(userId); 16877 broadcastIntentLocked(null, null, shutdownIntent, 16878 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16879 true, false, MY_PID, Process.SYSTEM_UID, userId); 16880 } 16881 }; 16882 // Kick things off. 16883 broadcastIntentLocked(null, null, stoppingIntent, 16884 null, stoppingReceiver, 0, null, null, 16885 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16886 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16887 } finally { 16888 Binder.restoreCallingIdentity(ident); 16889 } 16890 } 16891 16892 return ActivityManager.USER_OP_SUCCESS; 16893 } 16894 16895 void finishUserStop(UserStartedState uss) { 16896 final int userId = uss.mHandle.getIdentifier(); 16897 boolean stopped; 16898 ArrayList<IStopUserCallback> callbacks; 16899 synchronized (this) { 16900 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16901 if (mStartedUsers.get(userId) != uss) { 16902 stopped = false; 16903 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16904 stopped = false; 16905 } else { 16906 stopped = true; 16907 // User can no longer run. 16908 mStartedUsers.remove(userId); 16909 mUserLru.remove(Integer.valueOf(userId)); 16910 updateStartedUserArrayLocked(); 16911 16912 // Clean up all state and processes associated with the user. 16913 // Kill all the processes for the user. 16914 forceStopUserLocked(userId, "finish user"); 16915 } 16916 } 16917 16918 for (int i=0; i<callbacks.size(); i++) { 16919 try { 16920 if (stopped) callbacks.get(i).userStopped(userId); 16921 else callbacks.get(i).userStopAborted(userId); 16922 } catch (RemoteException e) { 16923 } 16924 } 16925 16926 if (stopped) { 16927 mSystemServiceManager.cleanupUser(userId); 16928 synchronized (this) { 16929 mStackSupervisor.removeUserLocked(userId); 16930 } 16931 } 16932 } 16933 16934 @Override 16935 public UserInfo getCurrentUser() { 16936 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16937 != PackageManager.PERMISSION_GRANTED) && ( 16938 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16939 != PackageManager.PERMISSION_GRANTED)) { 16940 String msg = "Permission Denial: getCurrentUser() from pid=" 16941 + Binder.getCallingPid() 16942 + ", uid=" + Binder.getCallingUid() 16943 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16944 Slog.w(TAG, msg); 16945 throw new SecurityException(msg); 16946 } 16947 synchronized (this) { 16948 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16949 } 16950 } 16951 16952 int getCurrentUserIdLocked() { 16953 return mCurrentUserId; 16954 } 16955 16956 @Override 16957 public boolean isUserRunning(int userId, boolean orStopped) { 16958 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16959 != PackageManager.PERMISSION_GRANTED) { 16960 String msg = "Permission Denial: isUserRunning() 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 isUserRunningLocked(userId, orStopped); 16969 } 16970 } 16971 16972 boolean isUserRunningLocked(int userId, boolean orStopped) { 16973 UserStartedState state = mStartedUsers.get(userId); 16974 if (state == null) { 16975 return false; 16976 } 16977 if (orStopped) { 16978 return true; 16979 } 16980 return state.mState != UserStartedState.STATE_STOPPING 16981 && state.mState != UserStartedState.STATE_SHUTDOWN; 16982 } 16983 16984 @Override 16985 public int[] getRunningUserIds() { 16986 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16987 != PackageManager.PERMISSION_GRANTED) { 16988 String msg = "Permission Denial: isUserRunning() from pid=" 16989 + Binder.getCallingPid() 16990 + ", uid=" + Binder.getCallingUid() 16991 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16992 Slog.w(TAG, msg); 16993 throw new SecurityException(msg); 16994 } 16995 synchronized (this) { 16996 return mStartedUserArray; 16997 } 16998 } 16999 17000 private void updateStartedUserArrayLocked() { 17001 int num = 0; 17002 for (int i=0; i<mStartedUsers.size(); i++) { 17003 UserStartedState uss = mStartedUsers.valueAt(i); 17004 // This list does not include stopping users. 17005 if (uss.mState != UserStartedState.STATE_STOPPING 17006 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17007 num++; 17008 } 17009 } 17010 mStartedUserArray = new int[num]; 17011 num = 0; 17012 for (int i=0; i<mStartedUsers.size(); i++) { 17013 UserStartedState uss = mStartedUsers.valueAt(i); 17014 if (uss.mState != UserStartedState.STATE_STOPPING 17015 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17016 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17017 num++; 17018 } 17019 } 17020 } 17021 17022 @Override 17023 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17024 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17025 != PackageManager.PERMISSION_GRANTED) { 17026 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17027 + Binder.getCallingPid() 17028 + ", uid=" + Binder.getCallingUid() 17029 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 17030 Slog.w(TAG, msg); 17031 throw new SecurityException(msg); 17032 } 17033 17034 mUserSwitchObservers.register(observer); 17035 } 17036 17037 @Override 17038 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17039 mUserSwitchObservers.unregister(observer); 17040 } 17041 17042 private boolean userExists(int userId) { 17043 if (userId == 0) { 17044 return true; 17045 } 17046 UserManagerService ums = getUserManagerLocked(); 17047 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17048 } 17049 17050 int[] getUsersLocked() { 17051 UserManagerService ums = getUserManagerLocked(); 17052 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17053 } 17054 17055 UserManagerService getUserManagerLocked() { 17056 if (mUserManager == null) { 17057 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17058 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17059 } 17060 return mUserManager; 17061 } 17062 17063 private int applyUserId(int uid, int userId) { 17064 return UserHandle.getUid(userId, uid); 17065 } 17066 17067 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17068 if (info == null) return null; 17069 ApplicationInfo newInfo = new ApplicationInfo(info); 17070 newInfo.uid = applyUserId(info.uid, userId); 17071 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17072 + info.packageName; 17073 return newInfo; 17074 } 17075 17076 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17077 if (aInfo == null 17078 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17079 return aInfo; 17080 } 17081 17082 ActivityInfo info = new ActivityInfo(aInfo); 17083 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17084 return info; 17085 } 17086 17087 private final class LocalService extends ActivityManagerInternal { 17088 @Override 17089 public void goingToSleep() { 17090 ActivityManagerService.this.goingToSleep(); 17091 } 17092 17093 @Override 17094 public void wakingUp() { 17095 ActivityManagerService.this.wakingUp(); 17096 } 17097 } 17098} 17099