ActivityManagerService.java revision f2e074604b1ee7e47bcbf82bb9d612b64bbcee93
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 increasing 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 final PackageManager pm = mContext.getPackageManager(); 1854 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1855 new ArrayList<Pair<Intent, Integer>>(); 1856 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1857 // Copy the list of recent tasks so that we don't hold onto the lock on 1858 // ActivityManagerService for long periods while checking if components exist. 1859 synchronized (ActivityManagerService.this) { 1860 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1861 TaskRecord tr = mRecentTasks.get(i); 1862 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1863 } 1864 } 1865 // Check the recent tasks and filter out all tasks with components that no longer exist. 1866 Intent tmpI = new Intent(); 1867 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1868 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1869 ComponentName cn = p.first.getComponent(); 1870 if (cn != null && cn.getPackageName().equals(packageName)) { 1871 try { 1872 // Add the task to the list to remove if the component no longer exists 1873 tmpI.setComponent(cn); 1874 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1875 tasksToRemove.add(p.second); 1876 } 1877 } catch (Exception e) {} 1878 } 1879 } 1880 // Prune all the tasks with removed components from the list of recent tasks 1881 synchronized (ActivityManagerService.this) { 1882 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1883 // Remove the task but don't kill the process (since other components in that 1884 // package may still be running and in the background) 1885 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1886 } 1887 } 1888 return true; 1889 } 1890 1891 @Override 1892 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1893 // Force stop the specified packages 1894 if (packages != null) { 1895 for (String pkg : packages) { 1896 synchronized (ActivityManagerService.this) { 1897 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1898 "finished booting")) { 1899 return true; 1900 } 1901 } 1902 } 1903 } 1904 return false; 1905 } 1906 }; 1907 1908 public void setSystemProcess() { 1909 try { 1910 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1911 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1912 ServiceManager.addService("meminfo", new MemBinder(this)); 1913 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1914 ServiceManager.addService("dbinfo", new DbBinder(this)); 1915 if (MONITOR_CPU_USAGE) { 1916 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1917 } 1918 ServiceManager.addService("permission", new PermissionController(this)); 1919 1920 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1921 "android", STOCK_PM_FLAGS); 1922 mSystemThread.installSystemApplicationInfo(info); 1923 1924 synchronized (this) { 1925 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1926 app.persistent = true; 1927 app.pid = MY_PID; 1928 app.maxAdj = ProcessList.SYSTEM_ADJ; 1929 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1930 mProcessNames.put(app.processName, app.uid, app); 1931 synchronized (mPidsSelfLocked) { 1932 mPidsSelfLocked.put(app.pid, app); 1933 } 1934 updateLruProcessLocked(app, false, null); 1935 updateOomAdjLocked(); 1936 } 1937 } catch (PackageManager.NameNotFoundException e) { 1938 throw new RuntimeException( 1939 "Unable to find android system package", e); 1940 } 1941 } 1942 1943 public void setWindowManager(WindowManagerService wm) { 1944 mWindowManager = wm; 1945 mStackSupervisor.setWindowManager(wm); 1946 } 1947 1948 public void startObservingNativeCrashes() { 1949 final NativeCrashListener ncl = new NativeCrashListener(this); 1950 ncl.start(); 1951 } 1952 1953 public IAppOpsService getAppOpsService() { 1954 return mAppOpsService; 1955 } 1956 1957 static class MemBinder extends Binder { 1958 ActivityManagerService mActivityManagerService; 1959 MemBinder(ActivityManagerService activityManagerService) { 1960 mActivityManagerService = activityManagerService; 1961 } 1962 1963 @Override 1964 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1965 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1966 != PackageManager.PERMISSION_GRANTED) { 1967 pw.println("Permission Denial: can't dump meminfo from from pid=" 1968 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1969 + " without permission " + android.Manifest.permission.DUMP); 1970 return; 1971 } 1972 1973 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1974 } 1975 } 1976 1977 static class GraphicsBinder extends Binder { 1978 ActivityManagerService mActivityManagerService; 1979 GraphicsBinder(ActivityManagerService activityManagerService) { 1980 mActivityManagerService = activityManagerService; 1981 } 1982 1983 @Override 1984 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1985 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1986 != PackageManager.PERMISSION_GRANTED) { 1987 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1988 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1989 + " without permission " + android.Manifest.permission.DUMP); 1990 return; 1991 } 1992 1993 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1994 } 1995 } 1996 1997 static class DbBinder extends Binder { 1998 ActivityManagerService mActivityManagerService; 1999 DbBinder(ActivityManagerService activityManagerService) { 2000 mActivityManagerService = activityManagerService; 2001 } 2002 2003 @Override 2004 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2005 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2006 != PackageManager.PERMISSION_GRANTED) { 2007 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2008 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2009 + " without permission " + android.Manifest.permission.DUMP); 2010 return; 2011 } 2012 2013 mActivityManagerService.dumpDbInfo(fd, pw, args); 2014 } 2015 } 2016 2017 static class CpuBinder extends Binder { 2018 ActivityManagerService mActivityManagerService; 2019 CpuBinder(ActivityManagerService activityManagerService) { 2020 mActivityManagerService = activityManagerService; 2021 } 2022 2023 @Override 2024 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2025 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2026 != PackageManager.PERMISSION_GRANTED) { 2027 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2028 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2029 + " without permission " + android.Manifest.permission.DUMP); 2030 return; 2031 } 2032 2033 synchronized (mActivityManagerService.mProcessCpuThread) { 2034 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2035 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2036 SystemClock.uptimeMillis())); 2037 } 2038 } 2039 } 2040 2041 public static final class Lifecycle extends SystemService { 2042 private final ActivityManagerService mService; 2043 2044 public Lifecycle(Context context) { 2045 super(context); 2046 mService = new ActivityManagerService(context); 2047 } 2048 2049 @Override 2050 public void onStart() { 2051 mService.start(); 2052 } 2053 2054 public ActivityManagerService getService() { 2055 return mService; 2056 } 2057 } 2058 2059 // Note: This method is invoked on the main thread but may need to attach various 2060 // handlers to other threads. So take care to be explicit about the looper. 2061 public ActivityManagerService(Context systemContext) { 2062 mContext = systemContext; 2063 mFactoryTest = FactoryTest.getMode(); 2064 mSystemThread = ActivityThread.currentActivityThread(); 2065 2066 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2067 2068 mHandlerThread = new ServiceThread(TAG, 2069 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2070 mHandlerThread.start(); 2071 mHandler = new MainHandler(mHandlerThread.getLooper()); 2072 2073 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2074 "foreground", BROADCAST_FG_TIMEOUT, false); 2075 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2076 "background", BROADCAST_BG_TIMEOUT, true); 2077 mBroadcastQueues[0] = mFgBroadcastQueue; 2078 mBroadcastQueues[1] = mBgBroadcastQueue; 2079 2080 mServices = new ActiveServices(this); 2081 mProviderMap = new ProviderMap(this); 2082 2083 // TODO: Move creation of battery stats service outside of activity manager service. 2084 File dataDir = Environment.getDataDirectory(); 2085 File systemDir = new File(dataDir, "system"); 2086 systemDir.mkdirs(); 2087 mBatteryStatsService = new BatteryStatsService(new File( 2088 systemDir, "batterystats.bin").toString(), mHandler); 2089 mBatteryStatsService.getActiveStatistics().readLocked(); 2090 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2091 mOnBattery = DEBUG_POWER ? true 2092 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2093 mBatteryStatsService.getActiveStatistics().setCallback(this); 2094 2095 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2096 2097 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2098 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2099 2100 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2101 2102 // User 0 is the first and only user that runs at boot. 2103 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2104 mUserLru.add(Integer.valueOf(0)); 2105 updateStartedUserArrayLocked(); 2106 2107 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2108 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2109 2110 mConfiguration.setToDefaults(); 2111 mConfiguration.setLocale(Locale.getDefault()); 2112 2113 mConfigurationSeq = mConfiguration.seq = 1; 2114 mProcessCpuTracker.init(); 2115 2116 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2117 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2118 mStackSupervisor = new ActivityStackSupervisor(this); 2119 2120 mProcessCpuThread = new Thread("CpuTracker") { 2121 @Override 2122 public void run() { 2123 while (true) { 2124 try { 2125 try { 2126 synchronized(this) { 2127 final long now = SystemClock.uptimeMillis(); 2128 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2129 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2130 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2131 // + ", write delay=" + nextWriteDelay); 2132 if (nextWriteDelay < nextCpuDelay) { 2133 nextCpuDelay = nextWriteDelay; 2134 } 2135 if (nextCpuDelay > 0) { 2136 mProcessCpuMutexFree.set(true); 2137 this.wait(nextCpuDelay); 2138 } 2139 } 2140 } catch (InterruptedException e) { 2141 } 2142 updateCpuStatsNow(); 2143 } catch (Exception e) { 2144 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2145 } 2146 } 2147 } 2148 }; 2149 2150 Watchdog.getInstance().addMonitor(this); 2151 Watchdog.getInstance().addThread(mHandler); 2152 } 2153 2154 public void setSystemServiceManager(SystemServiceManager mgr) { 2155 mSystemServiceManager = mgr; 2156 } 2157 2158 private void start() { 2159 mProcessCpuThread.start(); 2160 2161 mBatteryStatsService.publish(mContext); 2162 mUsageStatsService.publish(mContext); 2163 mAppOpsService.publish(mContext); 2164 2165 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2166 } 2167 2168 @Override 2169 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2170 throws RemoteException { 2171 if (code == SYSPROPS_TRANSACTION) { 2172 // We need to tell all apps about the system property change. 2173 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2174 synchronized(this) { 2175 final int NP = mProcessNames.getMap().size(); 2176 for (int ip=0; ip<NP; ip++) { 2177 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2178 final int NA = apps.size(); 2179 for (int ia=0; ia<NA; ia++) { 2180 ProcessRecord app = apps.valueAt(ia); 2181 if (app.thread != null) { 2182 procs.add(app.thread.asBinder()); 2183 } 2184 } 2185 } 2186 } 2187 2188 int N = procs.size(); 2189 for (int i=0; i<N; i++) { 2190 Parcel data2 = Parcel.obtain(); 2191 try { 2192 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2193 } catch (RemoteException e) { 2194 } 2195 data2.recycle(); 2196 } 2197 } 2198 try { 2199 return super.onTransact(code, data, reply, flags); 2200 } catch (RuntimeException e) { 2201 // The activity manager only throws security exceptions, so let's 2202 // log all others. 2203 if (!(e instanceof SecurityException)) { 2204 Slog.wtf(TAG, "Activity Manager Crash", e); 2205 } 2206 throw e; 2207 } 2208 } 2209 2210 void updateCpuStats() { 2211 final long now = SystemClock.uptimeMillis(); 2212 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2213 return; 2214 } 2215 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2216 synchronized (mProcessCpuThread) { 2217 mProcessCpuThread.notify(); 2218 } 2219 } 2220 } 2221 2222 void updateCpuStatsNow() { 2223 synchronized (mProcessCpuThread) { 2224 mProcessCpuMutexFree.set(false); 2225 final long now = SystemClock.uptimeMillis(); 2226 boolean haveNewCpuStats = false; 2227 2228 if (MONITOR_CPU_USAGE && 2229 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2230 mLastCpuTime.set(now); 2231 haveNewCpuStats = true; 2232 mProcessCpuTracker.update(); 2233 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2234 //Slog.i(TAG, "Total CPU usage: " 2235 // + mProcessCpu.getTotalCpuPercent() + "%"); 2236 2237 // Slog the cpu usage if the property is set. 2238 if ("true".equals(SystemProperties.get("events.cpu"))) { 2239 int user = mProcessCpuTracker.getLastUserTime(); 2240 int system = mProcessCpuTracker.getLastSystemTime(); 2241 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2242 int irq = mProcessCpuTracker.getLastIrqTime(); 2243 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2244 int idle = mProcessCpuTracker.getLastIdleTime(); 2245 2246 int total = user + system + iowait + irq + softIrq + idle; 2247 if (total == 0) total = 1; 2248 2249 EventLog.writeEvent(EventLogTags.CPU, 2250 ((user+system+iowait+irq+softIrq) * 100) / total, 2251 (user * 100) / total, 2252 (system * 100) / total, 2253 (iowait * 100) / total, 2254 (irq * 100) / total, 2255 (softIrq * 100) / total); 2256 } 2257 } 2258 2259 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2260 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2261 synchronized(bstats) { 2262 synchronized(mPidsSelfLocked) { 2263 if (haveNewCpuStats) { 2264 if (mOnBattery) { 2265 int perc = bstats.startAddingCpuLocked(); 2266 int totalUTime = 0; 2267 int totalSTime = 0; 2268 final int N = mProcessCpuTracker.countStats(); 2269 for (int i=0; i<N; i++) { 2270 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2271 if (!st.working) { 2272 continue; 2273 } 2274 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2275 int otherUTime = (st.rel_utime*perc)/100; 2276 int otherSTime = (st.rel_stime*perc)/100; 2277 totalUTime += otherUTime; 2278 totalSTime += otherSTime; 2279 if (pr != null) { 2280 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2281 if (ps == null || !ps.isActive()) { 2282 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2283 pr.info.uid, pr.processName); 2284 } 2285 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2286 st.rel_stime-otherSTime); 2287 ps.addSpeedStepTimes(cpuSpeedTimes); 2288 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2289 } else { 2290 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2291 if (ps == null || !ps.isActive()) { 2292 st.batteryStats = ps = bstats.getProcessStatsLocked( 2293 bstats.mapUid(st.uid), st.name); 2294 } 2295 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2296 st.rel_stime-otherSTime); 2297 ps.addSpeedStepTimes(cpuSpeedTimes); 2298 } 2299 } 2300 bstats.finishAddingCpuLocked(perc, totalUTime, 2301 totalSTime, cpuSpeedTimes); 2302 } 2303 } 2304 } 2305 2306 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2307 mLastWriteTime = now; 2308 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2309 } 2310 } 2311 } 2312 } 2313 2314 @Override 2315 public void batteryNeedsCpuUpdate() { 2316 updateCpuStatsNow(); 2317 } 2318 2319 @Override 2320 public void batteryPowerChanged(boolean onBattery) { 2321 // When plugging in, update the CPU stats first before changing 2322 // the plug state. 2323 updateCpuStatsNow(); 2324 synchronized (this) { 2325 synchronized(mPidsSelfLocked) { 2326 mOnBattery = DEBUG_POWER ? true : onBattery; 2327 } 2328 } 2329 } 2330 2331 /** 2332 * Initialize the application bind args. These are passed to each 2333 * process when the bindApplication() IPC is sent to the process. They're 2334 * lazily setup to make sure the services are running when they're asked for. 2335 */ 2336 private HashMap<String, IBinder> getCommonServicesLocked() { 2337 if (mAppBindArgs == null) { 2338 mAppBindArgs = new HashMap<String, IBinder>(); 2339 2340 // Setup the application init args 2341 mAppBindArgs.put("package", ServiceManager.getService("package")); 2342 mAppBindArgs.put("window", ServiceManager.getService("window")); 2343 mAppBindArgs.put(Context.ALARM_SERVICE, 2344 ServiceManager.getService(Context.ALARM_SERVICE)); 2345 } 2346 return mAppBindArgs; 2347 } 2348 2349 final void setFocusedActivityLocked(ActivityRecord r) { 2350 if (mFocusedActivity != r) { 2351 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2352 mFocusedActivity = r; 2353 if (r.task != null && r.task.voiceInteractor != null) { 2354 startRunningVoiceLocked(); 2355 } else { 2356 finishRunningVoiceLocked(); 2357 } 2358 mStackSupervisor.setFocusedStack(r); 2359 if (r != null) { 2360 mWindowManager.setFocusedApp(r.appToken, true); 2361 } 2362 applyUpdateLockStateLocked(r); 2363 } 2364 } 2365 2366 final void clearFocusedActivity(ActivityRecord r) { 2367 if (mFocusedActivity == r) { 2368 mFocusedActivity = null; 2369 } 2370 } 2371 2372 @Override 2373 public void setFocusedStack(int stackId) { 2374 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2375 synchronized (ActivityManagerService.this) { 2376 ActivityStack stack = mStackSupervisor.getStack(stackId); 2377 if (stack != null) { 2378 ActivityRecord r = stack.topRunningActivityLocked(null); 2379 if (r != null) { 2380 setFocusedActivityLocked(r); 2381 } 2382 } 2383 } 2384 } 2385 2386 @Override 2387 public void notifyActivityDrawn(IBinder token) { 2388 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2389 synchronized (this) { 2390 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2391 if (r != null) { 2392 r.task.stack.notifyActivityDrawnLocked(r); 2393 } 2394 } 2395 } 2396 2397 final void applyUpdateLockStateLocked(ActivityRecord r) { 2398 // Modifications to the UpdateLock state are done on our handler, outside 2399 // the activity manager's locks. The new state is determined based on the 2400 // state *now* of the relevant activity record. The object is passed to 2401 // the handler solely for logging detail, not to be consulted/modified. 2402 final boolean nextState = r != null && r.immersive; 2403 mHandler.sendMessage( 2404 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2405 } 2406 2407 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2408 Message msg = Message.obtain(); 2409 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2410 msg.obj = r.task.askedCompatMode ? null : r; 2411 mHandler.sendMessage(msg); 2412 } 2413 2414 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2415 String what, Object obj, ProcessRecord srcApp) { 2416 app.lastActivityTime = now; 2417 2418 if (app.activities.size() > 0) { 2419 // Don't want to touch dependent processes that are hosting activities. 2420 return index; 2421 } 2422 2423 int lrui = mLruProcesses.lastIndexOf(app); 2424 if (lrui < 0) { 2425 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2426 + what + " " + obj + " from " + srcApp); 2427 return index; 2428 } 2429 2430 if (lrui >= index) { 2431 // Don't want to cause this to move dependent processes *back* in the 2432 // list as if they were less frequently used. 2433 return index; 2434 } 2435 2436 if (lrui >= mLruProcessActivityStart) { 2437 // Don't want to touch dependent processes that are hosting activities. 2438 return index; 2439 } 2440 2441 mLruProcesses.remove(lrui); 2442 if (index > 0) { 2443 index--; 2444 } 2445 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2446 + " in LRU list: " + app); 2447 mLruProcesses.add(index, app); 2448 return index; 2449 } 2450 2451 final void removeLruProcessLocked(ProcessRecord app) { 2452 int lrui = mLruProcesses.lastIndexOf(app); 2453 if (lrui >= 0) { 2454 if (lrui <= mLruProcessActivityStart) { 2455 mLruProcessActivityStart--; 2456 } 2457 if (lrui <= mLruProcessServiceStart) { 2458 mLruProcessServiceStart--; 2459 } 2460 mLruProcesses.remove(lrui); 2461 } 2462 } 2463 2464 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2465 ProcessRecord client) { 2466 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2467 || app.treatLikeActivity; 2468 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2469 if (!activityChange && hasActivity) { 2470 // The process has activities, so we are only allowing activity-based adjustments 2471 // to move it. It should be kept in the front of the list with other 2472 // processes that have activities, and we don't want those to change their 2473 // order except due to activity operations. 2474 return; 2475 } 2476 2477 mLruSeq++; 2478 final long now = SystemClock.uptimeMillis(); 2479 app.lastActivityTime = now; 2480 2481 // First a quick reject: if the app is already at the position we will 2482 // put it, then there is nothing to do. 2483 if (hasActivity) { 2484 final int N = mLruProcesses.size(); 2485 if (N > 0 && mLruProcesses.get(N-1) == app) { 2486 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2487 return; 2488 } 2489 } else { 2490 if (mLruProcessServiceStart > 0 2491 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2492 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2493 return; 2494 } 2495 } 2496 2497 int lrui = mLruProcesses.lastIndexOf(app); 2498 2499 if (app.persistent && lrui >= 0) { 2500 // We don't care about the position of persistent processes, as long as 2501 // they are in the list. 2502 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2503 return; 2504 } 2505 2506 /* In progress: compute new position first, so we can avoid doing work 2507 if the process is not actually going to move. Not yet working. 2508 int addIndex; 2509 int nextIndex; 2510 boolean inActivity = false, inService = false; 2511 if (hasActivity) { 2512 // Process has activities, put it at the very tipsy-top. 2513 addIndex = mLruProcesses.size(); 2514 nextIndex = mLruProcessServiceStart; 2515 inActivity = true; 2516 } else if (hasService) { 2517 // Process has services, put it at the top of the service list. 2518 addIndex = mLruProcessActivityStart; 2519 nextIndex = mLruProcessServiceStart; 2520 inActivity = true; 2521 inService = true; 2522 } else { 2523 // Process not otherwise of interest, it goes to the top of the non-service area. 2524 addIndex = mLruProcessServiceStart; 2525 if (client != null) { 2526 int clientIndex = mLruProcesses.lastIndexOf(client); 2527 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2528 + app); 2529 if (clientIndex >= 0 && addIndex > clientIndex) { 2530 addIndex = clientIndex; 2531 } 2532 } 2533 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2534 } 2535 2536 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2537 + mLruProcessActivityStart + "): " + app); 2538 */ 2539 2540 if (lrui >= 0) { 2541 if (lrui < mLruProcessActivityStart) { 2542 mLruProcessActivityStart--; 2543 } 2544 if (lrui < mLruProcessServiceStart) { 2545 mLruProcessServiceStart--; 2546 } 2547 /* 2548 if (addIndex > lrui) { 2549 addIndex--; 2550 } 2551 if (nextIndex > lrui) { 2552 nextIndex--; 2553 } 2554 */ 2555 mLruProcesses.remove(lrui); 2556 } 2557 2558 /* 2559 mLruProcesses.add(addIndex, app); 2560 if (inActivity) { 2561 mLruProcessActivityStart++; 2562 } 2563 if (inService) { 2564 mLruProcessActivityStart++; 2565 } 2566 */ 2567 2568 int nextIndex; 2569 if (hasActivity) { 2570 final int N = mLruProcesses.size(); 2571 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2572 // Process doesn't have activities, but has clients with 2573 // activities... move it up, but one below the top (the top 2574 // should always have a real activity). 2575 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2576 mLruProcesses.add(N-1, app); 2577 // To keep it from spamming the LRU list (by making a bunch of clients), 2578 // we will push down any other entries owned by the app. 2579 final int uid = app.info.uid; 2580 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2581 ProcessRecord subProc = mLruProcesses.get(i); 2582 if (subProc.info.uid == uid) { 2583 // We want to push this one down the list. If the process after 2584 // it is for the same uid, however, don't do so, because we don't 2585 // want them internally to be re-ordered. 2586 if (mLruProcesses.get(i-1).info.uid != uid) { 2587 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2588 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2589 ProcessRecord tmp = mLruProcesses.get(i); 2590 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2591 mLruProcesses.set(i-1, tmp); 2592 i--; 2593 } 2594 } else { 2595 // A gap, we can stop here. 2596 break; 2597 } 2598 } 2599 } else { 2600 // Process has activities, put it at the very tipsy-top. 2601 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2602 mLruProcesses.add(app); 2603 } 2604 nextIndex = mLruProcessServiceStart; 2605 } else if (hasService) { 2606 // Process has services, put it at the top of the service list. 2607 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2608 mLruProcesses.add(mLruProcessActivityStart, app); 2609 nextIndex = mLruProcessServiceStart; 2610 mLruProcessActivityStart++; 2611 } else { 2612 // Process not otherwise of interest, it goes to the top of the non-service area. 2613 int index = mLruProcessServiceStart; 2614 if (client != null) { 2615 // If there is a client, don't allow the process to be moved up higher 2616 // in the list than that client. 2617 int clientIndex = mLruProcesses.lastIndexOf(client); 2618 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2619 + " when updating " + app); 2620 if (clientIndex <= lrui) { 2621 // Don't allow the client index restriction to push it down farther in the 2622 // list than it already is. 2623 clientIndex = lrui; 2624 } 2625 if (clientIndex >= 0 && index > clientIndex) { 2626 index = clientIndex; 2627 } 2628 } 2629 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2630 mLruProcesses.add(index, app); 2631 nextIndex = index-1; 2632 mLruProcessActivityStart++; 2633 mLruProcessServiceStart++; 2634 } 2635 2636 // If the app is currently using a content provider or service, 2637 // bump those processes as well. 2638 for (int j=app.connections.size()-1; j>=0; j--) { 2639 ConnectionRecord cr = app.connections.valueAt(j); 2640 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2641 && cr.binding.service.app != null 2642 && cr.binding.service.app.lruSeq != mLruSeq 2643 && !cr.binding.service.app.persistent) { 2644 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2645 "service connection", cr, app); 2646 } 2647 } 2648 for (int j=app.conProviders.size()-1; j>=0; j--) { 2649 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2650 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2651 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2652 "provider reference", cpr, app); 2653 } 2654 } 2655 } 2656 2657 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2658 if (uid == Process.SYSTEM_UID) { 2659 // The system gets to run in any process. If there are multiple 2660 // processes with the same uid, just pick the first (this 2661 // should never happen). 2662 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2663 if (procs == null) return null; 2664 final int N = procs.size(); 2665 for (int i = 0; i < N; i++) { 2666 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2667 } 2668 } 2669 ProcessRecord proc = mProcessNames.get(processName, uid); 2670 if (false && proc != null && !keepIfLarge 2671 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2672 && proc.lastCachedPss >= 4000) { 2673 // Turn this condition on to cause killing to happen regularly, for testing. 2674 if (proc.baseProcessTracker != null) { 2675 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2676 } 2677 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2678 + "k from cached"); 2679 } else if (proc != null && !keepIfLarge 2680 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2681 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2682 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2683 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2684 if (proc.baseProcessTracker != null) { 2685 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2686 } 2687 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2688 + "k from cached"); 2689 } 2690 } 2691 return proc; 2692 } 2693 2694 void ensurePackageDexOpt(String packageName) { 2695 IPackageManager pm = AppGlobals.getPackageManager(); 2696 try { 2697 if (pm.performDexOpt(packageName)) { 2698 mDidDexOpt = true; 2699 } 2700 } catch (RemoteException e) { 2701 } 2702 } 2703 2704 boolean isNextTransitionForward() { 2705 int transit = mWindowManager.getPendingAppTransition(); 2706 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2707 || transit == AppTransition.TRANSIT_TASK_OPEN 2708 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2709 } 2710 2711 final ProcessRecord startProcessLocked(String processName, 2712 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2713 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2714 boolean isolated, boolean keepIfLarge) { 2715 ProcessRecord app; 2716 if (!isolated) { 2717 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2718 } else { 2719 // If this is an isolated process, it can't re-use an existing process. 2720 app = null; 2721 } 2722 // We don't have to do anything more if: 2723 // (1) There is an existing application record; and 2724 // (2) The caller doesn't think it is dead, OR there is no thread 2725 // object attached to it so we know it couldn't have crashed; and 2726 // (3) There is a pid assigned to it, so it is either starting or 2727 // already running. 2728 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2729 + " app=" + app + " knownToBeDead=" + knownToBeDead 2730 + " thread=" + (app != null ? app.thread : null) 2731 + " pid=" + (app != null ? app.pid : -1)); 2732 if (app != null && app.pid > 0) { 2733 if (!knownToBeDead || app.thread == null) { 2734 // We already have the app running, or are waiting for it to 2735 // come up (we have a pid but not yet its thread), so keep it. 2736 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2737 // If this is a new package in the process, add the package to the list 2738 app.addPackage(info.packageName, mProcessStats); 2739 return app; 2740 } 2741 2742 // An application record is attached to a previous process, 2743 // clean it up now. 2744 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2745 handleAppDiedLocked(app, true, true); 2746 } 2747 2748 String hostingNameStr = hostingName != null 2749 ? hostingName.flattenToShortString() : null; 2750 2751 if (!isolated) { 2752 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2753 // If we are in the background, then check to see if this process 2754 // is bad. If so, we will just silently fail. 2755 if (mBadProcesses.get(info.processName, info.uid) != null) { 2756 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2757 + "/" + info.processName); 2758 return null; 2759 } 2760 } else { 2761 // When the user is explicitly starting a process, then clear its 2762 // crash count so that we won't make it bad until they see at 2763 // least one crash dialog again, and make the process good again 2764 // if it had been bad. 2765 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2766 + "/" + info.processName); 2767 mProcessCrashTimes.remove(info.processName, info.uid); 2768 if (mBadProcesses.get(info.processName, info.uid) != null) { 2769 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2770 UserHandle.getUserId(info.uid), info.uid, 2771 info.processName); 2772 mBadProcesses.remove(info.processName, info.uid); 2773 if (app != null) { 2774 app.bad = false; 2775 } 2776 } 2777 } 2778 } 2779 2780 if (app == null) { 2781 app = newProcessRecordLocked(info, processName, isolated); 2782 if (app == null) { 2783 Slog.w(TAG, "Failed making new process record for " 2784 + processName + "/" + info.uid + " isolated=" + isolated); 2785 return null; 2786 } 2787 mProcessNames.put(processName, app.uid, app); 2788 if (isolated) { 2789 mIsolatedProcesses.put(app.uid, app); 2790 } 2791 } else { 2792 // If this is a new package in the process, add the package to the list 2793 app.addPackage(info.packageName, mProcessStats); 2794 } 2795 2796 // If the system is not ready yet, then hold off on starting this 2797 // process until it is. 2798 if (!mProcessesReady 2799 && !isAllowedWhileBooting(info) 2800 && !allowWhileBooting) { 2801 if (!mProcessesOnHold.contains(app)) { 2802 mProcessesOnHold.add(app); 2803 } 2804 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2805 return app; 2806 } 2807 2808 startProcessLocked(app, hostingType, hostingNameStr); 2809 return (app.pid != 0) ? app : null; 2810 } 2811 2812 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2813 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2814 } 2815 2816 private final void startProcessLocked(ProcessRecord app, 2817 String hostingType, String hostingNameStr) { 2818 if (app.pid > 0 && app.pid != MY_PID) { 2819 synchronized (mPidsSelfLocked) { 2820 mPidsSelfLocked.remove(app.pid); 2821 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2822 } 2823 app.setPid(0); 2824 } 2825 2826 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2827 "startProcessLocked removing on hold: " + app); 2828 mProcessesOnHold.remove(app); 2829 2830 updateCpuStats(); 2831 2832 try { 2833 int uid = app.uid; 2834 2835 int[] gids = null; 2836 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2837 if (!app.isolated) { 2838 int[] permGids = null; 2839 try { 2840 final PackageManager pm = mContext.getPackageManager(); 2841 permGids = pm.getPackageGids(app.info.packageName); 2842 2843 if (Environment.isExternalStorageEmulated()) { 2844 if (pm.checkPermission( 2845 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2846 app.info.packageName) == PERMISSION_GRANTED) { 2847 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2848 } else { 2849 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2850 } 2851 } 2852 } catch (PackageManager.NameNotFoundException e) { 2853 Slog.w(TAG, "Unable to retrieve gids", e); 2854 } 2855 2856 /* 2857 * Add shared application GID so applications can share some 2858 * resources like shared libraries 2859 */ 2860 if (permGids == null) { 2861 gids = new int[1]; 2862 } else { 2863 gids = new int[permGids.length + 1]; 2864 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2865 } 2866 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2867 } 2868 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2869 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2870 && mTopComponent != null 2871 && app.processName.equals(mTopComponent.getPackageName())) { 2872 uid = 0; 2873 } 2874 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2875 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2876 uid = 0; 2877 } 2878 } 2879 int debugFlags = 0; 2880 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2881 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2882 // Also turn on CheckJNI for debuggable apps. It's quite 2883 // awkward to turn on otherwise. 2884 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2885 } 2886 // Run the app in safe mode if its manifest requests so or the 2887 // system is booted in safe mode. 2888 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2889 mSafeMode == true) { 2890 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2891 } 2892 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2893 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2894 } 2895 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2896 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2897 } 2898 if ("1".equals(SystemProperties.get("debug.assert"))) { 2899 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2900 } 2901 2902 String requiredAbi = app.info.requiredCpuAbi; 2903 if (requiredAbi == null) { 2904 requiredAbi = Build.SUPPORTED_ABIS[0]; 2905 } 2906 2907 // Start the process. It will either succeed and return a result containing 2908 // the PID of the new process, or else throw a RuntimeException. 2909 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2910 app.processName, uid, uid, gids, debugFlags, mountExternal, 2911 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2912 2913 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2914 synchronized (bs) { 2915 if (bs.isOnBattery()) { 2916 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2917 } 2918 } 2919 2920 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2921 UserHandle.getUserId(uid), startResult.pid, uid, 2922 app.processName, hostingType, 2923 hostingNameStr != null ? hostingNameStr : ""); 2924 2925 if (app.persistent) { 2926 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2927 } 2928 2929 StringBuilder buf = mStringBuilder; 2930 buf.setLength(0); 2931 buf.append("Start proc "); 2932 buf.append(app.processName); 2933 buf.append(" for "); 2934 buf.append(hostingType); 2935 if (hostingNameStr != null) { 2936 buf.append(" "); 2937 buf.append(hostingNameStr); 2938 } 2939 buf.append(": pid="); 2940 buf.append(startResult.pid); 2941 buf.append(" uid="); 2942 buf.append(uid); 2943 buf.append(" gids={"); 2944 if (gids != null) { 2945 for (int gi=0; gi<gids.length; gi++) { 2946 if (gi != 0) buf.append(", "); 2947 buf.append(gids[gi]); 2948 2949 } 2950 } 2951 buf.append("}"); 2952 Slog.i(TAG, buf.toString()); 2953 app.setPid(startResult.pid); 2954 app.usingWrapper = startResult.usingWrapper; 2955 app.removed = false; 2956 synchronized (mPidsSelfLocked) { 2957 this.mPidsSelfLocked.put(startResult.pid, app); 2958 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2959 msg.obj = app; 2960 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2961 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2962 } 2963 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2964 app.processName, app.info.uid); 2965 if (app.isolated) { 2966 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2967 } 2968 } catch (RuntimeException e) { 2969 // XXX do better error recovery. 2970 app.setPid(0); 2971 Slog.e(TAG, "Failure starting process " + app.processName, e); 2972 } 2973 } 2974 2975 void updateUsageStats(ActivityRecord component, boolean resumed) { 2976 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2977 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2978 if (resumed) { 2979 mUsageStatsService.noteResumeComponent(component.realActivity); 2980 synchronized (stats) { 2981 stats.noteActivityResumedLocked(component.app.uid); 2982 } 2983 } else { 2984 mUsageStatsService.notePauseComponent(component.realActivity); 2985 synchronized (stats) { 2986 stats.noteActivityPausedLocked(component.app.uid); 2987 } 2988 } 2989 } 2990 2991 Intent getHomeIntent() { 2992 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2993 intent.setComponent(mTopComponent); 2994 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2995 intent.addCategory(Intent.CATEGORY_HOME); 2996 } 2997 return intent; 2998 } 2999 3000 boolean startHomeActivityLocked(int userId) { 3001 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3002 && mTopAction == null) { 3003 // We are running in factory test mode, but unable to find 3004 // the factory test app, so just sit around displaying the 3005 // error message and don't try to start anything. 3006 return false; 3007 } 3008 Intent intent = getHomeIntent(); 3009 ActivityInfo aInfo = 3010 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3011 if (aInfo != null) { 3012 intent.setComponent(new ComponentName( 3013 aInfo.applicationInfo.packageName, aInfo.name)); 3014 // Don't do this if the home app is currently being 3015 // instrumented. 3016 aInfo = new ActivityInfo(aInfo); 3017 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3018 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3019 aInfo.applicationInfo.uid, true); 3020 if (app == null || app.instrumentationClass == null) { 3021 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3022 mStackSupervisor.startHomeActivity(intent, aInfo); 3023 } 3024 } 3025 3026 return true; 3027 } 3028 3029 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3030 ActivityInfo ai = null; 3031 ComponentName comp = intent.getComponent(); 3032 try { 3033 if (comp != null) { 3034 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3035 } else { 3036 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3037 intent, 3038 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3039 flags, userId); 3040 3041 if (info != null) { 3042 ai = info.activityInfo; 3043 } 3044 } 3045 } catch (RemoteException e) { 3046 // ignore 3047 } 3048 3049 return ai; 3050 } 3051 3052 /** 3053 * Starts the "new version setup screen" if appropriate. 3054 */ 3055 void startSetupActivityLocked() { 3056 // Only do this once per boot. 3057 if (mCheckedForSetup) { 3058 return; 3059 } 3060 3061 // We will show this screen if the current one is a different 3062 // version than the last one shown, and we are not running in 3063 // low-level factory test mode. 3064 final ContentResolver resolver = mContext.getContentResolver(); 3065 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3066 Settings.Global.getInt(resolver, 3067 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3068 mCheckedForSetup = true; 3069 3070 // See if we should be showing the platform update setup UI. 3071 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3072 List<ResolveInfo> ris = mContext.getPackageManager() 3073 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3074 3075 // We don't allow third party apps to replace this. 3076 ResolveInfo ri = null; 3077 for (int i=0; ris != null && i<ris.size(); i++) { 3078 if ((ris.get(i).activityInfo.applicationInfo.flags 3079 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3080 ri = ris.get(i); 3081 break; 3082 } 3083 } 3084 3085 if (ri != null) { 3086 String vers = ri.activityInfo.metaData != null 3087 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3088 : null; 3089 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3090 vers = ri.activityInfo.applicationInfo.metaData.getString( 3091 Intent.METADATA_SETUP_VERSION); 3092 } 3093 String lastVers = Settings.Secure.getString( 3094 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3095 if (vers != null && !vers.equals(lastVers)) { 3096 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3097 intent.setComponent(new ComponentName( 3098 ri.activityInfo.packageName, ri.activityInfo.name)); 3099 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3100 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3101 } 3102 } 3103 } 3104 } 3105 3106 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3107 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3108 } 3109 3110 void enforceNotIsolatedCaller(String caller) { 3111 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3112 throw new SecurityException("Isolated process not allowed to call " + caller); 3113 } 3114 } 3115 3116 @Override 3117 public int getFrontActivityScreenCompatMode() { 3118 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3119 synchronized (this) { 3120 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3121 } 3122 } 3123 3124 @Override 3125 public void setFrontActivityScreenCompatMode(int mode) { 3126 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3127 "setFrontActivityScreenCompatMode"); 3128 synchronized (this) { 3129 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3130 } 3131 } 3132 3133 @Override 3134 public int getPackageScreenCompatMode(String packageName) { 3135 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3136 synchronized (this) { 3137 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3138 } 3139 } 3140 3141 @Override 3142 public void setPackageScreenCompatMode(String packageName, int mode) { 3143 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3144 "setPackageScreenCompatMode"); 3145 synchronized (this) { 3146 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3147 } 3148 } 3149 3150 @Override 3151 public boolean getPackageAskScreenCompat(String packageName) { 3152 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3153 synchronized (this) { 3154 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3155 } 3156 } 3157 3158 @Override 3159 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3160 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3161 "setPackageAskScreenCompat"); 3162 synchronized (this) { 3163 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3164 } 3165 } 3166 3167 private void dispatchProcessesChanged() { 3168 int N; 3169 synchronized (this) { 3170 N = mPendingProcessChanges.size(); 3171 if (mActiveProcessChanges.length < N) { 3172 mActiveProcessChanges = new ProcessChangeItem[N]; 3173 } 3174 mPendingProcessChanges.toArray(mActiveProcessChanges); 3175 mAvailProcessChanges.addAll(mPendingProcessChanges); 3176 mPendingProcessChanges.clear(); 3177 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3178 } 3179 3180 int i = mProcessObservers.beginBroadcast(); 3181 while (i > 0) { 3182 i--; 3183 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3184 if (observer != null) { 3185 try { 3186 for (int j=0; j<N; j++) { 3187 ProcessChangeItem item = mActiveProcessChanges[j]; 3188 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3189 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3190 + item.pid + " uid=" + item.uid + ": " 3191 + item.foregroundActivities); 3192 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3193 item.foregroundActivities); 3194 } 3195 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3196 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3197 + item.pid + " uid=" + item.uid + ": " + item.processState); 3198 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3199 } 3200 } 3201 } catch (RemoteException e) { 3202 } 3203 } 3204 } 3205 mProcessObservers.finishBroadcast(); 3206 } 3207 3208 private void dispatchProcessDied(int pid, int uid) { 3209 int i = mProcessObservers.beginBroadcast(); 3210 while (i > 0) { 3211 i--; 3212 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3213 if (observer != null) { 3214 try { 3215 observer.onProcessDied(pid, uid); 3216 } catch (RemoteException e) { 3217 } 3218 } 3219 } 3220 mProcessObservers.finishBroadcast(); 3221 } 3222 3223 final void doPendingActivityLaunchesLocked(boolean doResume) { 3224 final int N = mPendingActivityLaunches.size(); 3225 if (N <= 0) { 3226 return; 3227 } 3228 for (int i=0; i<N; i++) { 3229 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3230 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3231 doResume && i == (N-1), null); 3232 } 3233 mPendingActivityLaunches.clear(); 3234 } 3235 3236 @Override 3237 public final int startActivity(IApplicationThread caller, String callingPackage, 3238 Intent intent, String resolvedType, IBinder resultTo, 3239 String resultWho, int requestCode, int startFlags, 3240 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3241 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3242 resultWho, requestCode, 3243 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3244 } 3245 3246 @Override 3247 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3248 Intent intent, String resolvedType, IBinder resultTo, 3249 String resultWho, int requestCode, int startFlags, 3250 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3251 enforceNotIsolatedCaller("startActivity"); 3252 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3253 false, true, "startActivity", null); 3254 // TODO: Switch to user app stacks here. 3255 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3256 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3257 null, null, options, userId, null); 3258 } 3259 3260 @Override 3261 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3262 Intent intent, String resolvedType, IBinder resultTo, 3263 String resultWho, int requestCode, int startFlags, String profileFile, 3264 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3265 enforceNotIsolatedCaller("startActivityAndWait"); 3266 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3267 false, true, "startActivityAndWait", null); 3268 WaitResult res = new WaitResult(); 3269 // TODO: Switch to user app stacks here. 3270 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3271 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3272 res, null, options, UserHandle.getCallingUserId(), null); 3273 return res; 3274 } 3275 3276 @Override 3277 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3278 Intent intent, String resolvedType, IBinder resultTo, 3279 String resultWho, int requestCode, int startFlags, Configuration config, 3280 Bundle options, int userId) { 3281 enforceNotIsolatedCaller("startActivityWithConfig"); 3282 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3283 false, true, "startActivityWithConfig", null); 3284 // TODO: Switch to user app stacks here. 3285 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3286 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3287 null, null, null, config, options, userId, null); 3288 return ret; 3289 } 3290 3291 @Override 3292 public int startActivityIntentSender(IApplicationThread caller, 3293 IntentSender intent, Intent fillInIntent, String resolvedType, 3294 IBinder resultTo, String resultWho, int requestCode, 3295 int flagsMask, int flagsValues, Bundle options) { 3296 enforceNotIsolatedCaller("startActivityIntentSender"); 3297 // Refuse possible leaked file descriptors 3298 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3299 throw new IllegalArgumentException("File descriptors passed in Intent"); 3300 } 3301 3302 IIntentSender sender = intent.getTarget(); 3303 if (!(sender instanceof PendingIntentRecord)) { 3304 throw new IllegalArgumentException("Bad PendingIntent object"); 3305 } 3306 3307 PendingIntentRecord pir = (PendingIntentRecord)sender; 3308 3309 synchronized (this) { 3310 // If this is coming from the currently resumed activity, it is 3311 // effectively saying that app switches are allowed at this point. 3312 final ActivityStack stack = getFocusedStack(); 3313 if (stack.mResumedActivity != null && 3314 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3315 mAppSwitchesAllowedTime = 0; 3316 } 3317 } 3318 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3319 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3320 return ret; 3321 } 3322 3323 @Override 3324 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3325 Intent intent, String resolvedType, IVoiceInteractionSession session, 3326 IVoiceInteractor interactor, int startFlags, String profileFile, 3327 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3328 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3329 != PackageManager.PERMISSION_GRANTED) { 3330 String msg = "Permission Denial: startVoiceActivity() from pid=" 3331 + Binder.getCallingPid() 3332 + ", uid=" + Binder.getCallingUid() 3333 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3334 Slog.w(TAG, msg); 3335 throw new SecurityException(msg); 3336 } 3337 if (session == null || interactor == null) { 3338 throw new NullPointerException("null session or interactor"); 3339 } 3340 userId = handleIncomingUser(callingPid, callingUid, userId, 3341 false, true, "startVoiceActivity", null); 3342 // TODO: Switch to user app stacks here. 3343 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3344 resolvedType, session, interactor, null, null, 0, startFlags, 3345 profileFile, profileFd, null, null, options, userId, null); 3346 } 3347 3348 @Override 3349 public boolean startNextMatchingActivity(IBinder callingActivity, 3350 Intent intent, Bundle options) { 3351 // Refuse possible leaked file descriptors 3352 if (intent != null && intent.hasFileDescriptors() == true) { 3353 throw new IllegalArgumentException("File descriptors passed in Intent"); 3354 } 3355 3356 synchronized (this) { 3357 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3358 if (r == null) { 3359 ActivityOptions.abort(options); 3360 return false; 3361 } 3362 if (r.app == null || r.app.thread == null) { 3363 // The caller is not running... d'oh! 3364 ActivityOptions.abort(options); 3365 return false; 3366 } 3367 intent = new Intent(intent); 3368 // The caller is not allowed to change the data. 3369 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3370 // And we are resetting to find the next component... 3371 intent.setComponent(null); 3372 3373 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3374 3375 ActivityInfo aInfo = null; 3376 try { 3377 List<ResolveInfo> resolves = 3378 AppGlobals.getPackageManager().queryIntentActivities( 3379 intent, r.resolvedType, 3380 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3381 UserHandle.getCallingUserId()); 3382 3383 // Look for the original activity in the list... 3384 final int N = resolves != null ? resolves.size() : 0; 3385 for (int i=0; i<N; i++) { 3386 ResolveInfo rInfo = resolves.get(i); 3387 if (rInfo.activityInfo.packageName.equals(r.packageName) 3388 && rInfo.activityInfo.name.equals(r.info.name)) { 3389 // We found the current one... the next matching is 3390 // after it. 3391 i++; 3392 if (i<N) { 3393 aInfo = resolves.get(i).activityInfo; 3394 } 3395 if (debug) { 3396 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3397 + "/" + r.info.name); 3398 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3399 + "/" + aInfo.name); 3400 } 3401 break; 3402 } 3403 } 3404 } catch (RemoteException e) { 3405 } 3406 3407 if (aInfo == null) { 3408 // Nobody who is next! 3409 ActivityOptions.abort(options); 3410 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3411 return false; 3412 } 3413 3414 intent.setComponent(new ComponentName( 3415 aInfo.applicationInfo.packageName, aInfo.name)); 3416 intent.setFlags(intent.getFlags()&~( 3417 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3418 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3419 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3420 Intent.FLAG_ACTIVITY_NEW_TASK)); 3421 3422 // Okay now we need to start the new activity, replacing the 3423 // currently running activity. This is a little tricky because 3424 // we want to start the new one as if the current one is finished, 3425 // but not finish the current one first so that there is no flicker. 3426 // And thus... 3427 final boolean wasFinishing = r.finishing; 3428 r.finishing = true; 3429 3430 // Propagate reply information over to the new activity. 3431 final ActivityRecord resultTo = r.resultTo; 3432 final String resultWho = r.resultWho; 3433 final int requestCode = r.requestCode; 3434 r.resultTo = null; 3435 if (resultTo != null) { 3436 resultTo.removeResultsLocked(r, resultWho, requestCode); 3437 } 3438 3439 final long origId = Binder.clearCallingIdentity(); 3440 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3441 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3442 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3443 options, false, null, null); 3444 Binder.restoreCallingIdentity(origId); 3445 3446 r.finishing = wasFinishing; 3447 if (res != ActivityManager.START_SUCCESS) { 3448 return false; 3449 } 3450 return true; 3451 } 3452 } 3453 3454 final int startActivityInPackage(int uid, String callingPackage, 3455 Intent intent, String resolvedType, IBinder resultTo, 3456 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3457 IActivityContainer container) { 3458 3459 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3460 false, true, "startActivityInPackage", null); 3461 3462 // TODO: Switch to user app stacks here. 3463 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3464 null, null, resultTo, resultWho, requestCode, startFlags, 3465 null, null, null, null, options, userId, container); 3466 return ret; 3467 } 3468 3469 @Override 3470 public final int startActivities(IApplicationThread caller, String callingPackage, 3471 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3472 int userId) { 3473 enforceNotIsolatedCaller("startActivities"); 3474 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3475 false, true, "startActivity", null); 3476 // TODO: Switch to user app stacks here. 3477 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3478 resolvedTypes, resultTo, options, userId); 3479 return ret; 3480 } 3481 3482 final int startActivitiesInPackage(int uid, String callingPackage, 3483 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3484 Bundle options, int userId) { 3485 3486 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3487 false, true, "startActivityInPackage", null); 3488 // TODO: Switch to user app stacks here. 3489 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3490 resultTo, options, userId); 3491 return ret; 3492 } 3493 3494 final void addRecentTaskLocked(TaskRecord task) { 3495 int N = mRecentTasks.size(); 3496 // Quick case: check if the top-most recent task is the same. 3497 if (N > 0 && mRecentTasks.get(0) == task) { 3498 return; 3499 } 3500 // Another quick case: never add voice sessions. 3501 if (task.voiceSession != null) { 3502 return; 3503 } 3504 // Remove any existing entries that are the same kind of task. 3505 final Intent intent = task.intent; 3506 final boolean document = intent != null && intent.isDocument(); 3507 for (int i=0; i<N; i++) { 3508 TaskRecord tr = mRecentTasks.get(i); 3509 if (task != tr) { 3510 if (task.userId != tr.userId) { 3511 continue; 3512 } 3513 final Intent trIntent = tr.intent; 3514 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3515 (intent == null || !intent.filterEquals(trIntent))) { 3516 continue; 3517 } 3518 if (document || trIntent != null && trIntent.isDocument()) { 3519 // Document tasks do not match other tasks. 3520 continue; 3521 } 3522 } 3523 3524 // Either task and tr are the same or, their affinities match or their intents match 3525 // and neither of them is a document. 3526 tr.disposeThumbnail(); 3527 mRecentTasks.remove(i); 3528 i--; 3529 N--; 3530 if (task.intent == null) { 3531 // If the new recent task we are adding is not fully 3532 // specified, then replace it with the existing recent task. 3533 task = tr; 3534 } 3535 } 3536 if (N >= MAX_RECENT_TASKS) { 3537 mRecentTasks.remove(N-1).disposeThumbnail(); 3538 } 3539 mRecentTasks.add(0, task); 3540 } 3541 3542 @Override 3543 public void reportActivityFullyDrawn(IBinder token) { 3544 synchronized (this) { 3545 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3546 if (r == null) { 3547 return; 3548 } 3549 r.reportFullyDrawnLocked(); 3550 } 3551 } 3552 3553 @Override 3554 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3555 synchronized (this) { 3556 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3557 if (r == null) { 3558 return; 3559 } 3560 final long origId = Binder.clearCallingIdentity(); 3561 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3562 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3563 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3564 if (config != null) { 3565 r.frozenBeforeDestroy = true; 3566 if (!updateConfigurationLocked(config, r, false, false)) { 3567 mStackSupervisor.resumeTopActivitiesLocked(); 3568 } 3569 } 3570 Binder.restoreCallingIdentity(origId); 3571 } 3572 } 3573 3574 @Override 3575 public int getRequestedOrientation(IBinder token) { 3576 synchronized (this) { 3577 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3578 if (r == null) { 3579 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3580 } 3581 return mWindowManager.getAppOrientation(r.appToken); 3582 } 3583 } 3584 3585 /** 3586 * This is the internal entry point for handling Activity.finish(). 3587 * 3588 * @param token The Binder token referencing the Activity we want to finish. 3589 * @param resultCode Result code, if any, from this Activity. 3590 * @param resultData Result data (Intent), if any, from this Activity. 3591 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3592 * the root Activity in the task. 3593 * 3594 * @return Returns true if the activity successfully finished, or false if it is still running. 3595 */ 3596 @Override 3597 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3598 boolean finishTask) { 3599 // Refuse possible leaked file descriptors 3600 if (resultData != null && resultData.hasFileDescriptors() == true) { 3601 throw new IllegalArgumentException("File descriptors passed in Intent"); 3602 } 3603 3604 synchronized(this) { 3605 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3606 if (r == null) { 3607 return true; 3608 } 3609 // Keep track of the root activity of the task before we finish it 3610 TaskRecord tr = r.task; 3611 ActivityRecord rootR = tr.getRootActivity(); 3612 if (mController != null) { 3613 // Find the first activity that is not finishing. 3614 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3615 if (next != null) { 3616 // ask watcher if this is allowed 3617 boolean resumeOK = true; 3618 try { 3619 resumeOK = mController.activityResuming(next.packageName); 3620 } catch (RemoteException e) { 3621 mController = null; 3622 Watchdog.getInstance().setActivityController(null); 3623 } 3624 3625 if (!resumeOK) { 3626 return false; 3627 } 3628 } 3629 } 3630 final long origId = Binder.clearCallingIdentity(); 3631 try { 3632 boolean res; 3633 if (finishTask && r == rootR) { 3634 // If requested, remove the task that is associated to this activity only if it 3635 // was the root activity in the task. The result code and data is ignored because 3636 // we don't support returning them across task boundaries. 3637 res = removeTaskByIdLocked(tr.taskId, 0); 3638 } else { 3639 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3640 resultData, "app-request", true); 3641 } 3642 return res; 3643 } finally { 3644 Binder.restoreCallingIdentity(origId); 3645 } 3646 } 3647 } 3648 3649 @Override 3650 public final void finishHeavyWeightApp() { 3651 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3652 != PackageManager.PERMISSION_GRANTED) { 3653 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3654 + Binder.getCallingPid() 3655 + ", uid=" + Binder.getCallingUid() 3656 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3657 Slog.w(TAG, msg); 3658 throw new SecurityException(msg); 3659 } 3660 3661 synchronized(this) { 3662 if (mHeavyWeightProcess == null) { 3663 return; 3664 } 3665 3666 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3667 mHeavyWeightProcess.activities); 3668 for (int i=0; i<activities.size(); i++) { 3669 ActivityRecord r = activities.get(i); 3670 if (!r.finishing) { 3671 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3672 null, "finish-heavy", true); 3673 } 3674 } 3675 3676 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3677 mHeavyWeightProcess.userId, 0)); 3678 mHeavyWeightProcess = null; 3679 } 3680 } 3681 3682 @Override 3683 public void crashApplication(int uid, int initialPid, String packageName, 3684 String message) { 3685 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3686 != PackageManager.PERMISSION_GRANTED) { 3687 String msg = "Permission Denial: crashApplication() from pid=" 3688 + Binder.getCallingPid() 3689 + ", uid=" + Binder.getCallingUid() 3690 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3691 Slog.w(TAG, msg); 3692 throw new SecurityException(msg); 3693 } 3694 3695 synchronized(this) { 3696 ProcessRecord proc = null; 3697 3698 // Figure out which process to kill. We don't trust that initialPid 3699 // still has any relation to current pids, so must scan through the 3700 // list. 3701 synchronized (mPidsSelfLocked) { 3702 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3703 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3704 if (p.uid != uid) { 3705 continue; 3706 } 3707 if (p.pid == initialPid) { 3708 proc = p; 3709 break; 3710 } 3711 if (p.pkgList.containsKey(packageName)) { 3712 proc = p; 3713 } 3714 } 3715 } 3716 3717 if (proc == null) { 3718 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3719 + " initialPid=" + initialPid 3720 + " packageName=" + packageName); 3721 return; 3722 } 3723 3724 if (proc.thread != null) { 3725 if (proc.pid == Process.myPid()) { 3726 Log.w(TAG, "crashApplication: trying to crash self!"); 3727 return; 3728 } 3729 long ident = Binder.clearCallingIdentity(); 3730 try { 3731 proc.thread.scheduleCrash(message); 3732 } catch (RemoteException e) { 3733 } 3734 Binder.restoreCallingIdentity(ident); 3735 } 3736 } 3737 } 3738 3739 @Override 3740 public final void finishSubActivity(IBinder token, String resultWho, 3741 int requestCode) { 3742 synchronized(this) { 3743 final long origId = Binder.clearCallingIdentity(); 3744 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3745 if (r != null) { 3746 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3747 } 3748 Binder.restoreCallingIdentity(origId); 3749 } 3750 } 3751 3752 @Override 3753 public boolean finishActivityAffinity(IBinder token) { 3754 synchronized(this) { 3755 final long origId = Binder.clearCallingIdentity(); 3756 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3757 boolean res = false; 3758 if (r != null) { 3759 res = r.task.stack.finishActivityAffinityLocked(r); 3760 } 3761 Binder.restoreCallingIdentity(origId); 3762 return res; 3763 } 3764 } 3765 3766 @Override 3767 public boolean willActivityBeVisible(IBinder token) { 3768 synchronized(this) { 3769 ActivityStack stack = ActivityRecord.getStackLocked(token); 3770 if (stack != null) { 3771 return stack.willActivityBeVisibleLocked(token); 3772 } 3773 return false; 3774 } 3775 } 3776 3777 @Override 3778 public void overridePendingTransition(IBinder token, String packageName, 3779 int enterAnim, int exitAnim) { 3780 synchronized(this) { 3781 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3782 if (self == null) { 3783 return; 3784 } 3785 3786 final long origId = Binder.clearCallingIdentity(); 3787 3788 if (self.state == ActivityState.RESUMED 3789 || self.state == ActivityState.PAUSING) { 3790 mWindowManager.overridePendingAppTransition(packageName, 3791 enterAnim, exitAnim, null); 3792 } 3793 3794 Binder.restoreCallingIdentity(origId); 3795 } 3796 } 3797 3798 /** 3799 * Main function for removing an existing process from the activity manager 3800 * as a result of that process going away. Clears out all connections 3801 * to the process. 3802 */ 3803 private final void handleAppDiedLocked(ProcessRecord app, 3804 boolean restarting, boolean allowRestart) { 3805 int pid = app.pid; 3806 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3807 if (!restarting) { 3808 removeLruProcessLocked(app); 3809 if (pid > 0) { 3810 ProcessList.remove(pid); 3811 } 3812 } 3813 3814 if (mProfileProc == app) { 3815 clearProfilerLocked(); 3816 } 3817 3818 // Remove this application's activities from active lists. 3819 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3820 3821 app.activities.clear(); 3822 3823 if (app.instrumentationClass != null) { 3824 Slog.w(TAG, "Crash of app " + app.processName 3825 + " running instrumentation " + app.instrumentationClass); 3826 Bundle info = new Bundle(); 3827 info.putString("shortMsg", "Process crashed."); 3828 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3829 } 3830 3831 if (!restarting) { 3832 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3833 // If there was nothing to resume, and we are not already 3834 // restarting this process, but there is a visible activity that 3835 // is hosted by the process... then make sure all visible 3836 // activities are running, taking care of restarting this 3837 // process. 3838 if (hasVisibleActivities) { 3839 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3840 } 3841 } 3842 } 3843 } 3844 3845 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3846 IBinder threadBinder = thread.asBinder(); 3847 // Find the application record. 3848 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3849 ProcessRecord rec = mLruProcesses.get(i); 3850 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3851 return i; 3852 } 3853 } 3854 return -1; 3855 } 3856 3857 final ProcessRecord getRecordForAppLocked( 3858 IApplicationThread thread) { 3859 if (thread == null) { 3860 return null; 3861 } 3862 3863 int appIndex = getLRURecordIndexForAppLocked(thread); 3864 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3865 } 3866 3867 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3868 // If there are no longer any background processes running, 3869 // and the app that died was not running instrumentation, 3870 // then tell everyone we are now low on memory. 3871 boolean haveBg = false; 3872 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3873 ProcessRecord rec = mLruProcesses.get(i); 3874 if (rec.thread != null 3875 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3876 haveBg = true; 3877 break; 3878 } 3879 } 3880 3881 if (!haveBg) { 3882 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3883 if (doReport) { 3884 long now = SystemClock.uptimeMillis(); 3885 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3886 doReport = false; 3887 } else { 3888 mLastMemUsageReportTime = now; 3889 } 3890 } 3891 final ArrayList<ProcessMemInfo> memInfos 3892 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3893 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3894 long now = SystemClock.uptimeMillis(); 3895 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3896 ProcessRecord rec = mLruProcesses.get(i); 3897 if (rec == dyingProc || rec.thread == null) { 3898 continue; 3899 } 3900 if (doReport) { 3901 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3902 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3903 } 3904 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3905 // The low memory report is overriding any current 3906 // state for a GC request. Make sure to do 3907 // heavy/important/visible/foreground processes first. 3908 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3909 rec.lastRequestedGc = 0; 3910 } else { 3911 rec.lastRequestedGc = rec.lastLowMemory; 3912 } 3913 rec.reportLowMemory = true; 3914 rec.lastLowMemory = now; 3915 mProcessesToGc.remove(rec); 3916 addProcessToGcListLocked(rec); 3917 } 3918 } 3919 if (doReport) { 3920 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3921 mHandler.sendMessage(msg); 3922 } 3923 scheduleAppGcsLocked(); 3924 } 3925 } 3926 3927 final void appDiedLocked(ProcessRecord app, int pid, 3928 IApplicationThread thread) { 3929 3930 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3931 synchronized (stats) { 3932 stats.noteProcessDiedLocked(app.info.uid, pid); 3933 } 3934 3935 // Clean up already done if the process has been re-started. 3936 if (app.pid == pid && app.thread != null && 3937 app.thread.asBinder() == thread.asBinder()) { 3938 boolean doLowMem = app.instrumentationClass == null; 3939 boolean doOomAdj = doLowMem; 3940 if (!app.killedByAm) { 3941 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3942 + ") has died."); 3943 mAllowLowerMemLevel = true; 3944 } else { 3945 // Note that we always want to do oom adj to update our state with the 3946 // new number of procs. 3947 mAllowLowerMemLevel = false; 3948 doLowMem = false; 3949 } 3950 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3951 if (DEBUG_CLEANUP) Slog.v( 3952 TAG, "Dying app: " + app + ", pid: " + pid 3953 + ", thread: " + thread.asBinder()); 3954 handleAppDiedLocked(app, false, true); 3955 3956 if (doOomAdj) { 3957 updateOomAdjLocked(); 3958 } 3959 if (doLowMem) { 3960 doLowMemReportIfNeededLocked(app); 3961 } 3962 } else if (app.pid != pid) { 3963 // A new process has already been started. 3964 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3965 + ") has died and restarted (pid " + app.pid + ")."); 3966 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3967 } else if (DEBUG_PROCESSES) { 3968 Slog.d(TAG, "Received spurious death notification for thread " 3969 + thread.asBinder()); 3970 } 3971 } 3972 3973 /** 3974 * If a stack trace dump file is configured, dump process stack traces. 3975 * @param clearTraces causes the dump file to be erased prior to the new 3976 * traces being written, if true; when false, the new traces will be 3977 * appended to any existing file content. 3978 * @param firstPids of dalvik VM processes to dump stack traces for first 3979 * @param lastPids of dalvik VM processes to dump stack traces for last 3980 * @param nativeProcs optional list of native process names to dump stack crawls 3981 * @return file containing stack traces, or null if no dump file is configured 3982 */ 3983 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3984 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3985 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3986 if (tracesPath == null || tracesPath.length() == 0) { 3987 return null; 3988 } 3989 3990 File tracesFile = new File(tracesPath); 3991 try { 3992 File tracesDir = tracesFile.getParentFile(); 3993 if (!tracesDir.exists()) { 3994 tracesFile.mkdirs(); 3995 if (!SELinux.restorecon(tracesDir)) { 3996 return null; 3997 } 3998 } 3999 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4000 4001 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4002 tracesFile.createNewFile(); 4003 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4004 } catch (IOException e) { 4005 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4006 return null; 4007 } 4008 4009 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4010 return tracesFile; 4011 } 4012 4013 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4014 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4015 // Use a FileObserver to detect when traces finish writing. 4016 // The order of traces is considered important to maintain for legibility. 4017 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4018 @Override 4019 public synchronized void onEvent(int event, String path) { notify(); } 4020 }; 4021 4022 try { 4023 observer.startWatching(); 4024 4025 // First collect all of the stacks of the most important pids. 4026 if (firstPids != null) { 4027 try { 4028 int num = firstPids.size(); 4029 for (int i = 0; i < num; i++) { 4030 synchronized (observer) { 4031 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4032 observer.wait(200); // Wait for write-close, give up after 200msec 4033 } 4034 } 4035 } catch (InterruptedException e) { 4036 Log.wtf(TAG, e); 4037 } 4038 } 4039 4040 // Next collect the stacks of the native pids 4041 if (nativeProcs != null) { 4042 int[] pids = Process.getPidsForCommands(nativeProcs); 4043 if (pids != null) { 4044 for (int pid : pids) { 4045 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4046 } 4047 } 4048 } 4049 4050 // Lastly, measure CPU usage. 4051 if (processCpuTracker != null) { 4052 processCpuTracker.init(); 4053 System.gc(); 4054 processCpuTracker.update(); 4055 try { 4056 synchronized (processCpuTracker) { 4057 processCpuTracker.wait(500); // measure over 1/2 second. 4058 } 4059 } catch (InterruptedException e) { 4060 } 4061 processCpuTracker.update(); 4062 4063 // We'll take the stack crawls of just the top apps using CPU. 4064 final int N = processCpuTracker.countWorkingStats(); 4065 int numProcs = 0; 4066 for (int i=0; i<N && numProcs<5; i++) { 4067 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4068 if (lastPids.indexOfKey(stats.pid) >= 0) { 4069 numProcs++; 4070 try { 4071 synchronized (observer) { 4072 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4073 observer.wait(200); // Wait for write-close, give up after 200msec 4074 } 4075 } catch (InterruptedException e) { 4076 Log.wtf(TAG, e); 4077 } 4078 4079 } 4080 } 4081 } 4082 } finally { 4083 observer.stopWatching(); 4084 } 4085 } 4086 4087 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4088 if (true || IS_USER_BUILD) { 4089 return; 4090 } 4091 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4092 if (tracesPath == null || tracesPath.length() == 0) { 4093 return; 4094 } 4095 4096 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4097 StrictMode.allowThreadDiskWrites(); 4098 try { 4099 final File tracesFile = new File(tracesPath); 4100 final File tracesDir = tracesFile.getParentFile(); 4101 final File tracesTmp = new File(tracesDir, "__tmp__"); 4102 try { 4103 if (!tracesDir.exists()) { 4104 tracesFile.mkdirs(); 4105 if (!SELinux.restorecon(tracesDir.getPath())) { 4106 return; 4107 } 4108 } 4109 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4110 4111 if (tracesFile.exists()) { 4112 tracesTmp.delete(); 4113 tracesFile.renameTo(tracesTmp); 4114 } 4115 StringBuilder sb = new StringBuilder(); 4116 Time tobj = new Time(); 4117 tobj.set(System.currentTimeMillis()); 4118 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4119 sb.append(": "); 4120 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4121 sb.append(" since "); 4122 sb.append(msg); 4123 FileOutputStream fos = new FileOutputStream(tracesFile); 4124 fos.write(sb.toString().getBytes()); 4125 if (app == null) { 4126 fos.write("\n*** No application process!".getBytes()); 4127 } 4128 fos.close(); 4129 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4130 } catch (IOException e) { 4131 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4132 return; 4133 } 4134 4135 if (app != null) { 4136 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4137 firstPids.add(app.pid); 4138 dumpStackTraces(tracesPath, firstPids, null, null, null); 4139 } 4140 4141 File lastTracesFile = null; 4142 File curTracesFile = null; 4143 for (int i=9; i>=0; i--) { 4144 String name = String.format(Locale.US, "slow%02d.txt", i); 4145 curTracesFile = new File(tracesDir, name); 4146 if (curTracesFile.exists()) { 4147 if (lastTracesFile != null) { 4148 curTracesFile.renameTo(lastTracesFile); 4149 } else { 4150 curTracesFile.delete(); 4151 } 4152 } 4153 lastTracesFile = curTracesFile; 4154 } 4155 tracesFile.renameTo(curTracesFile); 4156 if (tracesTmp.exists()) { 4157 tracesTmp.renameTo(tracesFile); 4158 } 4159 } finally { 4160 StrictMode.setThreadPolicy(oldPolicy); 4161 } 4162 } 4163 4164 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4165 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4166 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4167 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4168 4169 if (mController != null) { 4170 try { 4171 // 0 == continue, -1 = kill process immediately 4172 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4173 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4174 } catch (RemoteException e) { 4175 mController = null; 4176 Watchdog.getInstance().setActivityController(null); 4177 } 4178 } 4179 4180 long anrTime = SystemClock.uptimeMillis(); 4181 if (MONITOR_CPU_USAGE) { 4182 updateCpuStatsNow(); 4183 } 4184 4185 synchronized (this) { 4186 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4187 if (mShuttingDown) { 4188 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4189 return; 4190 } else if (app.notResponding) { 4191 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4192 return; 4193 } else if (app.crashing) { 4194 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4195 return; 4196 } 4197 4198 // In case we come through here for the same app before completing 4199 // this one, mark as anring now so we will bail out. 4200 app.notResponding = true; 4201 4202 // Log the ANR to the event log. 4203 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4204 app.processName, app.info.flags, annotation); 4205 4206 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4207 firstPids.add(app.pid); 4208 4209 int parentPid = app.pid; 4210 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4211 if (parentPid != app.pid) firstPids.add(parentPid); 4212 4213 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4214 4215 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4216 ProcessRecord r = mLruProcesses.get(i); 4217 if (r != null && r.thread != null) { 4218 int pid = r.pid; 4219 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4220 if (r.persistent) { 4221 firstPids.add(pid); 4222 } else { 4223 lastPids.put(pid, Boolean.TRUE); 4224 } 4225 } 4226 } 4227 } 4228 } 4229 4230 // Log the ANR to the main log. 4231 StringBuilder info = new StringBuilder(); 4232 info.setLength(0); 4233 info.append("ANR in ").append(app.processName); 4234 if (activity != null && activity.shortComponentName != null) { 4235 info.append(" (").append(activity.shortComponentName).append(")"); 4236 } 4237 info.append("\n"); 4238 info.append("PID: ").append(app.pid).append("\n"); 4239 if (annotation != null) { 4240 info.append("Reason: ").append(annotation).append("\n"); 4241 } 4242 if (parent != null && parent != activity) { 4243 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4244 } 4245 4246 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4247 4248 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4249 NATIVE_STACKS_OF_INTEREST); 4250 4251 String cpuInfo = null; 4252 if (MONITOR_CPU_USAGE) { 4253 updateCpuStatsNow(); 4254 synchronized (mProcessCpuThread) { 4255 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4256 } 4257 info.append(processCpuTracker.printCurrentLoad()); 4258 info.append(cpuInfo); 4259 } 4260 4261 info.append(processCpuTracker.printCurrentState(anrTime)); 4262 4263 Slog.e(TAG, info.toString()); 4264 if (tracesFile == null) { 4265 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4266 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4267 } 4268 4269 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4270 cpuInfo, tracesFile, null); 4271 4272 if (mController != null) { 4273 try { 4274 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4275 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4276 if (res != 0) { 4277 if (res < 0 && app.pid != MY_PID) { 4278 Process.killProcess(app.pid); 4279 } else { 4280 synchronized (this) { 4281 mServices.scheduleServiceTimeoutLocked(app); 4282 } 4283 } 4284 return; 4285 } 4286 } catch (RemoteException e) { 4287 mController = null; 4288 Watchdog.getInstance().setActivityController(null); 4289 } 4290 } 4291 4292 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4293 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4294 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4295 4296 synchronized (this) { 4297 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4298 killUnneededProcessLocked(app, "background ANR"); 4299 return; 4300 } 4301 4302 // Set the app's notResponding state, and look up the errorReportReceiver 4303 makeAppNotRespondingLocked(app, 4304 activity != null ? activity.shortComponentName : null, 4305 annotation != null ? "ANR " + annotation : "ANR", 4306 info.toString()); 4307 4308 // Bring up the infamous App Not Responding dialog 4309 Message msg = Message.obtain(); 4310 HashMap<String, Object> map = new HashMap<String, Object>(); 4311 msg.what = SHOW_NOT_RESPONDING_MSG; 4312 msg.obj = map; 4313 msg.arg1 = aboveSystem ? 1 : 0; 4314 map.put("app", app); 4315 if (activity != null) { 4316 map.put("activity", activity); 4317 } 4318 4319 mHandler.sendMessage(msg); 4320 } 4321 } 4322 4323 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4324 if (!mLaunchWarningShown) { 4325 mLaunchWarningShown = true; 4326 mHandler.post(new Runnable() { 4327 @Override 4328 public void run() { 4329 synchronized (ActivityManagerService.this) { 4330 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4331 d.show(); 4332 mHandler.postDelayed(new Runnable() { 4333 @Override 4334 public void run() { 4335 synchronized (ActivityManagerService.this) { 4336 d.dismiss(); 4337 mLaunchWarningShown = false; 4338 } 4339 } 4340 }, 4000); 4341 } 4342 } 4343 }); 4344 } 4345 } 4346 4347 @Override 4348 public boolean clearApplicationUserData(final String packageName, 4349 final IPackageDataObserver observer, int userId) { 4350 enforceNotIsolatedCaller("clearApplicationUserData"); 4351 int uid = Binder.getCallingUid(); 4352 int pid = Binder.getCallingPid(); 4353 userId = handleIncomingUser(pid, uid, 4354 userId, false, true, "clearApplicationUserData", null); 4355 long callingId = Binder.clearCallingIdentity(); 4356 try { 4357 IPackageManager pm = AppGlobals.getPackageManager(); 4358 int pkgUid = -1; 4359 synchronized(this) { 4360 try { 4361 pkgUid = pm.getPackageUid(packageName, userId); 4362 } catch (RemoteException e) { 4363 } 4364 if (pkgUid == -1) { 4365 Slog.w(TAG, "Invalid packageName: " + packageName); 4366 if (observer != null) { 4367 try { 4368 observer.onRemoveCompleted(packageName, false); 4369 } catch (RemoteException e) { 4370 Slog.i(TAG, "Observer no longer exists."); 4371 } 4372 } 4373 return false; 4374 } 4375 if (uid == pkgUid || checkComponentPermission( 4376 android.Manifest.permission.CLEAR_APP_USER_DATA, 4377 pid, uid, -1, true) 4378 == PackageManager.PERMISSION_GRANTED) { 4379 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4380 } else { 4381 throw new SecurityException("PID " + pid + " does not have permission " 4382 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4383 + " of package " + packageName); 4384 } 4385 } 4386 4387 try { 4388 // Clear application user data 4389 pm.clearApplicationUserData(packageName, observer, userId); 4390 4391 // Remove all permissions granted from/to this package 4392 removeUriPermissionsForPackageLocked(packageName, userId, true); 4393 4394 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4395 Uri.fromParts("package", packageName, null)); 4396 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4397 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4398 null, null, 0, null, null, null, false, false, userId); 4399 } catch (RemoteException e) { 4400 } 4401 } finally { 4402 Binder.restoreCallingIdentity(callingId); 4403 } 4404 return true; 4405 } 4406 4407 @Override 4408 public void killBackgroundProcesses(final String packageName, int userId) { 4409 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4410 != PackageManager.PERMISSION_GRANTED && 4411 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4412 != PackageManager.PERMISSION_GRANTED) { 4413 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4414 + Binder.getCallingPid() 4415 + ", uid=" + Binder.getCallingUid() 4416 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4417 Slog.w(TAG, msg); 4418 throw new SecurityException(msg); 4419 } 4420 4421 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4422 userId, true, true, "killBackgroundProcesses", null); 4423 long callingId = Binder.clearCallingIdentity(); 4424 try { 4425 IPackageManager pm = AppGlobals.getPackageManager(); 4426 synchronized(this) { 4427 int appId = -1; 4428 try { 4429 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4430 } catch (RemoteException e) { 4431 } 4432 if (appId == -1) { 4433 Slog.w(TAG, "Invalid packageName: " + packageName); 4434 return; 4435 } 4436 killPackageProcessesLocked(packageName, appId, userId, 4437 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4438 } 4439 } finally { 4440 Binder.restoreCallingIdentity(callingId); 4441 } 4442 } 4443 4444 @Override 4445 public void killAllBackgroundProcesses() { 4446 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4447 != PackageManager.PERMISSION_GRANTED) { 4448 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4449 + Binder.getCallingPid() 4450 + ", uid=" + Binder.getCallingUid() 4451 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4452 Slog.w(TAG, msg); 4453 throw new SecurityException(msg); 4454 } 4455 4456 long callingId = Binder.clearCallingIdentity(); 4457 try { 4458 synchronized(this) { 4459 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4460 final int NP = mProcessNames.getMap().size(); 4461 for (int ip=0; ip<NP; ip++) { 4462 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4463 final int NA = apps.size(); 4464 for (int ia=0; ia<NA; ia++) { 4465 ProcessRecord app = apps.valueAt(ia); 4466 if (app.persistent) { 4467 // we don't kill persistent processes 4468 continue; 4469 } 4470 if (app.removed) { 4471 procs.add(app); 4472 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4473 app.removed = true; 4474 procs.add(app); 4475 } 4476 } 4477 } 4478 4479 int N = procs.size(); 4480 for (int i=0; i<N; i++) { 4481 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4482 } 4483 mAllowLowerMemLevel = true; 4484 updateOomAdjLocked(); 4485 doLowMemReportIfNeededLocked(null); 4486 } 4487 } finally { 4488 Binder.restoreCallingIdentity(callingId); 4489 } 4490 } 4491 4492 @Override 4493 public void forceStopPackage(final String packageName, int userId) { 4494 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4495 != PackageManager.PERMISSION_GRANTED) { 4496 String msg = "Permission Denial: forceStopPackage() from pid=" 4497 + Binder.getCallingPid() 4498 + ", uid=" + Binder.getCallingUid() 4499 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4500 Slog.w(TAG, msg); 4501 throw new SecurityException(msg); 4502 } 4503 final int callingPid = Binder.getCallingPid(); 4504 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4505 userId, true, true, "forceStopPackage", null); 4506 long callingId = Binder.clearCallingIdentity(); 4507 try { 4508 IPackageManager pm = AppGlobals.getPackageManager(); 4509 synchronized(this) { 4510 int[] users = userId == UserHandle.USER_ALL 4511 ? getUsersLocked() : new int[] { userId }; 4512 for (int user : users) { 4513 int pkgUid = -1; 4514 try { 4515 pkgUid = pm.getPackageUid(packageName, user); 4516 } catch (RemoteException e) { 4517 } 4518 if (pkgUid == -1) { 4519 Slog.w(TAG, "Invalid packageName: " + packageName); 4520 continue; 4521 } 4522 try { 4523 pm.setPackageStoppedState(packageName, true, user); 4524 } catch (RemoteException e) { 4525 } catch (IllegalArgumentException e) { 4526 Slog.w(TAG, "Failed trying to unstop package " 4527 + packageName + ": " + e); 4528 } 4529 if (isUserRunningLocked(user, false)) { 4530 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4531 } 4532 } 4533 } 4534 } finally { 4535 Binder.restoreCallingIdentity(callingId); 4536 } 4537 } 4538 4539 /* 4540 * The pkg name and app id have to be specified. 4541 */ 4542 @Override 4543 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4544 if (pkg == null) { 4545 return; 4546 } 4547 // Make sure the uid is valid. 4548 if (appid < 0) { 4549 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4550 return; 4551 } 4552 int callerUid = Binder.getCallingUid(); 4553 // Only the system server can kill an application 4554 if (callerUid == Process.SYSTEM_UID) { 4555 // Post an aysnc message to kill the application 4556 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4557 msg.arg1 = appid; 4558 msg.arg2 = 0; 4559 Bundle bundle = new Bundle(); 4560 bundle.putString("pkg", pkg); 4561 bundle.putString("reason", reason); 4562 msg.obj = bundle; 4563 mHandler.sendMessage(msg); 4564 } else { 4565 throw new SecurityException(callerUid + " cannot kill pkg: " + 4566 pkg); 4567 } 4568 } 4569 4570 @Override 4571 public void closeSystemDialogs(String reason) { 4572 enforceNotIsolatedCaller("closeSystemDialogs"); 4573 4574 final int pid = Binder.getCallingPid(); 4575 final int uid = Binder.getCallingUid(); 4576 final long origId = Binder.clearCallingIdentity(); 4577 try { 4578 synchronized (this) { 4579 // Only allow this from foreground processes, so that background 4580 // applications can't abuse it to prevent system UI from being shown. 4581 if (uid >= Process.FIRST_APPLICATION_UID) { 4582 ProcessRecord proc; 4583 synchronized (mPidsSelfLocked) { 4584 proc = mPidsSelfLocked.get(pid); 4585 } 4586 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4587 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4588 + " from background process " + proc); 4589 return; 4590 } 4591 } 4592 closeSystemDialogsLocked(reason); 4593 } 4594 } finally { 4595 Binder.restoreCallingIdentity(origId); 4596 } 4597 } 4598 4599 void closeSystemDialogsLocked(String reason) { 4600 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4601 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4602 | Intent.FLAG_RECEIVER_FOREGROUND); 4603 if (reason != null) { 4604 intent.putExtra("reason", reason); 4605 } 4606 mWindowManager.closeSystemDialogs(reason); 4607 4608 mStackSupervisor.closeSystemDialogsLocked(); 4609 4610 broadcastIntentLocked(null, null, intent, null, 4611 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4612 Process.SYSTEM_UID, UserHandle.USER_ALL); 4613 } 4614 4615 @Override 4616 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4617 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4618 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4619 for (int i=pids.length-1; i>=0; i--) { 4620 ProcessRecord proc; 4621 int oomAdj; 4622 synchronized (this) { 4623 synchronized (mPidsSelfLocked) { 4624 proc = mPidsSelfLocked.get(pids[i]); 4625 oomAdj = proc != null ? proc.setAdj : 0; 4626 } 4627 } 4628 infos[i] = new Debug.MemoryInfo(); 4629 Debug.getMemoryInfo(pids[i], infos[i]); 4630 if (proc != null) { 4631 synchronized (this) { 4632 if (proc.thread != null && proc.setAdj == oomAdj) { 4633 // Record this for posterity if the process has been stable. 4634 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4635 infos[i].getTotalUss(), false, proc.pkgList); 4636 } 4637 } 4638 } 4639 } 4640 return infos; 4641 } 4642 4643 @Override 4644 public long[] getProcessPss(int[] pids) { 4645 enforceNotIsolatedCaller("getProcessPss"); 4646 long[] pss = new long[pids.length]; 4647 for (int i=pids.length-1; i>=0; i--) { 4648 ProcessRecord proc; 4649 int oomAdj; 4650 synchronized (this) { 4651 synchronized (mPidsSelfLocked) { 4652 proc = mPidsSelfLocked.get(pids[i]); 4653 oomAdj = proc != null ? proc.setAdj : 0; 4654 } 4655 } 4656 long[] tmpUss = new long[1]; 4657 pss[i] = Debug.getPss(pids[i], tmpUss); 4658 if (proc != null) { 4659 synchronized (this) { 4660 if (proc.thread != null && proc.setAdj == oomAdj) { 4661 // Record this for posterity if the process has been stable. 4662 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4663 } 4664 } 4665 } 4666 } 4667 return pss; 4668 } 4669 4670 @Override 4671 public void killApplicationProcess(String processName, int uid) { 4672 if (processName == null) { 4673 return; 4674 } 4675 4676 int callerUid = Binder.getCallingUid(); 4677 // Only the system server can kill an application 4678 if (callerUid == Process.SYSTEM_UID) { 4679 synchronized (this) { 4680 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4681 if (app != null && app.thread != null) { 4682 try { 4683 app.thread.scheduleSuicide(); 4684 } catch (RemoteException e) { 4685 // If the other end already died, then our work here is done. 4686 } 4687 } else { 4688 Slog.w(TAG, "Process/uid not found attempting kill of " 4689 + processName + " / " + uid); 4690 } 4691 } 4692 } else { 4693 throw new SecurityException(callerUid + " cannot kill app process: " + 4694 processName); 4695 } 4696 } 4697 4698 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4699 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4700 false, true, false, false, UserHandle.getUserId(uid), reason); 4701 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4702 Uri.fromParts("package", packageName, null)); 4703 if (!mProcessesReady) { 4704 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4705 | Intent.FLAG_RECEIVER_FOREGROUND); 4706 } 4707 intent.putExtra(Intent.EXTRA_UID, uid); 4708 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4709 broadcastIntentLocked(null, null, intent, 4710 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4711 false, false, 4712 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4713 } 4714 4715 private void forceStopUserLocked(int userId, String reason) { 4716 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4717 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4718 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4719 | Intent.FLAG_RECEIVER_FOREGROUND); 4720 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4721 broadcastIntentLocked(null, null, intent, 4722 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4723 false, false, 4724 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4725 } 4726 4727 private final boolean killPackageProcessesLocked(String packageName, int appId, 4728 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4729 boolean doit, boolean evenPersistent, String reason) { 4730 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4731 4732 // Remove all processes this package may have touched: all with the 4733 // same UID (except for the system or root user), and all whose name 4734 // matches the package name. 4735 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4736 final int NP = mProcessNames.getMap().size(); 4737 for (int ip=0; ip<NP; ip++) { 4738 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4739 final int NA = apps.size(); 4740 for (int ia=0; ia<NA; ia++) { 4741 ProcessRecord app = apps.valueAt(ia); 4742 if (app.persistent && !evenPersistent) { 4743 // we don't kill persistent processes 4744 continue; 4745 } 4746 if (app.removed) { 4747 if (doit) { 4748 procs.add(app); 4749 } 4750 continue; 4751 } 4752 4753 // Skip process if it doesn't meet our oom adj requirement. 4754 if (app.setAdj < minOomAdj) { 4755 continue; 4756 } 4757 4758 // If no package is specified, we call all processes under the 4759 // give user id. 4760 if (packageName == null) { 4761 if (app.userId != userId) { 4762 continue; 4763 } 4764 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4765 continue; 4766 } 4767 // Package has been specified, we want to hit all processes 4768 // that match it. We need to qualify this by the processes 4769 // that are running under the specified app and user ID. 4770 } else { 4771 if (UserHandle.getAppId(app.uid) != appId) { 4772 continue; 4773 } 4774 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4775 continue; 4776 } 4777 if (!app.pkgList.containsKey(packageName)) { 4778 continue; 4779 } 4780 } 4781 4782 // Process has passed all conditions, kill it! 4783 if (!doit) { 4784 return true; 4785 } 4786 app.removed = true; 4787 procs.add(app); 4788 } 4789 } 4790 4791 int N = procs.size(); 4792 for (int i=0; i<N; i++) { 4793 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4794 } 4795 updateOomAdjLocked(); 4796 return N > 0; 4797 } 4798 4799 private final boolean forceStopPackageLocked(String name, int appId, 4800 boolean callerWillRestart, boolean purgeCache, boolean doit, 4801 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4802 int i; 4803 int N; 4804 4805 if (userId == UserHandle.USER_ALL && name == null) { 4806 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4807 } 4808 4809 if (appId < 0 && name != null) { 4810 try { 4811 appId = UserHandle.getAppId( 4812 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4813 } catch (RemoteException e) { 4814 } 4815 } 4816 4817 if (doit) { 4818 if (name != null) { 4819 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4820 + " user=" + userId + ": " + reason); 4821 } else { 4822 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4823 } 4824 4825 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4826 for (int ip=pmap.size()-1; ip>=0; ip--) { 4827 SparseArray<Long> ba = pmap.valueAt(ip); 4828 for (i=ba.size()-1; i>=0; i--) { 4829 boolean remove = false; 4830 final int entUid = ba.keyAt(i); 4831 if (name != null) { 4832 if (userId == UserHandle.USER_ALL) { 4833 if (UserHandle.getAppId(entUid) == appId) { 4834 remove = true; 4835 } 4836 } else { 4837 if (entUid == UserHandle.getUid(userId, appId)) { 4838 remove = true; 4839 } 4840 } 4841 } else if (UserHandle.getUserId(entUid) == userId) { 4842 remove = true; 4843 } 4844 if (remove) { 4845 ba.removeAt(i); 4846 } 4847 } 4848 if (ba.size() == 0) { 4849 pmap.removeAt(ip); 4850 } 4851 } 4852 } 4853 4854 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4855 -100, callerWillRestart, true, doit, evenPersistent, 4856 name == null ? ("stop user " + userId) : ("stop " + name)); 4857 4858 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4859 if (!doit) { 4860 return true; 4861 } 4862 didSomething = true; 4863 } 4864 4865 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4866 if (!doit) { 4867 return true; 4868 } 4869 didSomething = true; 4870 } 4871 4872 if (name == null) { 4873 // Remove all sticky broadcasts from this user. 4874 mStickyBroadcasts.remove(userId); 4875 } 4876 4877 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4878 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4879 userId, providers)) { 4880 if (!doit) { 4881 return true; 4882 } 4883 didSomething = true; 4884 } 4885 N = providers.size(); 4886 for (i=0; i<N; i++) { 4887 removeDyingProviderLocked(null, providers.get(i), true); 4888 } 4889 4890 // Remove transient permissions granted from/to this package/user 4891 removeUriPermissionsForPackageLocked(name, userId, false); 4892 4893 if (name == null || uninstalling) { 4894 // Remove pending intents. For now we only do this when force 4895 // stopping users, because we have some problems when doing this 4896 // for packages -- app widgets are not currently cleaned up for 4897 // such packages, so they can be left with bad pending intents. 4898 if (mIntentSenderRecords.size() > 0) { 4899 Iterator<WeakReference<PendingIntentRecord>> it 4900 = mIntentSenderRecords.values().iterator(); 4901 while (it.hasNext()) { 4902 WeakReference<PendingIntentRecord> wpir = it.next(); 4903 if (wpir == null) { 4904 it.remove(); 4905 continue; 4906 } 4907 PendingIntentRecord pir = wpir.get(); 4908 if (pir == null) { 4909 it.remove(); 4910 continue; 4911 } 4912 if (name == null) { 4913 // Stopping user, remove all objects for the user. 4914 if (pir.key.userId != userId) { 4915 // Not the same user, skip it. 4916 continue; 4917 } 4918 } else { 4919 if (UserHandle.getAppId(pir.uid) != appId) { 4920 // Different app id, skip it. 4921 continue; 4922 } 4923 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4924 // Different user, skip it. 4925 continue; 4926 } 4927 if (!pir.key.packageName.equals(name)) { 4928 // Different package, skip it. 4929 continue; 4930 } 4931 } 4932 if (!doit) { 4933 return true; 4934 } 4935 didSomething = true; 4936 it.remove(); 4937 pir.canceled = true; 4938 if (pir.key.activity != null) { 4939 pir.key.activity.pendingResults.remove(pir.ref); 4940 } 4941 } 4942 } 4943 } 4944 4945 if (doit) { 4946 if (purgeCache && name != null) { 4947 AttributeCache ac = AttributeCache.instance(); 4948 if (ac != null) { 4949 ac.removePackage(name); 4950 } 4951 } 4952 if (mBooted) { 4953 mStackSupervisor.resumeTopActivitiesLocked(); 4954 mStackSupervisor.scheduleIdleLocked(); 4955 } 4956 } 4957 4958 return didSomething; 4959 } 4960 4961 private final boolean removeProcessLocked(ProcessRecord app, 4962 boolean callerWillRestart, boolean allowRestart, String reason) { 4963 final String name = app.processName; 4964 final int uid = app.uid; 4965 if (DEBUG_PROCESSES) Slog.d( 4966 TAG, "Force removing proc " + app.toShortString() + " (" + name 4967 + "/" + uid + ")"); 4968 4969 mProcessNames.remove(name, uid); 4970 mIsolatedProcesses.remove(app.uid); 4971 if (mHeavyWeightProcess == app) { 4972 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4973 mHeavyWeightProcess.userId, 0)); 4974 mHeavyWeightProcess = null; 4975 } 4976 boolean needRestart = false; 4977 if (app.pid > 0 && app.pid != MY_PID) { 4978 int pid = app.pid; 4979 synchronized (mPidsSelfLocked) { 4980 mPidsSelfLocked.remove(pid); 4981 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4982 } 4983 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4984 app.processName, app.info.uid); 4985 if (app.isolated) { 4986 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4987 } 4988 killUnneededProcessLocked(app, reason); 4989 handleAppDiedLocked(app, true, allowRestart); 4990 removeLruProcessLocked(app); 4991 4992 if (app.persistent && !app.isolated) { 4993 if (!callerWillRestart) { 4994 addAppLocked(app.info, false); 4995 } else { 4996 needRestart = true; 4997 } 4998 } 4999 } else { 5000 mRemovedProcesses.add(app); 5001 } 5002 5003 return needRestart; 5004 } 5005 5006 private final void processStartTimedOutLocked(ProcessRecord app) { 5007 final int pid = app.pid; 5008 boolean gone = false; 5009 synchronized (mPidsSelfLocked) { 5010 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5011 if (knownApp != null && knownApp.thread == null) { 5012 mPidsSelfLocked.remove(pid); 5013 gone = true; 5014 } 5015 } 5016 5017 if (gone) { 5018 Slog.w(TAG, "Process " + app + " failed to attach"); 5019 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5020 pid, app.uid, app.processName); 5021 mProcessNames.remove(app.processName, app.uid); 5022 mIsolatedProcesses.remove(app.uid); 5023 if (mHeavyWeightProcess == app) { 5024 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5025 mHeavyWeightProcess.userId, 0)); 5026 mHeavyWeightProcess = null; 5027 } 5028 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5029 app.processName, app.info.uid); 5030 if (app.isolated) { 5031 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5032 } 5033 // Take care of any launching providers waiting for this process. 5034 checkAppInLaunchingProvidersLocked(app, true); 5035 // Take care of any services that are waiting for the process. 5036 mServices.processStartTimedOutLocked(app); 5037 killUnneededProcessLocked(app, "start timeout"); 5038 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5039 Slog.w(TAG, "Unattached app died before backup, skipping"); 5040 try { 5041 IBackupManager bm = IBackupManager.Stub.asInterface( 5042 ServiceManager.getService(Context.BACKUP_SERVICE)); 5043 bm.agentDisconnected(app.info.packageName); 5044 } catch (RemoteException e) { 5045 // Can't happen; the backup manager is local 5046 } 5047 } 5048 if (isPendingBroadcastProcessLocked(pid)) { 5049 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5050 skipPendingBroadcastLocked(pid); 5051 } 5052 } else { 5053 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5054 } 5055 } 5056 5057 private final boolean attachApplicationLocked(IApplicationThread thread, 5058 int pid) { 5059 5060 // Find the application record that is being attached... either via 5061 // the pid if we are running in multiple processes, or just pull the 5062 // next app record if we are emulating process with anonymous threads. 5063 ProcessRecord app; 5064 if (pid != MY_PID && pid >= 0) { 5065 synchronized (mPidsSelfLocked) { 5066 app = mPidsSelfLocked.get(pid); 5067 } 5068 } else { 5069 app = null; 5070 } 5071 5072 if (app == null) { 5073 Slog.w(TAG, "No pending application record for pid " + pid 5074 + " (IApplicationThread " + thread + "); dropping process"); 5075 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5076 if (pid > 0 && pid != MY_PID) { 5077 Process.killProcessQuiet(pid); 5078 } else { 5079 try { 5080 thread.scheduleExit(); 5081 } catch (Exception e) { 5082 // Ignore exceptions. 5083 } 5084 } 5085 return false; 5086 } 5087 5088 // If this application record is still attached to a previous 5089 // process, clean it up now. 5090 if (app.thread != null) { 5091 handleAppDiedLocked(app, true, true); 5092 } 5093 5094 // Tell the process all about itself. 5095 5096 if (localLOGV) Slog.v( 5097 TAG, "Binding process pid " + pid + " to record " + app); 5098 5099 final String processName = app.processName; 5100 try { 5101 AppDeathRecipient adr = new AppDeathRecipient( 5102 app, pid, thread); 5103 thread.asBinder().linkToDeath(adr, 0); 5104 app.deathRecipient = adr; 5105 } catch (RemoteException e) { 5106 app.resetPackageList(mProcessStats); 5107 startProcessLocked(app, "link fail", processName); 5108 return false; 5109 } 5110 5111 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5112 5113 app.makeActive(thread, mProcessStats); 5114 app.curAdj = app.setAdj = -100; 5115 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5116 app.forcingToForeground = null; 5117 updateProcessForegroundLocked(app, false, false); 5118 app.hasShownUi = false; 5119 app.debugging = false; 5120 app.cached = false; 5121 5122 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5123 5124 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5125 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5126 5127 if (!normalMode) { 5128 Slog.i(TAG, "Launching preboot mode app: " + app); 5129 } 5130 5131 if (localLOGV) Slog.v( 5132 TAG, "New app record " + app 5133 + " thread=" + thread.asBinder() + " pid=" + pid); 5134 try { 5135 int testMode = IApplicationThread.DEBUG_OFF; 5136 if (mDebugApp != null && mDebugApp.equals(processName)) { 5137 testMode = mWaitForDebugger 5138 ? IApplicationThread.DEBUG_WAIT 5139 : IApplicationThread.DEBUG_ON; 5140 app.debugging = true; 5141 if (mDebugTransient) { 5142 mDebugApp = mOrigDebugApp; 5143 mWaitForDebugger = mOrigWaitForDebugger; 5144 } 5145 } 5146 String profileFile = app.instrumentationProfileFile; 5147 ParcelFileDescriptor profileFd = null; 5148 boolean profileAutoStop = false; 5149 if (mProfileApp != null && mProfileApp.equals(processName)) { 5150 mProfileProc = app; 5151 profileFile = mProfileFile; 5152 profileFd = mProfileFd; 5153 profileAutoStop = mAutoStopProfiler; 5154 } 5155 boolean enableOpenGlTrace = false; 5156 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5157 enableOpenGlTrace = true; 5158 mOpenGlTraceApp = null; 5159 } 5160 5161 // If the app is being launched for restore or full backup, set it up specially 5162 boolean isRestrictedBackupMode = false; 5163 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5164 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5165 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5166 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5167 } 5168 5169 ensurePackageDexOpt(app.instrumentationInfo != null 5170 ? app.instrumentationInfo.packageName 5171 : app.info.packageName); 5172 if (app.instrumentationClass != null) { 5173 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5174 } 5175 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5176 + processName + " with config " + mConfiguration); 5177 ApplicationInfo appInfo = app.instrumentationInfo != null 5178 ? app.instrumentationInfo : app.info; 5179 app.compat = compatibilityInfoForPackageLocked(appInfo); 5180 if (profileFd != null) { 5181 profileFd = profileFd.dup(); 5182 } 5183 thread.bindApplication(processName, appInfo, providers, 5184 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5185 app.instrumentationArguments, app.instrumentationWatcher, 5186 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5187 isRestrictedBackupMode || !normalMode, app.persistent, 5188 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5189 mCoreSettingsObserver.getCoreSettingsLocked()); 5190 updateLruProcessLocked(app, false, null); 5191 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5192 } catch (Exception e) { 5193 // todo: Yikes! What should we do? For now we will try to 5194 // start another process, but that could easily get us in 5195 // an infinite loop of restarting processes... 5196 Slog.w(TAG, "Exception thrown during bind!", e); 5197 5198 app.resetPackageList(mProcessStats); 5199 app.unlinkDeathRecipient(); 5200 startProcessLocked(app, "bind fail", processName); 5201 return false; 5202 } 5203 5204 // Remove this record from the list of starting applications. 5205 mPersistentStartingProcesses.remove(app); 5206 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5207 "Attach application locked removing on hold: " + app); 5208 mProcessesOnHold.remove(app); 5209 5210 boolean badApp = false; 5211 boolean didSomething = false; 5212 5213 // See if the top visible activity is waiting to run in this process... 5214 if (normalMode) { 5215 try { 5216 if (mStackSupervisor.attachApplicationLocked(app)) { 5217 didSomething = true; 5218 } 5219 } catch (Exception e) { 5220 badApp = true; 5221 } 5222 } 5223 5224 // Find any services that should be running in this process... 5225 if (!badApp) { 5226 try { 5227 didSomething |= mServices.attachApplicationLocked(app, processName); 5228 } catch (Exception e) { 5229 badApp = true; 5230 } 5231 } 5232 5233 // Check if a next-broadcast receiver is in this process... 5234 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5235 try { 5236 didSomething |= sendPendingBroadcastsLocked(app); 5237 } catch (Exception e) { 5238 // If the app died trying to launch the receiver we declare it 'bad' 5239 badApp = true; 5240 } 5241 } 5242 5243 // Check whether the next backup agent is in this process... 5244 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5245 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5246 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5247 try { 5248 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5249 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5250 mBackupTarget.backupMode); 5251 } catch (Exception e) { 5252 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5253 e.printStackTrace(); 5254 } 5255 } 5256 5257 if (badApp) { 5258 // todo: Also need to kill application to deal with all 5259 // kinds of exceptions. 5260 handleAppDiedLocked(app, false, true); 5261 return false; 5262 } 5263 5264 if (!didSomething) { 5265 updateOomAdjLocked(); 5266 } 5267 5268 return true; 5269 } 5270 5271 @Override 5272 public final void attachApplication(IApplicationThread thread) { 5273 synchronized (this) { 5274 int callingPid = Binder.getCallingPid(); 5275 final long origId = Binder.clearCallingIdentity(); 5276 attachApplicationLocked(thread, callingPid); 5277 Binder.restoreCallingIdentity(origId); 5278 } 5279 } 5280 5281 @Override 5282 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5283 final long origId = Binder.clearCallingIdentity(); 5284 synchronized (this) { 5285 ActivityStack stack = ActivityRecord.getStackLocked(token); 5286 if (stack != null) { 5287 ActivityRecord r = 5288 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5289 if (stopProfiling) { 5290 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5291 try { 5292 mProfileFd.close(); 5293 } catch (IOException e) { 5294 } 5295 clearProfilerLocked(); 5296 } 5297 } 5298 } 5299 } 5300 Binder.restoreCallingIdentity(origId); 5301 } 5302 5303 void enableScreenAfterBoot() { 5304 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5305 SystemClock.uptimeMillis()); 5306 mWindowManager.enableScreenAfterBoot(); 5307 5308 synchronized (this) { 5309 updateEventDispatchingLocked(); 5310 } 5311 } 5312 5313 @Override 5314 public void showBootMessage(final CharSequence msg, final boolean always) { 5315 enforceNotIsolatedCaller("showBootMessage"); 5316 mWindowManager.showBootMessage(msg, always); 5317 } 5318 5319 @Override 5320 public void dismissKeyguardOnNextActivity() { 5321 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5322 final long token = Binder.clearCallingIdentity(); 5323 try { 5324 synchronized (this) { 5325 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5326 if (mLockScreenShown) { 5327 mLockScreenShown = false; 5328 comeOutOfSleepIfNeededLocked(); 5329 } 5330 mStackSupervisor.setDismissKeyguard(true); 5331 } 5332 } finally { 5333 Binder.restoreCallingIdentity(token); 5334 } 5335 } 5336 5337 final void finishBooting() { 5338 // Register receivers to handle package update events 5339 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5340 5341 synchronized (this) { 5342 // Ensure that any processes we had put on hold are now started 5343 // up. 5344 final int NP = mProcessesOnHold.size(); 5345 if (NP > 0) { 5346 ArrayList<ProcessRecord> procs = 5347 new ArrayList<ProcessRecord>(mProcessesOnHold); 5348 for (int ip=0; ip<NP; ip++) { 5349 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5350 + procs.get(ip)); 5351 startProcessLocked(procs.get(ip), "on-hold", null); 5352 } 5353 } 5354 5355 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5356 // Start looking for apps that are abusing wake locks. 5357 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5358 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5359 // Tell anyone interested that we are done booting! 5360 SystemProperties.set("sys.boot_completed", "1"); 5361 SystemProperties.set("dev.bootcomplete", "1"); 5362 for (int i=0; i<mStartedUsers.size(); i++) { 5363 UserStartedState uss = mStartedUsers.valueAt(i); 5364 if (uss.mState == UserStartedState.STATE_BOOTING) { 5365 uss.mState = UserStartedState.STATE_RUNNING; 5366 final int userId = mStartedUsers.keyAt(i); 5367 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5368 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5369 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5370 broadcastIntentLocked(null, null, intent, null, 5371 new IIntentReceiver.Stub() { 5372 @Override 5373 public void performReceive(Intent intent, int resultCode, 5374 String data, Bundle extras, boolean ordered, 5375 boolean sticky, int sendingUser) { 5376 synchronized (ActivityManagerService.this) { 5377 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5378 true, false); 5379 } 5380 } 5381 }, 5382 0, null, null, 5383 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5384 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5385 userId); 5386 } 5387 } 5388 scheduleStartProfilesLocked(); 5389 } 5390 } 5391 } 5392 5393 final void ensureBootCompleted() { 5394 boolean booting; 5395 boolean enableScreen; 5396 synchronized (this) { 5397 booting = mBooting; 5398 mBooting = false; 5399 enableScreen = !mBooted; 5400 mBooted = true; 5401 } 5402 5403 if (booting) { 5404 finishBooting(); 5405 } 5406 5407 if (enableScreen) { 5408 enableScreenAfterBoot(); 5409 } 5410 } 5411 5412 @Override 5413 public final void activityResumed(IBinder token) { 5414 final long origId = Binder.clearCallingIdentity(); 5415 synchronized(this) { 5416 ActivityStack stack = ActivityRecord.getStackLocked(token); 5417 if (stack != null) { 5418 ActivityRecord.activityResumedLocked(token); 5419 } 5420 } 5421 Binder.restoreCallingIdentity(origId); 5422 } 5423 5424 @Override 5425 public final void activityPaused(IBinder token) { 5426 final long origId = Binder.clearCallingIdentity(); 5427 synchronized(this) { 5428 ActivityStack stack = ActivityRecord.getStackLocked(token); 5429 if (stack != null) { 5430 stack.activityPausedLocked(token, false); 5431 } 5432 } 5433 Binder.restoreCallingIdentity(origId); 5434 } 5435 5436 @Override 5437 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5438 CharSequence description) { 5439 if (localLOGV) Slog.v( 5440 TAG, "Activity stopped: token=" + token); 5441 5442 // Refuse possible leaked file descriptors 5443 if (icicle != null && icicle.hasFileDescriptors()) { 5444 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5445 } 5446 5447 final long origId = Binder.clearCallingIdentity(); 5448 5449 synchronized (this) { 5450 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5451 if (r != null) { 5452 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5453 } 5454 } 5455 5456 trimApplications(); 5457 5458 Binder.restoreCallingIdentity(origId); 5459 } 5460 5461 @Override 5462 public final void activityDestroyed(IBinder token) { 5463 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5464 synchronized (this) { 5465 ActivityStack stack = ActivityRecord.getStackLocked(token); 5466 if (stack != null) { 5467 stack.activityDestroyedLocked(token); 5468 } 5469 } 5470 } 5471 5472 @Override 5473 public String getCallingPackage(IBinder token) { 5474 synchronized (this) { 5475 ActivityRecord r = getCallingRecordLocked(token); 5476 return r != null ? r.info.packageName : null; 5477 } 5478 } 5479 5480 @Override 5481 public ComponentName getCallingActivity(IBinder token) { 5482 synchronized (this) { 5483 ActivityRecord r = getCallingRecordLocked(token); 5484 return r != null ? r.intent.getComponent() : null; 5485 } 5486 } 5487 5488 private ActivityRecord getCallingRecordLocked(IBinder token) { 5489 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5490 if (r == null) { 5491 return null; 5492 } 5493 return r.resultTo; 5494 } 5495 5496 @Override 5497 public ComponentName getActivityClassForToken(IBinder token) { 5498 synchronized(this) { 5499 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5500 if (r == null) { 5501 return null; 5502 } 5503 return r.intent.getComponent(); 5504 } 5505 } 5506 5507 @Override 5508 public String getPackageForToken(IBinder token) { 5509 synchronized(this) { 5510 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5511 if (r == null) { 5512 return null; 5513 } 5514 return r.packageName; 5515 } 5516 } 5517 5518 @Override 5519 public IIntentSender getIntentSender(int type, 5520 String packageName, IBinder token, String resultWho, 5521 int requestCode, Intent[] intents, String[] resolvedTypes, 5522 int flags, Bundle options, int userId) { 5523 enforceNotIsolatedCaller("getIntentSender"); 5524 // Refuse possible leaked file descriptors 5525 if (intents != null) { 5526 if (intents.length < 1) { 5527 throw new IllegalArgumentException("Intents array length must be >= 1"); 5528 } 5529 for (int i=0; i<intents.length; i++) { 5530 Intent intent = intents[i]; 5531 if (intent != null) { 5532 if (intent.hasFileDescriptors()) { 5533 throw new IllegalArgumentException("File descriptors passed in Intent"); 5534 } 5535 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5536 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5537 throw new IllegalArgumentException( 5538 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5539 } 5540 intents[i] = new Intent(intent); 5541 } 5542 } 5543 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5544 throw new IllegalArgumentException( 5545 "Intent array length does not match resolvedTypes length"); 5546 } 5547 } 5548 if (options != null) { 5549 if (options.hasFileDescriptors()) { 5550 throw new IllegalArgumentException("File descriptors passed in options"); 5551 } 5552 } 5553 5554 synchronized(this) { 5555 int callingUid = Binder.getCallingUid(); 5556 int origUserId = userId; 5557 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5558 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5559 "getIntentSender", null); 5560 if (origUserId == UserHandle.USER_CURRENT) { 5561 // We don't want to evaluate this until the pending intent is 5562 // actually executed. However, we do want to always do the 5563 // security checking for it above. 5564 userId = UserHandle.USER_CURRENT; 5565 } 5566 try { 5567 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5568 int uid = AppGlobals.getPackageManager() 5569 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5570 if (!UserHandle.isSameApp(callingUid, uid)) { 5571 String msg = "Permission Denial: getIntentSender() from pid=" 5572 + Binder.getCallingPid() 5573 + ", uid=" + Binder.getCallingUid() 5574 + ", (need uid=" + uid + ")" 5575 + " is not allowed to send as package " + packageName; 5576 Slog.w(TAG, msg); 5577 throw new SecurityException(msg); 5578 } 5579 } 5580 5581 return getIntentSenderLocked(type, packageName, callingUid, userId, 5582 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5583 5584 } catch (RemoteException e) { 5585 throw new SecurityException(e); 5586 } 5587 } 5588 } 5589 5590 IIntentSender getIntentSenderLocked(int type, String packageName, 5591 int callingUid, int userId, IBinder token, String resultWho, 5592 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5593 Bundle options) { 5594 if (DEBUG_MU) 5595 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5596 ActivityRecord activity = null; 5597 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5598 activity = ActivityRecord.isInStackLocked(token); 5599 if (activity == null) { 5600 return null; 5601 } 5602 if (activity.finishing) { 5603 return null; 5604 } 5605 } 5606 5607 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5608 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5609 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5610 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5611 |PendingIntent.FLAG_UPDATE_CURRENT); 5612 5613 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5614 type, packageName, activity, resultWho, 5615 requestCode, intents, resolvedTypes, flags, options, userId); 5616 WeakReference<PendingIntentRecord> ref; 5617 ref = mIntentSenderRecords.get(key); 5618 PendingIntentRecord rec = ref != null ? ref.get() : null; 5619 if (rec != null) { 5620 if (!cancelCurrent) { 5621 if (updateCurrent) { 5622 if (rec.key.requestIntent != null) { 5623 rec.key.requestIntent.replaceExtras(intents != null ? 5624 intents[intents.length - 1] : null); 5625 } 5626 if (intents != null) { 5627 intents[intents.length-1] = rec.key.requestIntent; 5628 rec.key.allIntents = intents; 5629 rec.key.allResolvedTypes = resolvedTypes; 5630 } else { 5631 rec.key.allIntents = null; 5632 rec.key.allResolvedTypes = null; 5633 } 5634 } 5635 return rec; 5636 } 5637 rec.canceled = true; 5638 mIntentSenderRecords.remove(key); 5639 } 5640 if (noCreate) { 5641 return rec; 5642 } 5643 rec = new PendingIntentRecord(this, key, callingUid); 5644 mIntentSenderRecords.put(key, rec.ref); 5645 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5646 if (activity.pendingResults == null) { 5647 activity.pendingResults 5648 = new HashSet<WeakReference<PendingIntentRecord>>(); 5649 } 5650 activity.pendingResults.add(rec.ref); 5651 } 5652 return rec; 5653 } 5654 5655 @Override 5656 public void cancelIntentSender(IIntentSender sender) { 5657 if (!(sender instanceof PendingIntentRecord)) { 5658 return; 5659 } 5660 synchronized(this) { 5661 PendingIntentRecord rec = (PendingIntentRecord)sender; 5662 try { 5663 int uid = AppGlobals.getPackageManager() 5664 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5665 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5666 String msg = "Permission Denial: cancelIntentSender() from pid=" 5667 + Binder.getCallingPid() 5668 + ", uid=" + Binder.getCallingUid() 5669 + " is not allowed to cancel packges " 5670 + rec.key.packageName; 5671 Slog.w(TAG, msg); 5672 throw new SecurityException(msg); 5673 } 5674 } catch (RemoteException e) { 5675 throw new SecurityException(e); 5676 } 5677 cancelIntentSenderLocked(rec, true); 5678 } 5679 } 5680 5681 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5682 rec.canceled = true; 5683 mIntentSenderRecords.remove(rec.key); 5684 if (cleanActivity && rec.key.activity != null) { 5685 rec.key.activity.pendingResults.remove(rec.ref); 5686 } 5687 } 5688 5689 @Override 5690 public String getPackageForIntentSender(IIntentSender pendingResult) { 5691 if (!(pendingResult instanceof PendingIntentRecord)) { 5692 return null; 5693 } 5694 try { 5695 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5696 return res.key.packageName; 5697 } catch (ClassCastException e) { 5698 } 5699 return null; 5700 } 5701 5702 @Override 5703 public int getUidForIntentSender(IIntentSender sender) { 5704 if (sender instanceof PendingIntentRecord) { 5705 try { 5706 PendingIntentRecord res = (PendingIntentRecord)sender; 5707 return res.uid; 5708 } catch (ClassCastException e) { 5709 } 5710 } 5711 return -1; 5712 } 5713 5714 @Override 5715 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5716 if (!(pendingResult instanceof PendingIntentRecord)) { 5717 return false; 5718 } 5719 try { 5720 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5721 if (res.key.allIntents == null) { 5722 return false; 5723 } 5724 for (int i=0; i<res.key.allIntents.length; i++) { 5725 Intent intent = res.key.allIntents[i]; 5726 if (intent.getPackage() != null && intent.getComponent() != null) { 5727 return false; 5728 } 5729 } 5730 return true; 5731 } catch (ClassCastException e) { 5732 } 5733 return false; 5734 } 5735 5736 @Override 5737 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5738 if (!(pendingResult instanceof PendingIntentRecord)) { 5739 return false; 5740 } 5741 try { 5742 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5743 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5744 return true; 5745 } 5746 return false; 5747 } catch (ClassCastException e) { 5748 } 5749 return false; 5750 } 5751 5752 @Override 5753 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5754 if (!(pendingResult instanceof PendingIntentRecord)) { 5755 return null; 5756 } 5757 try { 5758 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5759 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5760 } catch (ClassCastException e) { 5761 } 5762 return null; 5763 } 5764 5765 @Override 5766 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5767 if (!(pendingResult instanceof PendingIntentRecord)) { 5768 return null; 5769 } 5770 try { 5771 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5772 Intent intent = res.key.requestIntent; 5773 if (intent != null) { 5774 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5775 || res.lastTagPrefix.equals(prefix))) { 5776 return res.lastTag; 5777 } 5778 res.lastTagPrefix = prefix; 5779 StringBuilder sb = new StringBuilder(128); 5780 if (prefix != null) { 5781 sb.append(prefix); 5782 } 5783 if (intent.getAction() != null) { 5784 sb.append(intent.getAction()); 5785 } else if (intent.getComponent() != null) { 5786 intent.getComponent().appendShortString(sb); 5787 } else { 5788 sb.append("?"); 5789 } 5790 return res.lastTag = sb.toString(); 5791 } 5792 } catch (ClassCastException e) { 5793 } 5794 return null; 5795 } 5796 5797 @Override 5798 public void setProcessLimit(int max) { 5799 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5800 "setProcessLimit()"); 5801 synchronized (this) { 5802 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5803 mProcessLimitOverride = max; 5804 } 5805 trimApplications(); 5806 } 5807 5808 @Override 5809 public int getProcessLimit() { 5810 synchronized (this) { 5811 return mProcessLimitOverride; 5812 } 5813 } 5814 5815 void foregroundTokenDied(ForegroundToken token) { 5816 synchronized (ActivityManagerService.this) { 5817 synchronized (mPidsSelfLocked) { 5818 ForegroundToken cur 5819 = mForegroundProcesses.get(token.pid); 5820 if (cur != token) { 5821 return; 5822 } 5823 mForegroundProcesses.remove(token.pid); 5824 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5825 if (pr == null) { 5826 return; 5827 } 5828 pr.forcingToForeground = null; 5829 updateProcessForegroundLocked(pr, false, false); 5830 } 5831 updateOomAdjLocked(); 5832 } 5833 } 5834 5835 @Override 5836 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5837 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5838 "setProcessForeground()"); 5839 synchronized(this) { 5840 boolean changed = false; 5841 5842 synchronized (mPidsSelfLocked) { 5843 ProcessRecord pr = mPidsSelfLocked.get(pid); 5844 if (pr == null && isForeground) { 5845 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5846 return; 5847 } 5848 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5849 if (oldToken != null) { 5850 oldToken.token.unlinkToDeath(oldToken, 0); 5851 mForegroundProcesses.remove(pid); 5852 if (pr != null) { 5853 pr.forcingToForeground = null; 5854 } 5855 changed = true; 5856 } 5857 if (isForeground && token != null) { 5858 ForegroundToken newToken = new ForegroundToken() { 5859 @Override 5860 public void binderDied() { 5861 foregroundTokenDied(this); 5862 } 5863 }; 5864 newToken.pid = pid; 5865 newToken.token = token; 5866 try { 5867 token.linkToDeath(newToken, 0); 5868 mForegroundProcesses.put(pid, newToken); 5869 pr.forcingToForeground = token; 5870 changed = true; 5871 } catch (RemoteException e) { 5872 // If the process died while doing this, we will later 5873 // do the cleanup with the process death link. 5874 } 5875 } 5876 } 5877 5878 if (changed) { 5879 updateOomAdjLocked(); 5880 } 5881 } 5882 } 5883 5884 // ========================================================= 5885 // PERMISSIONS 5886 // ========================================================= 5887 5888 static class PermissionController extends IPermissionController.Stub { 5889 ActivityManagerService mActivityManagerService; 5890 PermissionController(ActivityManagerService activityManagerService) { 5891 mActivityManagerService = activityManagerService; 5892 } 5893 5894 @Override 5895 public boolean checkPermission(String permission, int pid, int uid) { 5896 return mActivityManagerService.checkPermission(permission, pid, 5897 uid) == PackageManager.PERMISSION_GRANTED; 5898 } 5899 } 5900 5901 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5902 @Override 5903 public int checkComponentPermission(String permission, int pid, int uid, 5904 int owningUid, boolean exported) { 5905 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5906 owningUid, exported); 5907 } 5908 5909 @Override 5910 public Object getAMSLock() { 5911 return ActivityManagerService.this; 5912 } 5913 } 5914 5915 /** 5916 * This can be called with or without the global lock held. 5917 */ 5918 int checkComponentPermission(String permission, int pid, int uid, 5919 int owningUid, boolean exported) { 5920 // We might be performing an operation on behalf of an indirect binder 5921 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5922 // client identity accordingly before proceeding. 5923 Identity tlsIdentity = sCallerIdentity.get(); 5924 if (tlsIdentity != null) { 5925 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5926 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5927 uid = tlsIdentity.uid; 5928 pid = tlsIdentity.pid; 5929 } 5930 5931 if (pid == MY_PID) { 5932 return PackageManager.PERMISSION_GRANTED; 5933 } 5934 5935 return ActivityManager.checkComponentPermission(permission, uid, 5936 owningUid, exported); 5937 } 5938 5939 /** 5940 * As the only public entry point for permissions checking, this method 5941 * can enforce the semantic that requesting a check on a null global 5942 * permission is automatically denied. (Internally a null permission 5943 * string is used when calling {@link #checkComponentPermission} in cases 5944 * when only uid-based security is needed.) 5945 * 5946 * This can be called with or without the global lock held. 5947 */ 5948 @Override 5949 public int checkPermission(String permission, int pid, int uid) { 5950 if (permission == null) { 5951 return PackageManager.PERMISSION_DENIED; 5952 } 5953 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5954 } 5955 5956 /** 5957 * Binder IPC calls go through the public entry point. 5958 * This can be called with or without the global lock held. 5959 */ 5960 int checkCallingPermission(String permission) { 5961 return checkPermission(permission, 5962 Binder.getCallingPid(), 5963 UserHandle.getAppId(Binder.getCallingUid())); 5964 } 5965 5966 /** 5967 * This can be called with or without the global lock held. 5968 */ 5969 void enforceCallingPermission(String permission, String func) { 5970 if (checkCallingPermission(permission) 5971 == PackageManager.PERMISSION_GRANTED) { 5972 return; 5973 } 5974 5975 String msg = "Permission Denial: " + func + " from pid=" 5976 + Binder.getCallingPid() 5977 + ", uid=" + Binder.getCallingUid() 5978 + " requires " + permission; 5979 Slog.w(TAG, msg); 5980 throw new SecurityException(msg); 5981 } 5982 5983 /** 5984 * Determine if UID is holding permissions required to access {@link Uri} in 5985 * the given {@link ProviderInfo}. Final permission checking is always done 5986 * in {@link ContentProvider}. 5987 */ 5988 private final boolean checkHoldingPermissionsLocked( 5989 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) { 5990 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5991 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5992 5993 if (pi.applicationInfo.uid == uid) { 5994 return true; 5995 } else if (!pi.exported) { 5996 return false; 5997 } 5998 5999 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6000 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6001 try { 6002 // check if target holds top-level <provider> permissions 6003 if (!readMet && pi.readPermission != null 6004 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6005 readMet = true; 6006 } 6007 if (!writeMet && pi.writePermission != null 6008 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6009 writeMet = true; 6010 } 6011 6012 // track if unprotected read/write is allowed; any denied 6013 // <path-permission> below removes this ability 6014 boolean allowDefaultRead = pi.readPermission == null; 6015 boolean allowDefaultWrite = pi.writePermission == null; 6016 6017 // check if target holds any <path-permission> that match uri 6018 final PathPermission[] pps = pi.pathPermissions; 6019 if (pps != null) { 6020 final String path = uri.getPath(); 6021 int i = pps.length; 6022 while (i > 0 && (!readMet || !writeMet)) { 6023 i--; 6024 PathPermission pp = pps[i]; 6025 if (pp.match(path)) { 6026 if (!readMet) { 6027 final String pprperm = pp.getReadPermission(); 6028 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6029 + pprperm + " for " + pp.getPath() 6030 + ": match=" + pp.match(path) 6031 + " check=" + pm.checkUidPermission(pprperm, uid)); 6032 if (pprperm != null) { 6033 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 6034 readMet = true; 6035 } else { 6036 allowDefaultRead = false; 6037 } 6038 } 6039 } 6040 if (!writeMet) { 6041 final String ppwperm = pp.getWritePermission(); 6042 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6043 + ppwperm + " for " + pp.getPath() 6044 + ": match=" + pp.match(path) 6045 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6046 if (ppwperm != null) { 6047 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 6048 writeMet = true; 6049 } else { 6050 allowDefaultWrite = false; 6051 } 6052 } 6053 } 6054 } 6055 } 6056 } 6057 6058 // grant unprotected <provider> read/write, if not blocked by 6059 // <path-permission> above 6060 if (allowDefaultRead) readMet = true; 6061 if (allowDefaultWrite) writeMet = true; 6062 6063 } catch (RemoteException e) { 6064 return false; 6065 } 6066 6067 return readMet && writeMet; 6068 } 6069 6070 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6071 ProviderInfo pi = null; 6072 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6073 if (cpr != null) { 6074 pi = cpr.info; 6075 } else { 6076 try { 6077 pi = AppGlobals.getPackageManager().resolveContentProvider( 6078 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6079 } catch (RemoteException ex) { 6080 } 6081 } 6082 return pi; 6083 } 6084 6085 private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) { 6086 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6087 if (targetUris != null) { 6088 return targetUris.get(uri); 6089 } 6090 return null; 6091 } 6092 6093 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6094 String targetPkg, int targetUid, GrantUri uri) { 6095 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6096 if (targetUris == null) { 6097 targetUris = Maps.newArrayMap(); 6098 mGrantedUriPermissions.put(targetUid, targetUris); 6099 } 6100 6101 UriPermission perm = targetUris.get(uri); 6102 if (perm == null) { 6103 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 6104 targetUris.put(uri, perm); 6105 } 6106 6107 return perm; 6108 } 6109 6110 private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) { 6111 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6112 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6113 : UriPermission.STRENGTH_OWNED; 6114 6115 // Root gets to do everything. 6116 if (uid == 0) { 6117 return true; 6118 } 6119 6120 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6121 if (perms == null) return false; 6122 6123 // First look for exact match 6124 final UriPermission exactPerm = perms.get(new GrantUri(uri, false)); 6125 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6126 return true; 6127 } 6128 6129 // No exact match, look for prefixes 6130 final int N = perms.size(); 6131 for (int i = 0; i < N; i++) { 6132 final UriPermission perm = perms.valueAt(i); 6133 if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri) 6134 && perm.getStrength(modeFlags) >= minStrength) { 6135 return true; 6136 } 6137 } 6138 6139 return false; 6140 } 6141 6142 @Override 6143 public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) { 6144 enforceNotIsolatedCaller("checkUriPermission"); 6145 6146 // Another redirected-binder-call permissions check as in 6147 // {@link checkComponentPermission}. 6148 Identity tlsIdentity = sCallerIdentity.get(); 6149 if (tlsIdentity != null) { 6150 uid = tlsIdentity.uid; 6151 pid = tlsIdentity.pid; 6152 } 6153 6154 // Our own process gets to do everything. 6155 if (pid == MY_PID) { 6156 return PackageManager.PERMISSION_GRANTED; 6157 } 6158 synchronized (this) { 6159 return checkUriPermissionLocked(uri, uid, modeFlags) 6160 ? PackageManager.PERMISSION_GRANTED 6161 : PackageManager.PERMISSION_DENIED; 6162 } 6163 } 6164 6165 /** 6166 * Check if the targetPkg can be granted permission to access uri by 6167 * the callingUid using the given modeFlags. Throws a security exception 6168 * if callingUid is not allowed to do this. Returns the uid of the target 6169 * if the URI permission grant should be performed; returns -1 if it is not 6170 * needed (for example targetPkg already has permission to access the URI). 6171 * If you already know the uid of the target, you can supply it in 6172 * lastTargetUid else set that to -1. 6173 */ 6174 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 6175 Uri uri, final int modeFlags, int lastTargetUid) { 6176 if (!Intent.isAccessUriMode(modeFlags)) { 6177 return -1; 6178 } 6179 6180 if (targetPkg != null) { 6181 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6182 "Checking grant " + targetPkg + " permission to " + uri); 6183 } 6184 6185 final IPackageManager pm = AppGlobals.getPackageManager(); 6186 6187 // If this is not a content: uri, we can't do anything with it. 6188 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 6189 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6190 "Can't grant URI permission for non-content URI: " + uri); 6191 return -1; 6192 } 6193 6194 final String authority = uri.getAuthority(); 6195 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6196 if (pi == null) { 6197 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 6198 return -1; 6199 } 6200 6201 int targetUid = lastTargetUid; 6202 if (targetUid < 0 && targetPkg != null) { 6203 try { 6204 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6205 if (targetUid < 0) { 6206 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6207 "Can't grant URI permission no uid for: " + targetPkg); 6208 return -1; 6209 } 6210 } catch (RemoteException ex) { 6211 return -1; 6212 } 6213 } 6214 6215 if (targetUid >= 0) { 6216 // First... does the target actually need this permission? 6217 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 6218 // No need to grant the target this permission. 6219 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6220 "Target " + targetPkg + " already has full permission to " + uri); 6221 return -1; 6222 } 6223 } else { 6224 // First... there is no target package, so can anyone access it? 6225 boolean allowed = pi.exported; 6226 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6227 if (pi.readPermission != null) { 6228 allowed = false; 6229 } 6230 } 6231 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6232 if (pi.writePermission != null) { 6233 allowed = false; 6234 } 6235 } 6236 if (allowed) { 6237 return -1; 6238 } 6239 } 6240 6241 // Second... is the provider allowing granting of URI permissions? 6242 if (!pi.grantUriPermissions) { 6243 throw new SecurityException("Provider " + pi.packageName 6244 + "/" + pi.name 6245 + " does not allow granting of Uri permissions (uri " 6246 + uri + ")"); 6247 } 6248 if (pi.uriPermissionPatterns != null) { 6249 final int N = pi.uriPermissionPatterns.length; 6250 boolean allowed = false; 6251 for (int i=0; i<N; i++) { 6252 if (pi.uriPermissionPatterns[i] != null 6253 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6254 allowed = true; 6255 break; 6256 } 6257 } 6258 if (!allowed) { 6259 throw new SecurityException("Provider " + pi.packageName 6260 + "/" + pi.name 6261 + " does not allow granting of permission to path of Uri " 6262 + uri); 6263 } 6264 } 6265 6266 // Third... does the caller itself have permission to access 6267 // this uri? 6268 if (callingUid != Process.myUid()) { 6269 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6270 // Require they hold a strong enough Uri permission 6271 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6272 throw new SecurityException("Uid " + callingUid 6273 + " does not have permission to uri " + uri); 6274 } 6275 } 6276 } 6277 6278 return targetUid; 6279 } 6280 6281 @Override 6282 public int checkGrantUriPermission(int callingUid, String targetPkg, 6283 Uri uri, final int modeFlags) { 6284 enforceNotIsolatedCaller("checkGrantUriPermission"); 6285 synchronized(this) { 6286 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6287 } 6288 } 6289 6290 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri, 6291 final int modeFlags, UriPermissionOwner owner) { 6292 if (!Intent.isAccessUriMode(modeFlags)) { 6293 return; 6294 } 6295 6296 // So here we are: the caller has the assumed permission 6297 // to the uri, and the target doesn't. Let's now give this to 6298 // the target. 6299 6300 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6301 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6302 6303 final String authority = uri.getAuthority(); 6304 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6305 if (pi == null) { 6306 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6307 return; 6308 } 6309 6310 final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0; 6311 final UriPermission perm = findOrCreateUriPermissionLocked( 6312 pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix)); 6313 perm.grantModes(modeFlags, owner); 6314 } 6315 6316 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6317 final int modeFlags, UriPermissionOwner owner) { 6318 if (targetPkg == null) { 6319 throw new NullPointerException("targetPkg"); 6320 } 6321 6322 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6323 if (targetUid < 0) { 6324 return; 6325 } 6326 6327 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6328 } 6329 6330 static class NeededUriGrants extends ArrayList<Uri> { 6331 final String targetPkg; 6332 final int targetUid; 6333 final int flags; 6334 6335 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6336 this.targetPkg = targetPkg; 6337 this.targetUid = targetUid; 6338 this.flags = flags; 6339 } 6340 } 6341 6342 /** 6343 * Like checkGrantUriPermissionLocked, but takes an Intent. 6344 */ 6345 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6346 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6347 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6348 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6349 + " clip=" + (intent != null ? intent.getClipData() : null) 6350 + " from " + intent + "; flags=0x" 6351 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6352 6353 if (targetPkg == null) { 6354 throw new NullPointerException("targetPkg"); 6355 } 6356 6357 if (intent == null) { 6358 return null; 6359 } 6360 Uri data = intent.getData(); 6361 ClipData clip = intent.getClipData(); 6362 if (data == null && clip == null) { 6363 return null; 6364 } 6365 6366 if (data != null) { 6367 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6368 mode, needed != null ? needed.targetUid : -1); 6369 if (targetUid > 0) { 6370 if (needed == null) { 6371 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6372 } 6373 needed.add(data); 6374 } 6375 } 6376 if (clip != null) { 6377 for (int i=0; i<clip.getItemCount(); i++) { 6378 Uri uri = clip.getItemAt(i).getUri(); 6379 if (uri != null) { 6380 int targetUid = -1; 6381 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6382 mode, needed != null ? needed.targetUid : -1); 6383 if (targetUid > 0) { 6384 if (needed == null) { 6385 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6386 } 6387 needed.add(uri); 6388 } 6389 } else { 6390 Intent clipIntent = clip.getItemAt(i).getIntent(); 6391 if (clipIntent != null) { 6392 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6393 callingUid, targetPkg, clipIntent, mode, needed); 6394 if (newNeeded != null) { 6395 needed = newNeeded; 6396 } 6397 } 6398 } 6399 } 6400 } 6401 6402 return needed; 6403 } 6404 6405 /** 6406 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6407 */ 6408 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6409 UriPermissionOwner owner) { 6410 if (needed != null) { 6411 for (int i=0; i<needed.size(); i++) { 6412 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6413 needed.get(i), needed.flags, owner); 6414 } 6415 } 6416 } 6417 6418 void grantUriPermissionFromIntentLocked(int callingUid, 6419 String targetPkg, Intent intent, UriPermissionOwner owner) { 6420 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6421 intent, intent != null ? intent.getFlags() : 0, null); 6422 if (needed == null) { 6423 return; 6424 } 6425 6426 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6427 } 6428 6429 @Override 6430 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6431 Uri uri, final int modeFlags) { 6432 enforceNotIsolatedCaller("grantUriPermission"); 6433 synchronized(this) { 6434 final ProcessRecord r = getRecordForAppLocked(caller); 6435 if (r == null) { 6436 throw new SecurityException("Unable to find app for caller " 6437 + caller 6438 + " when granting permission to uri " + uri); 6439 } 6440 if (targetPkg == null) { 6441 throw new IllegalArgumentException("null target"); 6442 } 6443 if (uri == null) { 6444 throw new IllegalArgumentException("null uri"); 6445 } 6446 6447 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6448 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6449 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6450 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6451 6452 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null); 6453 } 6454 } 6455 6456 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6457 if (perm.modeFlags == 0) { 6458 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6459 perm.targetUid); 6460 if (perms != null) { 6461 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6462 "Removing " + perm.targetUid + " permission to " + perm.uri); 6463 6464 perms.remove(perm.uri); 6465 if (perms.isEmpty()) { 6466 mGrantedUriPermissions.remove(perm.targetUid); 6467 } 6468 } 6469 } 6470 } 6471 6472 private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) { 6473 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6474 6475 final IPackageManager pm = AppGlobals.getPackageManager(); 6476 final String authority = uri.getAuthority(); 6477 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6478 if (pi == null) { 6479 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6480 return; 6481 } 6482 6483 // Does the caller have this permission on the URI? 6484 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6485 // Right now, if you are not the original owner of the permission, 6486 // you are not allowed to revoke it. 6487 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6488 throw new SecurityException("Uid " + callingUid 6489 + " does not have permission to uri " + uri); 6490 //} 6491 } 6492 6493 boolean persistChanged = false; 6494 6495 // Go through all of the permissions and remove any that match. 6496 int N = mGrantedUriPermissions.size(); 6497 for (int i = 0; i < N; i++) { 6498 final int targetUid = mGrantedUriPermissions.keyAt(i); 6499 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6500 6501 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6502 final UriPermission perm = it.next(); 6503 if (perm.uri.uri.isPathPrefixMatch(uri)) { 6504 if (DEBUG_URI_PERMISSION) 6505 Slog.v(TAG, 6506 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6507 persistChanged |= perm.revokeModes( 6508 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6509 if (perm.modeFlags == 0) { 6510 it.remove(); 6511 } 6512 } 6513 } 6514 6515 if (perms.isEmpty()) { 6516 mGrantedUriPermissions.remove(targetUid); 6517 N--; 6518 i--; 6519 } 6520 } 6521 6522 if (persistChanged) { 6523 schedulePersistUriGrants(); 6524 } 6525 } 6526 6527 @Override 6528 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6529 final int modeFlags) { 6530 enforceNotIsolatedCaller("revokeUriPermission"); 6531 synchronized(this) { 6532 final ProcessRecord r = getRecordForAppLocked(caller); 6533 if (r == null) { 6534 throw new SecurityException("Unable to find app for caller " 6535 + caller 6536 + " when revoking permission to uri " + uri); 6537 } 6538 if (uri == null) { 6539 Slog.w(TAG, "revokeUriPermission: null uri"); 6540 return; 6541 } 6542 6543 if (!Intent.isAccessUriMode(modeFlags)) { 6544 return; 6545 } 6546 6547 final IPackageManager pm = AppGlobals.getPackageManager(); 6548 final String authority = uri.getAuthority(); 6549 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6550 if (pi == null) { 6551 Slog.w(TAG, "No content provider found for permission revoke: " 6552 + uri.toSafeString()); 6553 return; 6554 } 6555 6556 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6557 } 6558 } 6559 6560 /** 6561 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6562 * given package. 6563 * 6564 * @param packageName Package name to match, or {@code null} to apply to all 6565 * packages. 6566 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6567 * to all users. 6568 * @param persistable If persistable grants should be removed. 6569 */ 6570 private void removeUriPermissionsForPackageLocked( 6571 String packageName, int userHandle, boolean persistable) { 6572 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6573 throw new IllegalArgumentException("Must narrow by either package or user"); 6574 } 6575 6576 boolean persistChanged = false; 6577 6578 int N = mGrantedUriPermissions.size(); 6579 for (int i = 0; i < N; i++) { 6580 final int targetUid = mGrantedUriPermissions.keyAt(i); 6581 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6582 6583 // Only inspect grants matching user 6584 if (userHandle == UserHandle.USER_ALL 6585 || userHandle == UserHandle.getUserId(targetUid)) { 6586 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6587 final UriPermission perm = it.next(); 6588 6589 // Only inspect grants matching package 6590 if (packageName == null || perm.sourcePkg.equals(packageName) 6591 || perm.targetPkg.equals(packageName)) { 6592 persistChanged |= perm.revokeModes( 6593 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6594 6595 // Only remove when no modes remain; any persisted grants 6596 // will keep this alive. 6597 if (perm.modeFlags == 0) { 6598 it.remove(); 6599 } 6600 } 6601 } 6602 6603 if (perms.isEmpty()) { 6604 mGrantedUriPermissions.remove(targetUid); 6605 N--; 6606 i--; 6607 } 6608 } 6609 } 6610 6611 if (persistChanged) { 6612 schedulePersistUriGrants(); 6613 } 6614 } 6615 6616 @Override 6617 public IBinder newUriPermissionOwner(String name) { 6618 enforceNotIsolatedCaller("newUriPermissionOwner"); 6619 synchronized(this) { 6620 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6621 return owner.getExternalTokenLocked(); 6622 } 6623 } 6624 6625 @Override 6626 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6627 Uri uri, final int modeFlags) { 6628 synchronized(this) { 6629 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6630 if (owner == null) { 6631 throw new IllegalArgumentException("Unknown owner: " + token); 6632 } 6633 if (fromUid != Binder.getCallingUid()) { 6634 if (Binder.getCallingUid() != Process.myUid()) { 6635 // Only system code can grant URI permissions on behalf 6636 // of other users. 6637 throw new SecurityException("nice try"); 6638 } 6639 } 6640 if (targetPkg == null) { 6641 throw new IllegalArgumentException("null target"); 6642 } 6643 if (uri == null) { 6644 throw new IllegalArgumentException("null uri"); 6645 } 6646 6647 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6648 } 6649 } 6650 6651 @Override 6652 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6653 synchronized(this) { 6654 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6655 if (owner == null) { 6656 throw new IllegalArgumentException("Unknown owner: " + token); 6657 } 6658 6659 if (uri == null) { 6660 owner.removeUriPermissionsLocked(mode); 6661 } else { 6662 owner.removeUriPermissionLocked(uri, mode); 6663 } 6664 } 6665 } 6666 6667 private void schedulePersistUriGrants() { 6668 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6669 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6670 10 * DateUtils.SECOND_IN_MILLIS); 6671 } 6672 } 6673 6674 private void writeGrantedUriPermissions() { 6675 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6676 6677 // Snapshot permissions so we can persist without lock 6678 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6679 synchronized (this) { 6680 final int size = mGrantedUriPermissions.size(); 6681 for (int i = 0; i < size; i++) { 6682 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6683 for (UriPermission perm : perms.values()) { 6684 if (perm.persistedModeFlags != 0) { 6685 persist.add(perm.snapshot()); 6686 } 6687 } 6688 } 6689 } 6690 6691 FileOutputStream fos = null; 6692 try { 6693 fos = mGrantFile.startWrite(); 6694 6695 XmlSerializer out = new FastXmlSerializer(); 6696 out.setOutput(fos, "utf-8"); 6697 out.startDocument(null, true); 6698 out.startTag(null, TAG_URI_GRANTS); 6699 for (UriPermission.Snapshot perm : persist) { 6700 out.startTag(null, TAG_URI_GRANT); 6701 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6702 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6703 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6704 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6705 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6706 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6707 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6708 out.endTag(null, TAG_URI_GRANT); 6709 } 6710 out.endTag(null, TAG_URI_GRANTS); 6711 out.endDocument(); 6712 6713 mGrantFile.finishWrite(fos); 6714 } catch (IOException e) { 6715 if (fos != null) { 6716 mGrantFile.failWrite(fos); 6717 } 6718 } 6719 } 6720 6721 private void readGrantedUriPermissionsLocked() { 6722 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6723 6724 final long now = System.currentTimeMillis(); 6725 6726 FileInputStream fis = null; 6727 try { 6728 fis = mGrantFile.openRead(); 6729 final XmlPullParser in = Xml.newPullParser(); 6730 in.setInput(fis, null); 6731 6732 int type; 6733 while ((type = in.next()) != END_DOCUMENT) { 6734 final String tag = in.getName(); 6735 if (type == START_TAG) { 6736 if (TAG_URI_GRANT.equals(tag)) { 6737 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6738 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6739 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6740 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6741 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6742 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6743 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6744 6745 // Sanity check that provider still belongs to source package 6746 final ProviderInfo pi = getProviderInfoLocked( 6747 uri.getAuthority(), userHandle); 6748 if (pi != null && sourcePkg.equals(pi.packageName)) { 6749 int targetUid = -1; 6750 try { 6751 targetUid = AppGlobals.getPackageManager() 6752 .getPackageUid(targetPkg, userHandle); 6753 } catch (RemoteException e) { 6754 } 6755 if (targetUid != -1) { 6756 final UriPermission perm = findOrCreateUriPermissionLocked( 6757 sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix)); 6758 perm.initPersistedModes(modeFlags, createdTime); 6759 } 6760 } else { 6761 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6762 + " but instead found " + pi); 6763 } 6764 } 6765 } 6766 } 6767 } catch (FileNotFoundException e) { 6768 // Missing grants is okay 6769 } catch (IOException e) { 6770 Log.wtf(TAG, "Failed reading Uri grants", e); 6771 } catch (XmlPullParserException e) { 6772 Log.wtf(TAG, "Failed reading Uri grants", e); 6773 } finally { 6774 IoUtils.closeQuietly(fis); 6775 } 6776 } 6777 6778 @Override 6779 public void takePersistableUriPermission(Uri uri, final int modeFlags) { 6780 enforceNotIsolatedCaller("takePersistableUriPermission"); 6781 6782 Preconditions.checkFlagsArgument(modeFlags, 6783 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6784 6785 synchronized (this) { 6786 final int callingUid = Binder.getCallingUid(); 6787 boolean persistChanged = false; 6788 6789 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6790 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6791 6792 final boolean exactValid = (exactPerm != null) 6793 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6794 final boolean prefixValid = (prefixPerm != null) 6795 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6796 6797 if (!(exactValid || prefixValid)) { 6798 throw new SecurityException("No persistable permission grants found for UID " 6799 + callingUid + " and Uri " + uri.toSafeString()); 6800 } 6801 6802 if (exactValid) { 6803 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6804 } 6805 if (prefixValid) { 6806 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6807 } 6808 6809 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6810 6811 if (persistChanged) { 6812 schedulePersistUriGrants(); 6813 } 6814 } 6815 } 6816 6817 @Override 6818 public void releasePersistableUriPermission(Uri uri, final int modeFlags) { 6819 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6820 6821 Preconditions.checkFlagsArgument(modeFlags, 6822 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6823 6824 synchronized (this) { 6825 final int callingUid = Binder.getCallingUid(); 6826 boolean persistChanged = false; 6827 6828 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6829 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6830 if (exactPerm == null && prefixPerm == null) { 6831 throw new SecurityException("No permission grants found for UID " + callingUid 6832 + " and Uri " + uri.toSafeString()); 6833 } 6834 6835 if (exactPerm != null) { 6836 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6837 removeUriPermissionIfNeededLocked(exactPerm); 6838 } 6839 if (prefixPerm != null) { 6840 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6841 removeUriPermissionIfNeededLocked(prefixPerm); 6842 } 6843 6844 if (persistChanged) { 6845 schedulePersistUriGrants(); 6846 } 6847 } 6848 } 6849 6850 /** 6851 * Prune any older {@link UriPermission} for the given UID until outstanding 6852 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6853 * 6854 * @return if any mutations occured that require persisting. 6855 */ 6856 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6857 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6858 if (perms == null) return false; 6859 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6860 6861 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6862 for (UriPermission perm : perms.values()) { 6863 if (perm.persistedModeFlags != 0) { 6864 persisted.add(perm); 6865 } 6866 } 6867 6868 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6869 if (trimCount <= 0) return false; 6870 6871 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6872 for (int i = 0; i < trimCount; i++) { 6873 final UriPermission perm = persisted.get(i); 6874 6875 if (DEBUG_URI_PERMISSION) { 6876 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6877 } 6878 6879 perm.releasePersistableModes(~0); 6880 removeUriPermissionIfNeededLocked(perm); 6881 } 6882 6883 return true; 6884 } 6885 6886 @Override 6887 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6888 String packageName, boolean incoming) { 6889 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6890 Preconditions.checkNotNull(packageName, "packageName"); 6891 6892 final int callingUid = Binder.getCallingUid(); 6893 final IPackageManager pm = AppGlobals.getPackageManager(); 6894 try { 6895 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6896 if (packageUid != callingUid) { 6897 throw new SecurityException( 6898 "Package " + packageName + " does not belong to calling UID " + callingUid); 6899 } 6900 } catch (RemoteException e) { 6901 throw new SecurityException("Failed to verify package name ownership"); 6902 } 6903 6904 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6905 synchronized (this) { 6906 if (incoming) { 6907 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6908 callingUid); 6909 if (perms == null) { 6910 Slog.w(TAG, "No permission grants found for " + packageName); 6911 } else { 6912 for (UriPermission perm : perms.values()) { 6913 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6914 result.add(perm.buildPersistedPublicApiObject()); 6915 } 6916 } 6917 } 6918 } else { 6919 final int size = mGrantedUriPermissions.size(); 6920 for (int i = 0; i < size; i++) { 6921 final ArrayMap<GrantUri, UriPermission> perms = 6922 mGrantedUriPermissions.valueAt(i); 6923 for (UriPermission perm : perms.values()) { 6924 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6925 result.add(perm.buildPersistedPublicApiObject()); 6926 } 6927 } 6928 } 6929 } 6930 } 6931 return new ParceledListSlice<android.content.UriPermission>(result); 6932 } 6933 6934 @Override 6935 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6936 synchronized (this) { 6937 ProcessRecord app = 6938 who != null ? getRecordForAppLocked(who) : null; 6939 if (app == null) return; 6940 6941 Message msg = Message.obtain(); 6942 msg.what = WAIT_FOR_DEBUGGER_MSG; 6943 msg.obj = app; 6944 msg.arg1 = waiting ? 1 : 0; 6945 mHandler.sendMessage(msg); 6946 } 6947 } 6948 6949 @Override 6950 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6951 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6952 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6953 outInfo.availMem = Process.getFreeMemory(); 6954 outInfo.totalMem = Process.getTotalMemory(); 6955 outInfo.threshold = homeAppMem; 6956 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6957 outInfo.hiddenAppThreshold = cachedAppMem; 6958 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6959 ProcessList.SERVICE_ADJ); 6960 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6961 ProcessList.VISIBLE_APP_ADJ); 6962 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6963 ProcessList.FOREGROUND_APP_ADJ); 6964 } 6965 6966 // ========================================================= 6967 // TASK MANAGEMENT 6968 // ========================================================= 6969 6970 @Override 6971 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 6972 final int callingUid = Binder.getCallingUid(); 6973 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6974 6975 synchronized(this) { 6976 if (localLOGV) Slog.v( 6977 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 6978 6979 final boolean allowed = checkCallingPermission( 6980 android.Manifest.permission.GET_TASKS) 6981 == PackageManager.PERMISSION_GRANTED; 6982 if (!allowed) { 6983 Slog.w(TAG, "getTasks: caller " + callingUid 6984 + " does not hold GET_TASKS; limiting output"); 6985 } 6986 6987 // TODO: Improve with MRU list from all ActivityStacks. 6988 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 6989 } 6990 6991 return list; 6992 } 6993 6994 TaskRecord getMostRecentTask() { 6995 return mRecentTasks.get(0); 6996 } 6997 6998 @Override 6999 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7000 int flags, int userId) { 7001 final int callingUid = Binder.getCallingUid(); 7002 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7003 false, true, "getRecentTasks", null); 7004 7005 synchronized (this) { 7006 final boolean allowed = checkCallingPermission( 7007 android.Manifest.permission.GET_TASKS) 7008 == PackageManager.PERMISSION_GRANTED; 7009 if (!allowed) { 7010 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7011 + " does not hold GET_TASKS; limiting output"); 7012 } 7013 final boolean detailed = checkCallingPermission( 7014 android.Manifest.permission.GET_DETAILED_TASKS) 7015 == PackageManager.PERMISSION_GRANTED; 7016 7017 IPackageManager pm = AppGlobals.getPackageManager(); 7018 7019 final int N = mRecentTasks.size(); 7020 ArrayList<ActivityManager.RecentTaskInfo> res 7021 = new ArrayList<ActivityManager.RecentTaskInfo>( 7022 maxNum < N ? maxNum : N); 7023 7024 final Set<Integer> includedUsers; 7025 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7026 includedUsers = getProfileIdsLocked(userId); 7027 } else { 7028 includedUsers = new HashSet<Integer>(); 7029 } 7030 includedUsers.add(Integer.valueOf(userId)); 7031 for (int i=0; i<N && maxNum > 0; i++) { 7032 TaskRecord tr = mRecentTasks.get(i); 7033 // Only add calling user or related users recent tasks 7034 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7035 7036 // Return the entry if desired by the caller. We always return 7037 // the first entry, because callers always expect this to be the 7038 // foreground app. We may filter others if the caller has 7039 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7040 // we should exclude the entry. 7041 7042 if (i == 0 7043 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7044 || (tr.intent == null) 7045 || ((tr.intent.getFlags() 7046 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7047 if (!allowed) { 7048 // If the caller doesn't have the GET_TASKS permission, then only 7049 // allow them to see a small subset of tasks -- their own and home. 7050 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7051 continue; 7052 } 7053 } 7054 ActivityManager.RecentTaskInfo rti 7055 = new ActivityManager.RecentTaskInfo(); 7056 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 7057 rti.persistentId = tr.taskId; 7058 rti.baseIntent = new Intent( 7059 tr.intent != null ? tr.intent : tr.affinityIntent); 7060 if (!detailed) { 7061 rti.baseIntent.replaceExtras((Bundle)null); 7062 } 7063 rti.origActivity = tr.origActivity; 7064 rti.description = tr.lastDescription; 7065 rti.stackId = tr.stack.mStackId; 7066 rti.userId = tr.userId; 7067 7068 // Traverse upwards looking for any break between main task activities and 7069 // utility activities. 7070 final ArrayList<ActivityRecord> activities = tr.mActivities; 7071 int activityNdx; 7072 final int numActivities = activities.size(); 7073 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities; 7074 ++activityNdx) { 7075 final ActivityRecord r = activities.get(activityNdx); 7076 if (r.intent != null && 7077 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) 7078 != 0) { 7079 break; 7080 } 7081 } 7082 if (activityNdx > 0) { 7083 // Traverse downwards starting below break looking for set label, icon. 7084 // Note that if there are activities in the task but none of them set the 7085 // recent activity values, then we do not fall back to the last set 7086 // values in the TaskRecord. 7087 rti.activityValues = new ActivityManager.RecentsActivityValues(); 7088 for (--activityNdx; activityNdx >= 0; --activityNdx) { 7089 final ActivityRecord r = activities.get(activityNdx); 7090 if (r.activityValues != null) { 7091 if (rti.activityValues.label == null) { 7092 rti.activityValues.label = r.activityValues.label; 7093 tr.lastActivityValues.label = r.activityValues.label; 7094 } 7095 if (rti.activityValues.icon == null) { 7096 rti.activityValues.icon = r.activityValues.icon; 7097 tr.lastActivityValues.icon = r.activityValues.icon; 7098 } 7099 if (rti.activityValues.colorPrimary == 0) { 7100 rti.activityValues.colorPrimary = r.activityValues.colorPrimary; 7101 tr.lastActivityValues.colorPrimary = r.activityValues.colorPrimary; 7102 } 7103 } 7104 } 7105 } else { 7106 // If there are no activity records in this task, then we use the last 7107 // resolved values 7108 rti.activityValues = 7109 new ActivityManager.RecentsActivityValues(tr.lastActivityValues); 7110 } 7111 7112 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7113 // Check whether this activity is currently available. 7114 try { 7115 if (rti.origActivity != null) { 7116 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7117 == null) { 7118 continue; 7119 } 7120 } else if (rti.baseIntent != null) { 7121 if (pm.queryIntentActivities(rti.baseIntent, 7122 null, 0, userId) == null) { 7123 continue; 7124 } 7125 } 7126 } catch (RemoteException e) { 7127 // Will never happen. 7128 } 7129 } 7130 7131 res.add(rti); 7132 maxNum--; 7133 } 7134 } 7135 return res; 7136 } 7137 } 7138 7139 private TaskRecord recentTaskForIdLocked(int id) { 7140 final int N = mRecentTasks.size(); 7141 for (int i=0; i<N; i++) { 7142 TaskRecord tr = mRecentTasks.get(i); 7143 if (tr.taskId == id) { 7144 return tr; 7145 } 7146 } 7147 return null; 7148 } 7149 7150 @Override 7151 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7152 synchronized (this) { 7153 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7154 "getTaskThumbnails()"); 7155 TaskRecord tr = recentTaskForIdLocked(id); 7156 if (tr != null) { 7157 return tr.getTaskThumbnailsLocked(); 7158 } 7159 } 7160 return null; 7161 } 7162 7163 @Override 7164 public Bitmap getTaskTopThumbnail(int id) { 7165 synchronized (this) { 7166 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7167 "getTaskTopThumbnail()"); 7168 TaskRecord tr = recentTaskForIdLocked(id); 7169 if (tr != null) { 7170 return tr.getTaskTopThumbnailLocked(); 7171 } 7172 } 7173 return null; 7174 } 7175 7176 @Override 7177 public void setRecentsActivityValues(IBinder token, ActivityManager.RecentsActivityValues rav) { 7178 synchronized (this) { 7179 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7180 if (r != null) { 7181 r.activityValues = rav; 7182 } 7183 } 7184 } 7185 7186 @Override 7187 public boolean removeSubTask(int taskId, int subTaskIndex) { 7188 synchronized (this) { 7189 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7190 "removeSubTask()"); 7191 long ident = Binder.clearCallingIdentity(); 7192 try { 7193 TaskRecord tr = recentTaskForIdLocked(taskId); 7194 if (tr != null) { 7195 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7196 } 7197 return false; 7198 } finally { 7199 Binder.restoreCallingIdentity(ident); 7200 } 7201 } 7202 } 7203 7204 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7205 if (!pr.killedByAm) { 7206 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7207 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7208 pr.processName, pr.setAdj, reason); 7209 pr.killedByAm = true; 7210 Process.killProcessQuiet(pr.pid); 7211 } 7212 } 7213 7214 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7215 tr.disposeThumbnail(); 7216 mRecentTasks.remove(tr); 7217 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7218 Intent baseIntent = new Intent( 7219 tr.intent != null ? tr.intent : tr.affinityIntent); 7220 ComponentName component = baseIntent.getComponent(); 7221 if (component == null) { 7222 Slog.w(TAG, "Now component for base intent of task: " + tr); 7223 return; 7224 } 7225 7226 // Find any running services associated with this app. 7227 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7228 7229 if (killProcesses) { 7230 // Find any running processes associated with this app. 7231 final String pkg = component.getPackageName(); 7232 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7233 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7234 for (int i=0; i<pmap.size(); i++) { 7235 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7236 for (int j=0; j<uids.size(); j++) { 7237 ProcessRecord proc = uids.valueAt(j); 7238 if (proc.userId != tr.userId) { 7239 continue; 7240 } 7241 if (!proc.pkgList.containsKey(pkg)) { 7242 continue; 7243 } 7244 procs.add(proc); 7245 } 7246 } 7247 7248 // Kill the running processes. 7249 for (int i=0; i<procs.size(); i++) { 7250 ProcessRecord pr = procs.get(i); 7251 if (pr == mHomeProcess) { 7252 // Don't kill the home process along with tasks from the same package. 7253 continue; 7254 } 7255 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7256 killUnneededProcessLocked(pr, "remove task"); 7257 } else { 7258 pr.waitingToKill = "remove task"; 7259 } 7260 } 7261 } 7262 } 7263 7264 /** 7265 * Removes the task with the specified task id. 7266 * 7267 * @param taskId Identifier of the task to be removed. 7268 * @param flags Additional operational flags. May be 0 or 7269 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7270 * @return Returns true if the given task was found and removed. 7271 */ 7272 private boolean removeTaskByIdLocked(int taskId, int flags) { 7273 TaskRecord tr = recentTaskForIdLocked(taskId); 7274 if (tr != null) { 7275 tr.removeTaskActivitiesLocked(-1, false); 7276 cleanUpRemovedTaskLocked(tr, flags); 7277 return true; 7278 } 7279 return false; 7280 } 7281 7282 @Override 7283 public boolean removeTask(int taskId, int flags) { 7284 synchronized (this) { 7285 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7286 "removeTask()"); 7287 long ident = Binder.clearCallingIdentity(); 7288 try { 7289 return removeTaskByIdLocked(taskId, flags); 7290 } finally { 7291 Binder.restoreCallingIdentity(ident); 7292 } 7293 } 7294 } 7295 7296 /** 7297 * TODO: Add mController hook 7298 */ 7299 @Override 7300 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7301 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7302 "moveTaskToFront()"); 7303 7304 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7305 synchronized(this) { 7306 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7307 Binder.getCallingUid(), "Task to front")) { 7308 ActivityOptions.abort(options); 7309 return; 7310 } 7311 final long origId = Binder.clearCallingIdentity(); 7312 try { 7313 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7314 if (task == null) { 7315 return; 7316 } 7317 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7318 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7319 return; 7320 } 7321 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7322 } finally { 7323 Binder.restoreCallingIdentity(origId); 7324 } 7325 ActivityOptions.abort(options); 7326 } 7327 } 7328 7329 @Override 7330 public void moveTaskToBack(int taskId) { 7331 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7332 "moveTaskToBack()"); 7333 7334 synchronized(this) { 7335 TaskRecord tr = recentTaskForIdLocked(taskId); 7336 if (tr != null) { 7337 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7338 ActivityStack stack = tr.stack; 7339 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7340 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7341 Binder.getCallingUid(), "Task to back")) { 7342 return; 7343 } 7344 } 7345 final long origId = Binder.clearCallingIdentity(); 7346 try { 7347 stack.moveTaskToBackLocked(taskId, null); 7348 } finally { 7349 Binder.restoreCallingIdentity(origId); 7350 } 7351 } 7352 } 7353 } 7354 7355 /** 7356 * Moves an activity, and all of the other activities within the same task, to the bottom 7357 * of the history stack. The activity's order within the task is unchanged. 7358 * 7359 * @param token A reference to the activity we wish to move 7360 * @param nonRoot If false then this only works if the activity is the root 7361 * of a task; if true it will work for any activity in a task. 7362 * @return Returns true if the move completed, false if not. 7363 */ 7364 @Override 7365 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7366 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7367 synchronized(this) { 7368 final long origId = Binder.clearCallingIdentity(); 7369 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7370 if (taskId >= 0) { 7371 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7372 } 7373 Binder.restoreCallingIdentity(origId); 7374 } 7375 return false; 7376 } 7377 7378 @Override 7379 public void moveTaskBackwards(int task) { 7380 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7381 "moveTaskBackwards()"); 7382 7383 synchronized(this) { 7384 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7385 Binder.getCallingUid(), "Task backwards")) { 7386 return; 7387 } 7388 final long origId = Binder.clearCallingIdentity(); 7389 moveTaskBackwardsLocked(task); 7390 Binder.restoreCallingIdentity(origId); 7391 } 7392 } 7393 7394 private final void moveTaskBackwardsLocked(int task) { 7395 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7396 } 7397 7398 @Override 7399 public IBinder getHomeActivityToken() throws RemoteException { 7400 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7401 "getHomeActivityToken()"); 7402 synchronized (this) { 7403 return mStackSupervisor.getHomeActivityToken(); 7404 } 7405 } 7406 7407 @Override 7408 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7409 IActivityContainerCallback callback) throws RemoteException { 7410 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7411 "createActivityContainer()"); 7412 synchronized (this) { 7413 if (parentActivityToken == null) { 7414 throw new IllegalArgumentException("parent token must not be null"); 7415 } 7416 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7417 if (r == null) { 7418 return null; 7419 } 7420 if (callback == null) { 7421 throw new IllegalArgumentException("callback must not be null"); 7422 } 7423 return mStackSupervisor.createActivityContainer(r, callback); 7424 } 7425 } 7426 7427 @Override 7428 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7429 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7430 "deleteActivityContainer()"); 7431 synchronized (this) { 7432 mStackSupervisor.deleteActivityContainer(container); 7433 } 7434 } 7435 7436 @Override 7437 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7438 throws RemoteException { 7439 synchronized (this) { 7440 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7441 if (stack != null) { 7442 return stack.mActivityContainer; 7443 } 7444 return null; 7445 } 7446 } 7447 7448 @Override 7449 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7450 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7451 "moveTaskToStack()"); 7452 if (stackId == HOME_STACK_ID) { 7453 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7454 new RuntimeException("here").fillInStackTrace()); 7455 } 7456 synchronized (this) { 7457 long ident = Binder.clearCallingIdentity(); 7458 try { 7459 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7460 + stackId + " toTop=" + toTop); 7461 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7462 } finally { 7463 Binder.restoreCallingIdentity(ident); 7464 } 7465 } 7466 } 7467 7468 @Override 7469 public void resizeStack(int stackBoxId, Rect bounds) { 7470 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7471 "resizeStackBox()"); 7472 long ident = Binder.clearCallingIdentity(); 7473 try { 7474 mWindowManager.resizeStack(stackBoxId, bounds); 7475 } finally { 7476 Binder.restoreCallingIdentity(ident); 7477 } 7478 } 7479 7480 @Override 7481 public List<StackInfo> getAllStackInfos() { 7482 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7483 "getAllStackInfos()"); 7484 long ident = Binder.clearCallingIdentity(); 7485 try { 7486 synchronized (this) { 7487 return mStackSupervisor.getAllStackInfosLocked(); 7488 } 7489 } finally { 7490 Binder.restoreCallingIdentity(ident); 7491 } 7492 } 7493 7494 @Override 7495 public StackInfo getStackInfo(int stackId) { 7496 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7497 "getStackInfo()"); 7498 long ident = Binder.clearCallingIdentity(); 7499 try { 7500 synchronized (this) { 7501 return mStackSupervisor.getStackInfoLocked(stackId); 7502 } 7503 } finally { 7504 Binder.restoreCallingIdentity(ident); 7505 } 7506 } 7507 7508 @Override 7509 public boolean isInHomeStack(int taskId) { 7510 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7511 "getStackInfo()"); 7512 long ident = Binder.clearCallingIdentity(); 7513 try { 7514 synchronized (this) { 7515 TaskRecord tr = recentTaskForIdLocked(taskId); 7516 if (tr != null) { 7517 return tr.stack.isHomeStack(); 7518 } 7519 } 7520 } finally { 7521 Binder.restoreCallingIdentity(ident); 7522 } 7523 return false; 7524 } 7525 7526 @Override 7527 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7528 synchronized(this) { 7529 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7530 } 7531 } 7532 7533 private boolean isLockTaskAuthorized(ComponentName name) { 7534// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7535// "startLockTaskMode()"); 7536// DevicePolicyManager dpm = (DevicePolicyManager) 7537// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7538// return dpm != null && dpm.isLockTaskPermitted(name); 7539 return true; 7540 } 7541 7542 private void startLockTaskMode(TaskRecord task) { 7543 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7544 return; 7545 } 7546 long ident = Binder.clearCallingIdentity(); 7547 try { 7548 synchronized (this) { 7549 // Since we lost lock on task, make sure it is still there. 7550 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7551 if (task != null) { 7552 mStackSupervisor.setLockTaskModeLocked(task); 7553 } 7554 } 7555 } finally { 7556 Binder.restoreCallingIdentity(ident); 7557 } 7558 } 7559 7560 @Override 7561 public void startLockTaskMode(int taskId) { 7562 long ident = Binder.clearCallingIdentity(); 7563 try { 7564 final TaskRecord task; 7565 synchronized (this) { 7566 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7567 } 7568 if (task != null) { 7569 startLockTaskMode(task); 7570 } 7571 } finally { 7572 Binder.restoreCallingIdentity(ident); 7573 } 7574 } 7575 7576 @Override 7577 public void startLockTaskMode(IBinder token) { 7578 long ident = Binder.clearCallingIdentity(); 7579 try { 7580 final TaskRecord task; 7581 synchronized (this) { 7582 final ActivityRecord r = ActivityRecord.forToken(token); 7583 if (r == null) { 7584 return; 7585 } 7586 task = r.task; 7587 } 7588 if (task != null) { 7589 startLockTaskMode(task); 7590 } 7591 } finally { 7592 Binder.restoreCallingIdentity(ident); 7593 } 7594 } 7595 7596 @Override 7597 public void stopLockTaskMode() { 7598// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7599// "stopLockTaskMode()"); 7600 synchronized (this) { 7601 mStackSupervisor.setLockTaskModeLocked(null); 7602 } 7603 } 7604 7605 @Override 7606 public boolean isInLockTaskMode() { 7607 synchronized (this) { 7608 return mStackSupervisor.isInLockTaskMode(); 7609 } 7610 } 7611 7612 // ========================================================= 7613 // CONTENT PROVIDERS 7614 // ========================================================= 7615 7616 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7617 List<ProviderInfo> providers = null; 7618 try { 7619 providers = AppGlobals.getPackageManager(). 7620 queryContentProviders(app.processName, app.uid, 7621 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7622 } catch (RemoteException ex) { 7623 } 7624 if (DEBUG_MU) 7625 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7626 int userId = app.userId; 7627 if (providers != null) { 7628 int N = providers.size(); 7629 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7630 for (int i=0; i<N; i++) { 7631 ProviderInfo cpi = 7632 (ProviderInfo)providers.get(i); 7633 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7634 cpi.name, cpi.flags); 7635 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7636 // This is a singleton provider, but a user besides the 7637 // default user is asking to initialize a process it runs 7638 // in... well, no, it doesn't actually run in this process, 7639 // it runs in the process of the default user. Get rid of it. 7640 providers.remove(i); 7641 N--; 7642 i--; 7643 continue; 7644 } 7645 7646 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7647 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7648 if (cpr == null) { 7649 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7650 mProviderMap.putProviderByClass(comp, cpr); 7651 } 7652 if (DEBUG_MU) 7653 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7654 app.pubProviders.put(cpi.name, cpr); 7655 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7656 // Don't add this if it is a platform component that is marked 7657 // to run in multiple processes, because this is actually 7658 // part of the framework so doesn't make sense to track as a 7659 // separate apk in the process. 7660 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7661 } 7662 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7663 } 7664 } 7665 return providers; 7666 } 7667 7668 /** 7669 * Check if {@link ProcessRecord} has a possible chance at accessing the 7670 * given {@link ProviderInfo}. Final permission checking is always done 7671 * in {@link ContentProvider}. 7672 */ 7673 private final String checkContentProviderPermissionLocked( 7674 ProviderInfo cpi, ProcessRecord r) { 7675 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7676 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7677 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7678 cpi.applicationInfo.uid, cpi.exported) 7679 == PackageManager.PERMISSION_GRANTED) { 7680 return null; 7681 } 7682 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7683 cpi.applicationInfo.uid, cpi.exported) 7684 == PackageManager.PERMISSION_GRANTED) { 7685 return null; 7686 } 7687 7688 PathPermission[] pps = cpi.pathPermissions; 7689 if (pps != null) { 7690 int i = pps.length; 7691 while (i > 0) { 7692 i--; 7693 PathPermission pp = pps[i]; 7694 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7695 cpi.applicationInfo.uid, cpi.exported) 7696 == PackageManager.PERMISSION_GRANTED) { 7697 return null; 7698 } 7699 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7700 cpi.applicationInfo.uid, cpi.exported) 7701 == PackageManager.PERMISSION_GRANTED) { 7702 return null; 7703 } 7704 } 7705 } 7706 7707 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7708 if (perms != null) { 7709 for (GrantUri uri : perms.keySet()) { 7710 if (uri.uri.getAuthority().equals(cpi.authority)) { 7711 return null; 7712 } 7713 } 7714 } 7715 7716 String msg; 7717 if (!cpi.exported) { 7718 msg = "Permission Denial: opening provider " + cpi.name 7719 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7720 + ", uid=" + callingUid + ") that is not exported from uid " 7721 + cpi.applicationInfo.uid; 7722 } else { 7723 msg = "Permission Denial: opening provider " + cpi.name 7724 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7725 + ", uid=" + callingUid + ") requires " 7726 + cpi.readPermission + " or " + cpi.writePermission; 7727 } 7728 Slog.w(TAG, msg); 7729 return msg; 7730 } 7731 7732 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7733 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7734 if (r != null) { 7735 for (int i=0; i<r.conProviders.size(); i++) { 7736 ContentProviderConnection conn = r.conProviders.get(i); 7737 if (conn.provider == cpr) { 7738 if (DEBUG_PROVIDER) Slog.v(TAG, 7739 "Adding provider requested by " 7740 + r.processName + " from process " 7741 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7742 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7743 if (stable) { 7744 conn.stableCount++; 7745 conn.numStableIncs++; 7746 } else { 7747 conn.unstableCount++; 7748 conn.numUnstableIncs++; 7749 } 7750 return conn; 7751 } 7752 } 7753 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7754 if (stable) { 7755 conn.stableCount = 1; 7756 conn.numStableIncs = 1; 7757 } else { 7758 conn.unstableCount = 1; 7759 conn.numUnstableIncs = 1; 7760 } 7761 cpr.connections.add(conn); 7762 r.conProviders.add(conn); 7763 return conn; 7764 } 7765 cpr.addExternalProcessHandleLocked(externalProcessToken); 7766 return null; 7767 } 7768 7769 boolean decProviderCountLocked(ContentProviderConnection conn, 7770 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7771 if (conn != null) { 7772 cpr = conn.provider; 7773 if (DEBUG_PROVIDER) Slog.v(TAG, 7774 "Removing provider requested by " 7775 + conn.client.processName + " from process " 7776 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7777 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7778 if (stable) { 7779 conn.stableCount--; 7780 } else { 7781 conn.unstableCount--; 7782 } 7783 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7784 cpr.connections.remove(conn); 7785 conn.client.conProviders.remove(conn); 7786 return true; 7787 } 7788 return false; 7789 } 7790 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7791 return false; 7792 } 7793 7794 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7795 String name, IBinder token, boolean stable, int userId) { 7796 ContentProviderRecord cpr; 7797 ContentProviderConnection conn = null; 7798 ProviderInfo cpi = null; 7799 7800 synchronized(this) { 7801 ProcessRecord r = null; 7802 if (caller != null) { 7803 r = getRecordForAppLocked(caller); 7804 if (r == null) { 7805 throw new SecurityException( 7806 "Unable to find app for caller " + caller 7807 + " (pid=" + Binder.getCallingPid() 7808 + ") when getting content provider " + name); 7809 } 7810 } 7811 7812 // First check if this content provider has been published... 7813 cpr = mProviderMap.getProviderByName(name, userId); 7814 boolean providerRunning = cpr != null; 7815 if (providerRunning) { 7816 cpi = cpr.info; 7817 String msg; 7818 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7819 throw new SecurityException(msg); 7820 } 7821 7822 if (r != null && cpr.canRunHere(r)) { 7823 // This provider has been published or is in the process 7824 // of being published... but it is also allowed to run 7825 // in the caller's process, so don't make a connection 7826 // and just let the caller instantiate its own instance. 7827 ContentProviderHolder holder = cpr.newHolder(null); 7828 // don't give caller the provider object, it needs 7829 // to make its own. 7830 holder.provider = null; 7831 return holder; 7832 } 7833 7834 final long origId = Binder.clearCallingIdentity(); 7835 7836 // In this case the provider instance already exists, so we can 7837 // return it right away. 7838 conn = incProviderCountLocked(r, cpr, token, stable); 7839 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7840 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7841 // If this is a perceptible app accessing the provider, 7842 // make sure to count it as being accessed and thus 7843 // back up on the LRU list. This is good because 7844 // content providers are often expensive to start. 7845 updateLruProcessLocked(cpr.proc, false, null); 7846 } 7847 } 7848 7849 if (cpr.proc != null) { 7850 if (false) { 7851 if (cpr.name.flattenToShortString().equals( 7852 "com.android.providers.calendar/.CalendarProvider2")) { 7853 Slog.v(TAG, "****************** KILLING " 7854 + cpr.name.flattenToShortString()); 7855 Process.killProcess(cpr.proc.pid); 7856 } 7857 } 7858 boolean success = updateOomAdjLocked(cpr.proc); 7859 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7860 // NOTE: there is still a race here where a signal could be 7861 // pending on the process even though we managed to update its 7862 // adj level. Not sure what to do about this, but at least 7863 // the race is now smaller. 7864 if (!success) { 7865 // Uh oh... it looks like the provider's process 7866 // has been killed on us. We need to wait for a new 7867 // process to be started, and make sure its death 7868 // doesn't kill our process. 7869 Slog.i(TAG, 7870 "Existing provider " + cpr.name.flattenToShortString() 7871 + " is crashing; detaching " + r); 7872 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7873 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7874 if (!lastRef) { 7875 // This wasn't the last ref our process had on 7876 // the provider... we have now been killed, bail. 7877 return null; 7878 } 7879 providerRunning = false; 7880 conn = null; 7881 } 7882 } 7883 7884 Binder.restoreCallingIdentity(origId); 7885 } 7886 7887 boolean singleton; 7888 if (!providerRunning) { 7889 try { 7890 cpi = AppGlobals.getPackageManager(). 7891 resolveContentProvider(name, 7892 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7893 } catch (RemoteException ex) { 7894 } 7895 if (cpi == null) { 7896 return null; 7897 } 7898 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7899 cpi.name, cpi.flags); 7900 if (singleton) { 7901 userId = 0; 7902 } 7903 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7904 7905 String msg; 7906 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7907 throw new SecurityException(msg); 7908 } 7909 7910 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7911 && !cpi.processName.equals("system")) { 7912 // If this content provider does not run in the system 7913 // process, and the system is not yet ready to run other 7914 // processes, then fail fast instead of hanging. 7915 throw new IllegalArgumentException( 7916 "Attempt to launch content provider before system ready"); 7917 } 7918 7919 // Make sure that the user who owns this provider is started. If not, 7920 // we don't want to allow it to run. 7921 if (mStartedUsers.get(userId) == null) { 7922 Slog.w(TAG, "Unable to launch app " 7923 + cpi.applicationInfo.packageName + "/" 7924 + cpi.applicationInfo.uid + " for provider " 7925 + name + ": user " + userId + " is stopped"); 7926 return null; 7927 } 7928 7929 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7930 cpr = mProviderMap.getProviderByClass(comp, userId); 7931 final boolean firstClass = cpr == null; 7932 if (firstClass) { 7933 try { 7934 ApplicationInfo ai = 7935 AppGlobals.getPackageManager(). 7936 getApplicationInfo( 7937 cpi.applicationInfo.packageName, 7938 STOCK_PM_FLAGS, userId); 7939 if (ai == null) { 7940 Slog.w(TAG, "No package info for content provider " 7941 + cpi.name); 7942 return null; 7943 } 7944 ai = getAppInfoForUser(ai, userId); 7945 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7946 } catch (RemoteException ex) { 7947 // pm is in same process, this will never happen. 7948 } 7949 } 7950 7951 if (r != null && cpr.canRunHere(r)) { 7952 // If this is a multiprocess provider, then just return its 7953 // info and allow the caller to instantiate it. Only do 7954 // this if the provider is the same user as the caller's 7955 // process, or can run as root (so can be in any process). 7956 return cpr.newHolder(null); 7957 } 7958 7959 if (DEBUG_PROVIDER) { 7960 RuntimeException e = new RuntimeException("here"); 7961 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7962 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7963 } 7964 7965 // This is single process, and our app is now connecting to it. 7966 // See if we are already in the process of launching this 7967 // provider. 7968 final int N = mLaunchingProviders.size(); 7969 int i; 7970 for (i=0; i<N; i++) { 7971 if (mLaunchingProviders.get(i) == cpr) { 7972 break; 7973 } 7974 } 7975 7976 // If the provider is not already being launched, then get it 7977 // started. 7978 if (i >= N) { 7979 final long origId = Binder.clearCallingIdentity(); 7980 7981 try { 7982 // Content provider is now in use, its package can't be stopped. 7983 try { 7984 AppGlobals.getPackageManager().setPackageStoppedState( 7985 cpr.appInfo.packageName, false, userId); 7986 } catch (RemoteException e) { 7987 } catch (IllegalArgumentException e) { 7988 Slog.w(TAG, "Failed trying to unstop package " 7989 + cpr.appInfo.packageName + ": " + e); 7990 } 7991 7992 // Use existing process if already started 7993 ProcessRecord proc = getProcessRecordLocked( 7994 cpi.processName, cpr.appInfo.uid, false); 7995 if (proc != null && proc.thread != null) { 7996 if (DEBUG_PROVIDER) { 7997 Slog.d(TAG, "Installing in existing process " + proc); 7998 } 7999 proc.pubProviders.put(cpi.name, cpr); 8000 try { 8001 proc.thread.scheduleInstallProvider(cpi); 8002 } catch (RemoteException e) { 8003 } 8004 } else { 8005 proc = startProcessLocked(cpi.processName, 8006 cpr.appInfo, false, 0, "content provider", 8007 new ComponentName(cpi.applicationInfo.packageName, 8008 cpi.name), false, false, false); 8009 if (proc == null) { 8010 Slog.w(TAG, "Unable to launch app " 8011 + cpi.applicationInfo.packageName + "/" 8012 + cpi.applicationInfo.uid + " for provider " 8013 + name + ": process is bad"); 8014 return null; 8015 } 8016 } 8017 cpr.launchingApp = proc; 8018 mLaunchingProviders.add(cpr); 8019 } finally { 8020 Binder.restoreCallingIdentity(origId); 8021 } 8022 } 8023 8024 // Make sure the provider is published (the same provider class 8025 // may be published under multiple names). 8026 if (firstClass) { 8027 mProviderMap.putProviderByClass(comp, cpr); 8028 } 8029 8030 mProviderMap.putProviderByName(name, cpr); 8031 conn = incProviderCountLocked(r, cpr, token, stable); 8032 if (conn != null) { 8033 conn.waiting = true; 8034 } 8035 } 8036 } 8037 8038 // Wait for the provider to be published... 8039 synchronized (cpr) { 8040 while (cpr.provider == null) { 8041 if (cpr.launchingApp == null) { 8042 Slog.w(TAG, "Unable to launch app " 8043 + cpi.applicationInfo.packageName + "/" 8044 + cpi.applicationInfo.uid + " for provider " 8045 + name + ": launching app became null"); 8046 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8047 UserHandle.getUserId(cpi.applicationInfo.uid), 8048 cpi.applicationInfo.packageName, 8049 cpi.applicationInfo.uid, name); 8050 return null; 8051 } 8052 try { 8053 if (DEBUG_MU) { 8054 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8055 + cpr.launchingApp); 8056 } 8057 if (conn != null) { 8058 conn.waiting = true; 8059 } 8060 cpr.wait(); 8061 } catch (InterruptedException ex) { 8062 } finally { 8063 if (conn != null) { 8064 conn.waiting = false; 8065 } 8066 } 8067 } 8068 } 8069 return cpr != null ? cpr.newHolder(conn) : null; 8070 } 8071 8072 public final ContentProviderHolder getContentProvider( 8073 IApplicationThread caller, String name, int userId, boolean stable) { 8074 enforceNotIsolatedCaller("getContentProvider"); 8075 if (caller == null) { 8076 String msg = "null IApplicationThread when getting content provider " 8077 + name; 8078 Slog.w(TAG, msg); 8079 throw new SecurityException(msg); 8080 } 8081 8082 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8083 false, true, "getContentProvider", null); 8084 return getContentProviderImpl(caller, name, null, stable, userId); 8085 } 8086 8087 public ContentProviderHolder getContentProviderExternal( 8088 String name, int userId, IBinder token) { 8089 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8090 "Do not have permission in call getContentProviderExternal()"); 8091 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8092 false, true, "getContentProvider", null); 8093 return getContentProviderExternalUnchecked(name, token, userId); 8094 } 8095 8096 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8097 IBinder token, int userId) { 8098 return getContentProviderImpl(null, name, token, true, userId); 8099 } 8100 8101 /** 8102 * Drop a content provider from a ProcessRecord's bookkeeping 8103 */ 8104 public void removeContentProvider(IBinder connection, boolean stable) { 8105 enforceNotIsolatedCaller("removeContentProvider"); 8106 long ident = Binder.clearCallingIdentity(); 8107 try { 8108 synchronized (this) { 8109 ContentProviderConnection conn; 8110 try { 8111 conn = (ContentProviderConnection)connection; 8112 } catch (ClassCastException e) { 8113 String msg ="removeContentProvider: " + connection 8114 + " not a ContentProviderConnection"; 8115 Slog.w(TAG, msg); 8116 throw new IllegalArgumentException(msg); 8117 } 8118 if (conn == null) { 8119 throw new NullPointerException("connection is null"); 8120 } 8121 if (decProviderCountLocked(conn, null, null, stable)) { 8122 updateOomAdjLocked(); 8123 } 8124 } 8125 } finally { 8126 Binder.restoreCallingIdentity(ident); 8127 } 8128 } 8129 8130 public void removeContentProviderExternal(String name, IBinder token) { 8131 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8132 "Do not have permission in call removeContentProviderExternal()"); 8133 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8134 } 8135 8136 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8137 synchronized (this) { 8138 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8139 if(cpr == null) { 8140 //remove from mProvidersByClass 8141 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8142 return; 8143 } 8144 8145 //update content provider record entry info 8146 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8147 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8148 if (localCpr.hasExternalProcessHandles()) { 8149 if (localCpr.removeExternalProcessHandleLocked(token)) { 8150 updateOomAdjLocked(); 8151 } else { 8152 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8153 + " with no external reference for token: " 8154 + token + "."); 8155 } 8156 } else { 8157 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8158 + " with no external references."); 8159 } 8160 } 8161 } 8162 8163 public final void publishContentProviders(IApplicationThread caller, 8164 List<ContentProviderHolder> providers) { 8165 if (providers == null) { 8166 return; 8167 } 8168 8169 enforceNotIsolatedCaller("publishContentProviders"); 8170 synchronized (this) { 8171 final ProcessRecord r = getRecordForAppLocked(caller); 8172 if (DEBUG_MU) 8173 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8174 if (r == null) { 8175 throw new SecurityException( 8176 "Unable to find app for caller " + caller 8177 + " (pid=" + Binder.getCallingPid() 8178 + ") when publishing content providers"); 8179 } 8180 8181 final long origId = Binder.clearCallingIdentity(); 8182 8183 final int N = providers.size(); 8184 for (int i=0; i<N; i++) { 8185 ContentProviderHolder src = providers.get(i); 8186 if (src == null || src.info == null || src.provider == null) { 8187 continue; 8188 } 8189 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8190 if (DEBUG_MU) 8191 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8192 if (dst != null) { 8193 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8194 mProviderMap.putProviderByClass(comp, dst); 8195 String names[] = dst.info.authority.split(";"); 8196 for (int j = 0; j < names.length; j++) { 8197 mProviderMap.putProviderByName(names[j], dst); 8198 } 8199 8200 int NL = mLaunchingProviders.size(); 8201 int j; 8202 for (j=0; j<NL; j++) { 8203 if (mLaunchingProviders.get(j) == dst) { 8204 mLaunchingProviders.remove(j); 8205 j--; 8206 NL--; 8207 } 8208 } 8209 synchronized (dst) { 8210 dst.provider = src.provider; 8211 dst.proc = r; 8212 dst.notifyAll(); 8213 } 8214 updateOomAdjLocked(r); 8215 } 8216 } 8217 8218 Binder.restoreCallingIdentity(origId); 8219 } 8220 } 8221 8222 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8223 ContentProviderConnection conn; 8224 try { 8225 conn = (ContentProviderConnection)connection; 8226 } catch (ClassCastException e) { 8227 String msg ="refContentProvider: " + connection 8228 + " not a ContentProviderConnection"; 8229 Slog.w(TAG, msg); 8230 throw new IllegalArgumentException(msg); 8231 } 8232 if (conn == null) { 8233 throw new NullPointerException("connection is null"); 8234 } 8235 8236 synchronized (this) { 8237 if (stable > 0) { 8238 conn.numStableIncs += stable; 8239 } 8240 stable = conn.stableCount + stable; 8241 if (stable < 0) { 8242 throw new IllegalStateException("stableCount < 0: " + stable); 8243 } 8244 8245 if (unstable > 0) { 8246 conn.numUnstableIncs += unstable; 8247 } 8248 unstable = conn.unstableCount + unstable; 8249 if (unstable < 0) { 8250 throw new IllegalStateException("unstableCount < 0: " + unstable); 8251 } 8252 8253 if ((stable+unstable) <= 0) { 8254 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8255 + stable + " unstable=" + unstable); 8256 } 8257 conn.stableCount = stable; 8258 conn.unstableCount = unstable; 8259 return !conn.dead; 8260 } 8261 } 8262 8263 public void unstableProviderDied(IBinder connection) { 8264 ContentProviderConnection conn; 8265 try { 8266 conn = (ContentProviderConnection)connection; 8267 } catch (ClassCastException e) { 8268 String msg ="refContentProvider: " + connection 8269 + " not a ContentProviderConnection"; 8270 Slog.w(TAG, msg); 8271 throw new IllegalArgumentException(msg); 8272 } 8273 if (conn == null) { 8274 throw new NullPointerException("connection is null"); 8275 } 8276 8277 // Safely retrieve the content provider associated with the connection. 8278 IContentProvider provider; 8279 synchronized (this) { 8280 provider = conn.provider.provider; 8281 } 8282 8283 if (provider == null) { 8284 // Um, yeah, we're way ahead of you. 8285 return; 8286 } 8287 8288 // Make sure the caller is being honest with us. 8289 if (provider.asBinder().pingBinder()) { 8290 // Er, no, still looks good to us. 8291 synchronized (this) { 8292 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8293 + " says " + conn + " died, but we don't agree"); 8294 return; 8295 } 8296 } 8297 8298 // Well look at that! It's dead! 8299 synchronized (this) { 8300 if (conn.provider.provider != provider) { 8301 // But something changed... good enough. 8302 return; 8303 } 8304 8305 ProcessRecord proc = conn.provider.proc; 8306 if (proc == null || proc.thread == null) { 8307 // Seems like the process is already cleaned up. 8308 return; 8309 } 8310 8311 // As far as we're concerned, this is just like receiving a 8312 // death notification... just a bit prematurely. 8313 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8314 + ") early provider death"); 8315 final long ident = Binder.clearCallingIdentity(); 8316 try { 8317 appDiedLocked(proc, proc.pid, proc.thread); 8318 } finally { 8319 Binder.restoreCallingIdentity(ident); 8320 } 8321 } 8322 } 8323 8324 @Override 8325 public void appNotRespondingViaProvider(IBinder connection) { 8326 enforceCallingPermission( 8327 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8328 8329 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8330 if (conn == null) { 8331 Slog.w(TAG, "ContentProviderConnection is null"); 8332 return; 8333 } 8334 8335 final ProcessRecord host = conn.provider.proc; 8336 if (host == null) { 8337 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8338 return; 8339 } 8340 8341 final long token = Binder.clearCallingIdentity(); 8342 try { 8343 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8344 } finally { 8345 Binder.restoreCallingIdentity(token); 8346 } 8347 } 8348 8349 public final void installSystemProviders() { 8350 List<ProviderInfo> providers; 8351 synchronized (this) { 8352 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8353 providers = generateApplicationProvidersLocked(app); 8354 if (providers != null) { 8355 for (int i=providers.size()-1; i>=0; i--) { 8356 ProviderInfo pi = (ProviderInfo)providers.get(i); 8357 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8358 Slog.w(TAG, "Not installing system proc provider " + pi.name 8359 + ": not system .apk"); 8360 providers.remove(i); 8361 } 8362 } 8363 } 8364 } 8365 if (providers != null) { 8366 mSystemThread.installSystemProviders(providers); 8367 } 8368 8369 mCoreSettingsObserver = new CoreSettingsObserver(this); 8370 8371 mUsageStatsService.monitorPackages(); 8372 } 8373 8374 /** 8375 * Allows app to retrieve the MIME type of a URI without having permission 8376 * to access its content provider. 8377 * 8378 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8379 * 8380 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8381 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8382 */ 8383 public String getProviderMimeType(Uri uri, int userId) { 8384 enforceNotIsolatedCaller("getProviderMimeType"); 8385 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8386 userId, false, true, "getProviderMimeType", null); 8387 final String name = uri.getAuthority(); 8388 final long ident = Binder.clearCallingIdentity(); 8389 ContentProviderHolder holder = null; 8390 8391 try { 8392 holder = getContentProviderExternalUnchecked(name, null, userId); 8393 if (holder != null) { 8394 return holder.provider.getType(uri); 8395 } 8396 } catch (RemoteException e) { 8397 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8398 return null; 8399 } finally { 8400 if (holder != null) { 8401 removeContentProviderExternalUnchecked(name, null, userId); 8402 } 8403 Binder.restoreCallingIdentity(ident); 8404 } 8405 8406 return null; 8407 } 8408 8409 // ========================================================= 8410 // GLOBAL MANAGEMENT 8411 // ========================================================= 8412 8413 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8414 boolean isolated) { 8415 String proc = customProcess != null ? customProcess : info.processName; 8416 BatteryStatsImpl.Uid.Proc ps = null; 8417 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8418 int uid = info.uid; 8419 if (isolated) { 8420 int userId = UserHandle.getUserId(uid); 8421 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8422 while (true) { 8423 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8424 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8425 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8426 } 8427 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8428 mNextIsolatedProcessUid++; 8429 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8430 // No process for this uid, use it. 8431 break; 8432 } 8433 stepsLeft--; 8434 if (stepsLeft <= 0) { 8435 return null; 8436 } 8437 } 8438 } 8439 return new ProcessRecord(stats, info, proc, uid); 8440 } 8441 8442 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8443 ProcessRecord app; 8444 if (!isolated) { 8445 app = getProcessRecordLocked(info.processName, info.uid, true); 8446 } else { 8447 app = null; 8448 } 8449 8450 if (app == null) { 8451 app = newProcessRecordLocked(info, null, isolated); 8452 mProcessNames.put(info.processName, app.uid, app); 8453 if (isolated) { 8454 mIsolatedProcesses.put(app.uid, app); 8455 } 8456 updateLruProcessLocked(app, false, null); 8457 updateOomAdjLocked(); 8458 } 8459 8460 // This package really, really can not be stopped. 8461 try { 8462 AppGlobals.getPackageManager().setPackageStoppedState( 8463 info.packageName, false, UserHandle.getUserId(app.uid)); 8464 } catch (RemoteException e) { 8465 } catch (IllegalArgumentException e) { 8466 Slog.w(TAG, "Failed trying to unstop package " 8467 + info.packageName + ": " + e); 8468 } 8469 8470 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8471 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8472 app.persistent = true; 8473 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8474 } 8475 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8476 mPersistentStartingProcesses.add(app); 8477 startProcessLocked(app, "added application", app.processName); 8478 } 8479 8480 return app; 8481 } 8482 8483 public void unhandledBack() { 8484 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8485 "unhandledBack()"); 8486 8487 synchronized(this) { 8488 final long origId = Binder.clearCallingIdentity(); 8489 try { 8490 getFocusedStack().unhandledBackLocked(); 8491 } finally { 8492 Binder.restoreCallingIdentity(origId); 8493 } 8494 } 8495 } 8496 8497 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8498 enforceNotIsolatedCaller("openContentUri"); 8499 final int userId = UserHandle.getCallingUserId(); 8500 String name = uri.getAuthority(); 8501 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8502 ParcelFileDescriptor pfd = null; 8503 if (cph != null) { 8504 // We record the binder invoker's uid in thread-local storage before 8505 // going to the content provider to open the file. Later, in the code 8506 // that handles all permissions checks, we look for this uid and use 8507 // that rather than the Activity Manager's own uid. The effect is that 8508 // we do the check against the caller's permissions even though it looks 8509 // to the content provider like the Activity Manager itself is making 8510 // the request. 8511 sCallerIdentity.set(new Identity( 8512 Binder.getCallingPid(), Binder.getCallingUid())); 8513 try { 8514 pfd = cph.provider.openFile(null, uri, "r", null); 8515 } catch (FileNotFoundException e) { 8516 // do nothing; pfd will be returned null 8517 } finally { 8518 // Ensure that whatever happens, we clean up the identity state 8519 sCallerIdentity.remove(); 8520 } 8521 8522 // We've got the fd now, so we're done with the provider. 8523 removeContentProviderExternalUnchecked(name, null, userId); 8524 } else { 8525 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8526 } 8527 return pfd; 8528 } 8529 8530 // Actually is sleeping or shutting down or whatever else in the future 8531 // is an inactive state. 8532 public boolean isSleepingOrShuttingDown() { 8533 return mSleeping || mShuttingDown; 8534 } 8535 8536 public boolean isSleeping() { 8537 return mSleeping; 8538 } 8539 8540 void goingToSleep() { 8541 synchronized(this) { 8542 mWentToSleep = true; 8543 updateEventDispatchingLocked(); 8544 goToSleepIfNeededLocked(); 8545 } 8546 } 8547 8548 void finishRunningVoiceLocked() { 8549 if (mRunningVoice) { 8550 mRunningVoice = false; 8551 goToSleepIfNeededLocked(); 8552 } 8553 } 8554 8555 void goToSleepIfNeededLocked() { 8556 if (mWentToSleep && !mRunningVoice) { 8557 if (!mSleeping) { 8558 mSleeping = true; 8559 mStackSupervisor.goingToSleepLocked(); 8560 8561 // Initialize the wake times of all processes. 8562 checkExcessivePowerUsageLocked(false); 8563 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8564 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8565 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8566 } 8567 } 8568 } 8569 8570 @Override 8571 public boolean shutdown(int timeout) { 8572 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8573 != PackageManager.PERMISSION_GRANTED) { 8574 throw new SecurityException("Requires permission " 8575 + android.Manifest.permission.SHUTDOWN); 8576 } 8577 8578 boolean timedout = false; 8579 8580 synchronized(this) { 8581 mShuttingDown = true; 8582 updateEventDispatchingLocked(); 8583 timedout = mStackSupervisor.shutdownLocked(timeout); 8584 } 8585 8586 mAppOpsService.shutdown(); 8587 mUsageStatsService.shutdown(); 8588 mBatteryStatsService.shutdown(); 8589 synchronized (this) { 8590 mProcessStats.shutdownLocked(); 8591 } 8592 8593 return timedout; 8594 } 8595 8596 public final void activitySlept(IBinder token) { 8597 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8598 8599 final long origId = Binder.clearCallingIdentity(); 8600 8601 synchronized (this) { 8602 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8603 if (r != null) { 8604 mStackSupervisor.activitySleptLocked(r); 8605 } 8606 } 8607 8608 Binder.restoreCallingIdentity(origId); 8609 } 8610 8611 void logLockScreen(String msg) { 8612 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8613 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8614 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8615 mStackSupervisor.mDismissKeyguardOnNextActivity); 8616 } 8617 8618 private void comeOutOfSleepIfNeededLocked() { 8619 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8620 if (mSleeping) { 8621 mSleeping = false; 8622 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8623 } 8624 } 8625 } 8626 8627 void wakingUp() { 8628 synchronized(this) { 8629 mWentToSleep = false; 8630 updateEventDispatchingLocked(); 8631 comeOutOfSleepIfNeededLocked(); 8632 } 8633 } 8634 8635 void startRunningVoiceLocked() { 8636 if (!mRunningVoice) { 8637 mRunningVoice = true; 8638 comeOutOfSleepIfNeededLocked(); 8639 } 8640 } 8641 8642 private void updateEventDispatchingLocked() { 8643 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8644 } 8645 8646 public void setLockScreenShown(boolean shown) { 8647 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8648 != PackageManager.PERMISSION_GRANTED) { 8649 throw new SecurityException("Requires permission " 8650 + android.Manifest.permission.DEVICE_POWER); 8651 } 8652 8653 synchronized(this) { 8654 long ident = Binder.clearCallingIdentity(); 8655 try { 8656 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8657 mLockScreenShown = shown; 8658 comeOutOfSleepIfNeededLocked(); 8659 } finally { 8660 Binder.restoreCallingIdentity(ident); 8661 } 8662 } 8663 } 8664 8665 public void stopAppSwitches() { 8666 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8667 != PackageManager.PERMISSION_GRANTED) { 8668 throw new SecurityException("Requires permission " 8669 + android.Manifest.permission.STOP_APP_SWITCHES); 8670 } 8671 8672 synchronized(this) { 8673 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8674 + APP_SWITCH_DELAY_TIME; 8675 mDidAppSwitch = false; 8676 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8677 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8678 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8679 } 8680 } 8681 8682 public void resumeAppSwitches() { 8683 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8684 != PackageManager.PERMISSION_GRANTED) { 8685 throw new SecurityException("Requires permission " 8686 + android.Manifest.permission.STOP_APP_SWITCHES); 8687 } 8688 8689 synchronized(this) { 8690 // Note that we don't execute any pending app switches... we will 8691 // let those wait until either the timeout, or the next start 8692 // activity request. 8693 mAppSwitchesAllowedTime = 0; 8694 } 8695 } 8696 8697 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8698 String name) { 8699 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8700 return true; 8701 } 8702 8703 final int perm = checkComponentPermission( 8704 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8705 callingUid, -1, true); 8706 if (perm == PackageManager.PERMISSION_GRANTED) { 8707 return true; 8708 } 8709 8710 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8711 return false; 8712 } 8713 8714 public void setDebugApp(String packageName, boolean waitForDebugger, 8715 boolean persistent) { 8716 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8717 "setDebugApp()"); 8718 8719 long ident = Binder.clearCallingIdentity(); 8720 try { 8721 // Note that this is not really thread safe if there are multiple 8722 // callers into it at the same time, but that's not a situation we 8723 // care about. 8724 if (persistent) { 8725 final ContentResolver resolver = mContext.getContentResolver(); 8726 Settings.Global.putString( 8727 resolver, Settings.Global.DEBUG_APP, 8728 packageName); 8729 Settings.Global.putInt( 8730 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8731 waitForDebugger ? 1 : 0); 8732 } 8733 8734 synchronized (this) { 8735 if (!persistent) { 8736 mOrigDebugApp = mDebugApp; 8737 mOrigWaitForDebugger = mWaitForDebugger; 8738 } 8739 mDebugApp = packageName; 8740 mWaitForDebugger = waitForDebugger; 8741 mDebugTransient = !persistent; 8742 if (packageName != null) { 8743 forceStopPackageLocked(packageName, -1, false, false, true, true, 8744 false, UserHandle.USER_ALL, "set debug app"); 8745 } 8746 } 8747 } finally { 8748 Binder.restoreCallingIdentity(ident); 8749 } 8750 } 8751 8752 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8753 synchronized (this) { 8754 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8755 if (!isDebuggable) { 8756 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8757 throw new SecurityException("Process not debuggable: " + app.packageName); 8758 } 8759 } 8760 8761 mOpenGlTraceApp = processName; 8762 } 8763 } 8764 8765 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8766 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8767 synchronized (this) { 8768 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8769 if (!isDebuggable) { 8770 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8771 throw new SecurityException("Process not debuggable: " + app.packageName); 8772 } 8773 } 8774 mProfileApp = processName; 8775 mProfileFile = profileFile; 8776 if (mProfileFd != null) { 8777 try { 8778 mProfileFd.close(); 8779 } catch (IOException e) { 8780 } 8781 mProfileFd = null; 8782 } 8783 mProfileFd = profileFd; 8784 mProfileType = 0; 8785 mAutoStopProfiler = autoStopProfiler; 8786 } 8787 } 8788 8789 @Override 8790 public void setAlwaysFinish(boolean enabled) { 8791 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8792 "setAlwaysFinish()"); 8793 8794 Settings.Global.putInt( 8795 mContext.getContentResolver(), 8796 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8797 8798 synchronized (this) { 8799 mAlwaysFinishActivities = enabled; 8800 } 8801 } 8802 8803 @Override 8804 public void setActivityController(IActivityController controller) { 8805 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8806 "setActivityController()"); 8807 synchronized (this) { 8808 mController = controller; 8809 Watchdog.getInstance().setActivityController(controller); 8810 } 8811 } 8812 8813 @Override 8814 public void setUserIsMonkey(boolean userIsMonkey) { 8815 synchronized (this) { 8816 synchronized (mPidsSelfLocked) { 8817 final int callingPid = Binder.getCallingPid(); 8818 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8819 if (precessRecord == null) { 8820 throw new SecurityException("Unknown process: " + callingPid); 8821 } 8822 if (precessRecord.instrumentationUiAutomationConnection == null) { 8823 throw new SecurityException("Only an instrumentation process " 8824 + "with a UiAutomation can call setUserIsMonkey"); 8825 } 8826 } 8827 mUserIsMonkey = userIsMonkey; 8828 } 8829 } 8830 8831 @Override 8832 public boolean isUserAMonkey() { 8833 synchronized (this) { 8834 // If there is a controller also implies the user is a monkey. 8835 return (mUserIsMonkey || mController != null); 8836 } 8837 } 8838 8839 public void requestBugReport() { 8840 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8841 SystemProperties.set("ctl.start", "bugreport"); 8842 } 8843 8844 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8845 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8846 } 8847 8848 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8849 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8850 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8851 } 8852 return KEY_DISPATCHING_TIMEOUT; 8853 } 8854 8855 @Override 8856 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8857 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8858 != PackageManager.PERMISSION_GRANTED) { 8859 throw new SecurityException("Requires permission " 8860 + android.Manifest.permission.FILTER_EVENTS); 8861 } 8862 ProcessRecord proc; 8863 long timeout; 8864 synchronized (this) { 8865 synchronized (mPidsSelfLocked) { 8866 proc = mPidsSelfLocked.get(pid); 8867 } 8868 timeout = getInputDispatchingTimeoutLocked(proc); 8869 } 8870 8871 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8872 return -1; 8873 } 8874 8875 return timeout; 8876 } 8877 8878 /** 8879 * Handle input dispatching timeouts. 8880 * Returns whether input dispatching should be aborted or not. 8881 */ 8882 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8883 final ActivityRecord activity, final ActivityRecord parent, 8884 final boolean aboveSystem, String reason) { 8885 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8886 != PackageManager.PERMISSION_GRANTED) { 8887 throw new SecurityException("Requires permission " 8888 + android.Manifest.permission.FILTER_EVENTS); 8889 } 8890 8891 final String annotation; 8892 if (reason == null) { 8893 annotation = "Input dispatching timed out"; 8894 } else { 8895 annotation = "Input dispatching timed out (" + reason + ")"; 8896 } 8897 8898 if (proc != null) { 8899 synchronized (this) { 8900 if (proc.debugging) { 8901 return false; 8902 } 8903 8904 if (mDidDexOpt) { 8905 // Give more time since we were dexopting. 8906 mDidDexOpt = false; 8907 return false; 8908 } 8909 8910 if (proc.instrumentationClass != null) { 8911 Bundle info = new Bundle(); 8912 info.putString("shortMsg", "keyDispatchingTimedOut"); 8913 info.putString("longMsg", annotation); 8914 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8915 return true; 8916 } 8917 } 8918 mHandler.post(new Runnable() { 8919 @Override 8920 public void run() { 8921 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8922 } 8923 }); 8924 } 8925 8926 return true; 8927 } 8928 8929 public Bundle getAssistContextExtras(int requestType) { 8930 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8931 "getAssistContextExtras()"); 8932 PendingAssistExtras pae; 8933 Bundle extras = new Bundle(); 8934 synchronized (this) { 8935 ActivityRecord activity = getFocusedStack().mResumedActivity; 8936 if (activity == null) { 8937 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8938 return null; 8939 } 8940 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8941 if (activity.app == null || activity.app.thread == null) { 8942 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8943 return extras; 8944 } 8945 if (activity.app.pid == Binder.getCallingPid()) { 8946 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8947 return extras; 8948 } 8949 pae = new PendingAssistExtras(activity); 8950 try { 8951 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8952 requestType); 8953 mPendingAssistExtras.add(pae); 8954 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8955 } catch (RemoteException e) { 8956 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8957 return extras; 8958 } 8959 } 8960 synchronized (pae) { 8961 while (!pae.haveResult) { 8962 try { 8963 pae.wait(); 8964 } catch (InterruptedException e) { 8965 } 8966 } 8967 if (pae.result != null) { 8968 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8969 } 8970 } 8971 synchronized (this) { 8972 mPendingAssistExtras.remove(pae); 8973 mHandler.removeCallbacks(pae); 8974 } 8975 return extras; 8976 } 8977 8978 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8979 PendingAssistExtras pae = (PendingAssistExtras)token; 8980 synchronized (pae) { 8981 pae.result = extras; 8982 pae.haveResult = true; 8983 pae.notifyAll(); 8984 } 8985 } 8986 8987 public void registerProcessObserver(IProcessObserver observer) { 8988 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8989 "registerProcessObserver()"); 8990 synchronized (this) { 8991 mProcessObservers.register(observer); 8992 } 8993 } 8994 8995 @Override 8996 public void unregisterProcessObserver(IProcessObserver observer) { 8997 synchronized (this) { 8998 mProcessObservers.unregister(observer); 8999 } 9000 } 9001 9002 @Override 9003 public boolean convertFromTranslucent(IBinder token) { 9004 final long origId = Binder.clearCallingIdentity(); 9005 try { 9006 synchronized (this) { 9007 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9008 if (r == null) { 9009 return false; 9010 } 9011 if (r.changeWindowTranslucency(true)) { 9012 mWindowManager.setAppFullscreen(token, true); 9013 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9014 return true; 9015 } 9016 return false; 9017 } 9018 } finally { 9019 Binder.restoreCallingIdentity(origId); 9020 } 9021 } 9022 9023 @Override 9024 public boolean convertToTranslucent(IBinder token) { 9025 final long origId = Binder.clearCallingIdentity(); 9026 try { 9027 synchronized (this) { 9028 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9029 if (r == null) { 9030 return false; 9031 } 9032 if (r.changeWindowTranslucency(false)) { 9033 r.task.stack.convertToTranslucent(r); 9034 mWindowManager.setAppFullscreen(token, false); 9035 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9036 return true; 9037 } 9038 return false; 9039 } 9040 } finally { 9041 Binder.restoreCallingIdentity(origId); 9042 } 9043 } 9044 9045 @Override 9046 public void setImmersive(IBinder token, boolean immersive) { 9047 synchronized(this) { 9048 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9049 if (r == null) { 9050 throw new IllegalArgumentException(); 9051 } 9052 r.immersive = immersive; 9053 9054 // update associated state if we're frontmost 9055 if (r == mFocusedActivity) { 9056 if (DEBUG_IMMERSIVE) { 9057 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9058 } 9059 applyUpdateLockStateLocked(r); 9060 } 9061 } 9062 } 9063 9064 @Override 9065 public boolean isImmersive(IBinder token) { 9066 synchronized (this) { 9067 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9068 if (r == null) { 9069 throw new IllegalArgumentException(); 9070 } 9071 return r.immersive; 9072 } 9073 } 9074 9075 public boolean isTopActivityImmersive() { 9076 enforceNotIsolatedCaller("startActivity"); 9077 synchronized (this) { 9078 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9079 return (r != null) ? r.immersive : false; 9080 } 9081 } 9082 9083 public final void enterSafeMode() { 9084 synchronized(this) { 9085 // It only makes sense to do this before the system is ready 9086 // and started launching other packages. 9087 if (!mSystemReady) { 9088 try { 9089 AppGlobals.getPackageManager().enterSafeMode(); 9090 } catch (RemoteException e) { 9091 } 9092 } 9093 9094 mSafeMode = true; 9095 } 9096 } 9097 9098 public final void showSafeModeOverlay() { 9099 View v = LayoutInflater.from(mContext).inflate( 9100 com.android.internal.R.layout.safe_mode, null); 9101 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9102 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9103 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9104 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9105 lp.gravity = Gravity.BOTTOM | Gravity.START; 9106 lp.format = v.getBackground().getOpacity(); 9107 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9108 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9109 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9110 ((WindowManager)mContext.getSystemService( 9111 Context.WINDOW_SERVICE)).addView(v, lp); 9112 } 9113 9114 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9115 if (!(sender instanceof PendingIntentRecord)) { 9116 return; 9117 } 9118 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9119 synchronized (stats) { 9120 if (mBatteryStatsService.isOnBattery()) { 9121 mBatteryStatsService.enforceCallingPermission(); 9122 PendingIntentRecord rec = (PendingIntentRecord)sender; 9123 int MY_UID = Binder.getCallingUid(); 9124 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9125 BatteryStatsImpl.Uid.Pkg pkg = 9126 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9127 sourcePkg != null ? sourcePkg : rec.key.packageName); 9128 pkg.incWakeupsLocked(); 9129 } 9130 } 9131 } 9132 9133 public boolean killPids(int[] pids, String pReason, boolean secure) { 9134 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9135 throw new SecurityException("killPids only available to the system"); 9136 } 9137 String reason = (pReason == null) ? "Unknown" : pReason; 9138 // XXX Note: don't acquire main activity lock here, because the window 9139 // manager calls in with its locks held. 9140 9141 boolean killed = false; 9142 synchronized (mPidsSelfLocked) { 9143 int[] types = new int[pids.length]; 9144 int worstType = 0; 9145 for (int i=0; i<pids.length; i++) { 9146 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9147 if (proc != null) { 9148 int type = proc.setAdj; 9149 types[i] = type; 9150 if (type > worstType) { 9151 worstType = type; 9152 } 9153 } 9154 } 9155 9156 // If the worst oom_adj is somewhere in the cached proc LRU range, 9157 // then constrain it so we will kill all cached procs. 9158 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9159 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9160 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9161 } 9162 9163 // If this is not a secure call, don't let it kill processes that 9164 // are important. 9165 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9166 worstType = ProcessList.SERVICE_ADJ; 9167 } 9168 9169 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9170 for (int i=0; i<pids.length; i++) { 9171 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9172 if (proc == null) { 9173 continue; 9174 } 9175 int adj = proc.setAdj; 9176 if (adj >= worstType && !proc.killedByAm) { 9177 killUnneededProcessLocked(proc, reason); 9178 killed = true; 9179 } 9180 } 9181 } 9182 return killed; 9183 } 9184 9185 @Override 9186 public void killUid(int uid, String reason) { 9187 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9188 throw new SecurityException("killUid only available to the system"); 9189 } 9190 synchronized (this) { 9191 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9192 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9193 reason != null ? reason : "kill uid"); 9194 } 9195 } 9196 9197 @Override 9198 public boolean killProcessesBelowForeground(String reason) { 9199 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9200 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9201 } 9202 9203 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9204 } 9205 9206 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9207 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9208 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9209 } 9210 9211 boolean killed = false; 9212 synchronized (mPidsSelfLocked) { 9213 final int size = mPidsSelfLocked.size(); 9214 for (int i = 0; i < size; i++) { 9215 final int pid = mPidsSelfLocked.keyAt(i); 9216 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9217 if (proc == null) continue; 9218 9219 final int adj = proc.setAdj; 9220 if (adj > belowAdj && !proc.killedByAm) { 9221 killUnneededProcessLocked(proc, reason); 9222 killed = true; 9223 } 9224 } 9225 } 9226 return killed; 9227 } 9228 9229 @Override 9230 public void hang(final IBinder who, boolean allowRestart) { 9231 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9232 != PackageManager.PERMISSION_GRANTED) { 9233 throw new SecurityException("Requires permission " 9234 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9235 } 9236 9237 final IBinder.DeathRecipient death = new DeathRecipient() { 9238 @Override 9239 public void binderDied() { 9240 synchronized (this) { 9241 notifyAll(); 9242 } 9243 } 9244 }; 9245 9246 try { 9247 who.linkToDeath(death, 0); 9248 } catch (RemoteException e) { 9249 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9250 return; 9251 } 9252 9253 synchronized (this) { 9254 Watchdog.getInstance().setAllowRestart(allowRestart); 9255 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9256 synchronized (death) { 9257 while (who.isBinderAlive()) { 9258 try { 9259 death.wait(); 9260 } catch (InterruptedException e) { 9261 } 9262 } 9263 } 9264 Watchdog.getInstance().setAllowRestart(true); 9265 } 9266 } 9267 9268 @Override 9269 public void restart() { 9270 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9271 != PackageManager.PERMISSION_GRANTED) { 9272 throw new SecurityException("Requires permission " 9273 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9274 } 9275 9276 Log.i(TAG, "Sending shutdown broadcast..."); 9277 9278 BroadcastReceiver br = new BroadcastReceiver() { 9279 @Override public void onReceive(Context context, Intent intent) { 9280 // Now the broadcast is done, finish up the low-level shutdown. 9281 Log.i(TAG, "Shutting down activity manager..."); 9282 shutdown(10000); 9283 Log.i(TAG, "Shutdown complete, restarting!"); 9284 Process.killProcess(Process.myPid()); 9285 System.exit(10); 9286 } 9287 }; 9288 9289 // First send the high-level shut down broadcast. 9290 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9291 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9292 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9293 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9294 mContext.sendOrderedBroadcastAsUser(intent, 9295 UserHandle.ALL, null, br, mHandler, 0, null, null); 9296 */ 9297 br.onReceive(mContext, intent); 9298 } 9299 9300 private long getLowRamTimeSinceIdle(long now) { 9301 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9302 } 9303 9304 @Override 9305 public void performIdleMaintenance() { 9306 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9307 != PackageManager.PERMISSION_GRANTED) { 9308 throw new SecurityException("Requires permission " 9309 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9310 } 9311 9312 synchronized (this) { 9313 final long now = SystemClock.uptimeMillis(); 9314 final long timeSinceLastIdle = now - mLastIdleTime; 9315 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9316 mLastIdleTime = now; 9317 mLowRamTimeSinceLastIdle = 0; 9318 if (mLowRamStartTime != 0) { 9319 mLowRamStartTime = now; 9320 } 9321 9322 StringBuilder sb = new StringBuilder(128); 9323 sb.append("Idle maintenance over "); 9324 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9325 sb.append(" low RAM for "); 9326 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9327 Slog.i(TAG, sb.toString()); 9328 9329 // If at least 1/3 of our time since the last idle period has been spent 9330 // with RAM low, then we want to kill processes. 9331 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9332 9333 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9334 ProcessRecord proc = mLruProcesses.get(i); 9335 if (proc.notCachedSinceIdle) { 9336 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9337 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9338 if (doKilling && proc.initialIdlePss != 0 9339 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9340 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9341 + " from " + proc.initialIdlePss + ")"); 9342 } 9343 } 9344 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9345 proc.notCachedSinceIdle = true; 9346 proc.initialIdlePss = 0; 9347 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9348 isSleeping(), now); 9349 } 9350 } 9351 9352 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9353 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9354 } 9355 } 9356 9357 private void retrieveSettings() { 9358 final ContentResolver resolver = mContext.getContentResolver(); 9359 String debugApp = Settings.Global.getString( 9360 resolver, Settings.Global.DEBUG_APP); 9361 boolean waitForDebugger = Settings.Global.getInt( 9362 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9363 boolean alwaysFinishActivities = Settings.Global.getInt( 9364 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9365 boolean forceRtl = Settings.Global.getInt( 9366 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9367 // Transfer any global setting for forcing RTL layout, into a System Property 9368 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9369 9370 Configuration configuration = new Configuration(); 9371 Settings.System.getConfiguration(resolver, configuration); 9372 if (forceRtl) { 9373 // This will take care of setting the correct layout direction flags 9374 configuration.setLayoutDirection(configuration.locale); 9375 } 9376 9377 synchronized (this) { 9378 mDebugApp = mOrigDebugApp = debugApp; 9379 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9380 mAlwaysFinishActivities = alwaysFinishActivities; 9381 // This happens before any activities are started, so we can 9382 // change mConfiguration in-place. 9383 updateConfigurationLocked(configuration, null, false, true); 9384 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9385 } 9386 } 9387 9388 public boolean testIsSystemReady() { 9389 // no need to synchronize(this) just to read & return the value 9390 return mSystemReady; 9391 } 9392 9393 private static File getCalledPreBootReceiversFile() { 9394 File dataDir = Environment.getDataDirectory(); 9395 File systemDir = new File(dataDir, "system"); 9396 File fname = new File(systemDir, "called_pre_boots.dat"); 9397 return fname; 9398 } 9399 9400 static final int LAST_DONE_VERSION = 10000; 9401 9402 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9403 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9404 File file = getCalledPreBootReceiversFile(); 9405 FileInputStream fis = null; 9406 try { 9407 fis = new FileInputStream(file); 9408 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9409 int fvers = dis.readInt(); 9410 if (fvers == LAST_DONE_VERSION) { 9411 String vers = dis.readUTF(); 9412 String codename = dis.readUTF(); 9413 String build = dis.readUTF(); 9414 if (android.os.Build.VERSION.RELEASE.equals(vers) 9415 && android.os.Build.VERSION.CODENAME.equals(codename) 9416 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9417 int num = dis.readInt(); 9418 while (num > 0) { 9419 num--; 9420 String pkg = dis.readUTF(); 9421 String cls = dis.readUTF(); 9422 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9423 } 9424 } 9425 } 9426 } catch (FileNotFoundException e) { 9427 } catch (IOException e) { 9428 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9429 } finally { 9430 if (fis != null) { 9431 try { 9432 fis.close(); 9433 } catch (IOException e) { 9434 } 9435 } 9436 } 9437 return lastDoneReceivers; 9438 } 9439 9440 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9441 File file = getCalledPreBootReceiversFile(); 9442 FileOutputStream fos = null; 9443 DataOutputStream dos = null; 9444 try { 9445 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9446 fos = new FileOutputStream(file); 9447 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9448 dos.writeInt(LAST_DONE_VERSION); 9449 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9450 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9451 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9452 dos.writeInt(list.size()); 9453 for (int i=0; i<list.size(); i++) { 9454 dos.writeUTF(list.get(i).getPackageName()); 9455 dos.writeUTF(list.get(i).getClassName()); 9456 } 9457 } catch (IOException e) { 9458 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9459 file.delete(); 9460 } finally { 9461 FileUtils.sync(fos); 9462 if (dos != null) { 9463 try { 9464 dos.close(); 9465 } catch (IOException e) { 9466 // TODO Auto-generated catch block 9467 e.printStackTrace(); 9468 } 9469 } 9470 } 9471 } 9472 9473 public void systemReady(final Runnable goingCallback) { 9474 synchronized(this) { 9475 if (mSystemReady) { 9476 if (goingCallback != null) goingCallback.run(); 9477 return; 9478 } 9479 9480 // Check to see if there are any update receivers to run. 9481 if (!mDidUpdate) { 9482 if (mWaitingUpdate) { 9483 return; 9484 } 9485 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9486 List<ResolveInfo> ris = null; 9487 try { 9488 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9489 intent, null, 0, 0); 9490 } catch (RemoteException e) { 9491 } 9492 if (ris != null) { 9493 for (int i=ris.size()-1; i>=0; i--) { 9494 if ((ris.get(i).activityInfo.applicationInfo.flags 9495 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9496 ris.remove(i); 9497 } 9498 } 9499 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9500 9501 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9502 9503 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9504 for (int i=0; i<ris.size(); i++) { 9505 ActivityInfo ai = ris.get(i).activityInfo; 9506 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9507 if (lastDoneReceivers.contains(comp)) { 9508 // We already did the pre boot receiver for this app with the current 9509 // platform version, so don't do it again... 9510 ris.remove(i); 9511 i--; 9512 // ...however, do keep it as one that has been done, so we don't 9513 // forget about it when rewriting the file of last done receivers. 9514 doneReceivers.add(comp); 9515 } 9516 } 9517 9518 final int[] users = getUsersLocked(); 9519 for (int i=0; i<ris.size(); i++) { 9520 ActivityInfo ai = ris.get(i).activityInfo; 9521 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9522 doneReceivers.add(comp); 9523 intent.setComponent(comp); 9524 for (int j=0; j<users.length; j++) { 9525 IIntentReceiver finisher = null; 9526 if (i == ris.size()-1 && j == users.length-1) { 9527 finisher = new IIntentReceiver.Stub() { 9528 public void performReceive(Intent intent, int resultCode, 9529 String data, Bundle extras, boolean ordered, 9530 boolean sticky, int sendingUser) { 9531 // The raw IIntentReceiver interface is called 9532 // with the AM lock held, so redispatch to 9533 // execute our code without the lock. 9534 mHandler.post(new Runnable() { 9535 public void run() { 9536 synchronized (ActivityManagerService.this) { 9537 mDidUpdate = true; 9538 } 9539 writeLastDonePreBootReceivers(doneReceivers); 9540 showBootMessage(mContext.getText( 9541 R.string.android_upgrading_complete), 9542 false); 9543 systemReady(goingCallback); 9544 } 9545 }); 9546 } 9547 }; 9548 } 9549 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9550 + " for user " + users[j]); 9551 broadcastIntentLocked(null, null, intent, null, finisher, 9552 0, null, null, null, AppOpsManager.OP_NONE, 9553 true, false, MY_PID, Process.SYSTEM_UID, 9554 users[j]); 9555 if (finisher != null) { 9556 mWaitingUpdate = true; 9557 } 9558 } 9559 } 9560 } 9561 if (mWaitingUpdate) { 9562 return; 9563 } 9564 mDidUpdate = true; 9565 } 9566 9567 mAppOpsService.systemReady(); 9568 mSystemReady = true; 9569 } 9570 9571 ArrayList<ProcessRecord> procsToKill = null; 9572 synchronized(mPidsSelfLocked) { 9573 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9574 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9575 if (!isAllowedWhileBooting(proc.info)){ 9576 if (procsToKill == null) { 9577 procsToKill = new ArrayList<ProcessRecord>(); 9578 } 9579 procsToKill.add(proc); 9580 } 9581 } 9582 } 9583 9584 synchronized(this) { 9585 if (procsToKill != null) { 9586 for (int i=procsToKill.size()-1; i>=0; i--) { 9587 ProcessRecord proc = procsToKill.get(i); 9588 Slog.i(TAG, "Removing system update proc: " + proc); 9589 removeProcessLocked(proc, true, false, "system update done"); 9590 } 9591 } 9592 9593 // Now that we have cleaned up any update processes, we 9594 // are ready to start launching real processes and know that 9595 // we won't trample on them any more. 9596 mProcessesReady = true; 9597 } 9598 9599 Slog.i(TAG, "System now ready"); 9600 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9601 SystemClock.uptimeMillis()); 9602 9603 synchronized(this) { 9604 // Make sure we have no pre-ready processes sitting around. 9605 9606 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9607 ResolveInfo ri = mContext.getPackageManager() 9608 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9609 STOCK_PM_FLAGS); 9610 CharSequence errorMsg = null; 9611 if (ri != null) { 9612 ActivityInfo ai = ri.activityInfo; 9613 ApplicationInfo app = ai.applicationInfo; 9614 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9615 mTopAction = Intent.ACTION_FACTORY_TEST; 9616 mTopData = null; 9617 mTopComponent = new ComponentName(app.packageName, 9618 ai.name); 9619 } else { 9620 errorMsg = mContext.getResources().getText( 9621 com.android.internal.R.string.factorytest_not_system); 9622 } 9623 } else { 9624 errorMsg = mContext.getResources().getText( 9625 com.android.internal.R.string.factorytest_no_action); 9626 } 9627 if (errorMsg != null) { 9628 mTopAction = null; 9629 mTopData = null; 9630 mTopComponent = null; 9631 Message msg = Message.obtain(); 9632 msg.what = SHOW_FACTORY_ERROR_MSG; 9633 msg.getData().putCharSequence("msg", errorMsg); 9634 mHandler.sendMessage(msg); 9635 } 9636 } 9637 } 9638 9639 retrieveSettings(); 9640 9641 synchronized (this) { 9642 readGrantedUriPermissionsLocked(); 9643 } 9644 9645 if (goingCallback != null) goingCallback.run(); 9646 9647 mSystemServiceManager.startUser(mCurrentUserId); 9648 9649 synchronized (this) { 9650 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9651 try { 9652 List apps = AppGlobals.getPackageManager(). 9653 getPersistentApplications(STOCK_PM_FLAGS); 9654 if (apps != null) { 9655 int N = apps.size(); 9656 int i; 9657 for (i=0; i<N; i++) { 9658 ApplicationInfo info 9659 = (ApplicationInfo)apps.get(i); 9660 if (info != null && 9661 !info.packageName.equals("android")) { 9662 addAppLocked(info, false); 9663 } 9664 } 9665 } 9666 } catch (RemoteException ex) { 9667 // pm is in same process, this will never happen. 9668 } 9669 } 9670 9671 // Start up initial activity. 9672 mBooting = true; 9673 9674 try { 9675 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9676 Message msg = Message.obtain(); 9677 msg.what = SHOW_UID_ERROR_MSG; 9678 mHandler.sendMessage(msg); 9679 } 9680 } catch (RemoteException e) { 9681 } 9682 9683 long ident = Binder.clearCallingIdentity(); 9684 try { 9685 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9686 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9687 | Intent.FLAG_RECEIVER_FOREGROUND); 9688 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9689 broadcastIntentLocked(null, null, intent, 9690 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9691 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9692 intent = new Intent(Intent.ACTION_USER_STARTING); 9693 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9694 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9695 broadcastIntentLocked(null, null, intent, 9696 null, new IIntentReceiver.Stub() { 9697 @Override 9698 public void performReceive(Intent intent, int resultCode, String data, 9699 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9700 throws RemoteException { 9701 } 9702 }, 0, null, null, 9703 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9704 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9705 } catch (Throwable t) { 9706 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 9707 } finally { 9708 Binder.restoreCallingIdentity(ident); 9709 } 9710 mStackSupervisor.resumeTopActivitiesLocked(); 9711 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9712 } 9713 } 9714 9715 private boolean makeAppCrashingLocked(ProcessRecord app, 9716 String shortMsg, String longMsg, String stackTrace) { 9717 app.crashing = true; 9718 app.crashingReport = generateProcessError(app, 9719 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9720 startAppProblemLocked(app); 9721 app.stopFreezingAllLocked(); 9722 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9723 } 9724 9725 private void makeAppNotRespondingLocked(ProcessRecord app, 9726 String activity, String shortMsg, String longMsg) { 9727 app.notResponding = true; 9728 app.notRespondingReport = generateProcessError(app, 9729 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9730 activity, shortMsg, longMsg, null); 9731 startAppProblemLocked(app); 9732 app.stopFreezingAllLocked(); 9733 } 9734 9735 /** 9736 * Generate a process error record, suitable for attachment to a ProcessRecord. 9737 * 9738 * @param app The ProcessRecord in which the error occurred. 9739 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9740 * ActivityManager.AppErrorStateInfo 9741 * @param activity The activity associated with the crash, if known. 9742 * @param shortMsg Short message describing the crash. 9743 * @param longMsg Long message describing the crash. 9744 * @param stackTrace Full crash stack trace, may be null. 9745 * 9746 * @return Returns a fully-formed AppErrorStateInfo record. 9747 */ 9748 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9749 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9750 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9751 9752 report.condition = condition; 9753 report.processName = app.processName; 9754 report.pid = app.pid; 9755 report.uid = app.info.uid; 9756 report.tag = activity; 9757 report.shortMsg = shortMsg; 9758 report.longMsg = longMsg; 9759 report.stackTrace = stackTrace; 9760 9761 return report; 9762 } 9763 9764 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9765 synchronized (this) { 9766 app.crashing = false; 9767 app.crashingReport = null; 9768 app.notResponding = false; 9769 app.notRespondingReport = null; 9770 if (app.anrDialog == fromDialog) { 9771 app.anrDialog = null; 9772 } 9773 if (app.waitDialog == fromDialog) { 9774 app.waitDialog = null; 9775 } 9776 if (app.pid > 0 && app.pid != MY_PID) { 9777 handleAppCrashLocked(app, null, null, null); 9778 killUnneededProcessLocked(app, "user request after error"); 9779 } 9780 } 9781 } 9782 9783 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9784 String stackTrace) { 9785 long now = SystemClock.uptimeMillis(); 9786 9787 Long crashTime; 9788 if (!app.isolated) { 9789 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9790 } else { 9791 crashTime = null; 9792 } 9793 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9794 // This process loses! 9795 Slog.w(TAG, "Process " + app.info.processName 9796 + " has crashed too many times: killing!"); 9797 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9798 app.userId, app.info.processName, app.uid); 9799 mStackSupervisor.handleAppCrashLocked(app); 9800 if (!app.persistent) { 9801 // We don't want to start this process again until the user 9802 // explicitly does so... but for persistent process, we really 9803 // need to keep it running. If a persistent process is actually 9804 // repeatedly crashing, then badness for everyone. 9805 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9806 app.info.processName); 9807 if (!app.isolated) { 9808 // XXX We don't have a way to mark isolated processes 9809 // as bad, since they don't have a peristent identity. 9810 mBadProcesses.put(app.info.processName, app.uid, 9811 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9812 mProcessCrashTimes.remove(app.info.processName, app.uid); 9813 } 9814 app.bad = true; 9815 app.removed = true; 9816 // Don't let services in this process be restarted and potentially 9817 // annoy the user repeatedly. Unless it is persistent, since those 9818 // processes run critical code. 9819 removeProcessLocked(app, false, false, "crash"); 9820 mStackSupervisor.resumeTopActivitiesLocked(); 9821 return false; 9822 } 9823 mStackSupervisor.resumeTopActivitiesLocked(); 9824 } else { 9825 mStackSupervisor.finishTopRunningActivityLocked(app); 9826 } 9827 9828 // Bump up the crash count of any services currently running in the proc. 9829 for (int i=app.services.size()-1; i>=0; i--) { 9830 // Any services running in the application need to be placed 9831 // back in the pending list. 9832 ServiceRecord sr = app.services.valueAt(i); 9833 sr.crashCount++; 9834 } 9835 9836 // If the crashing process is what we consider to be the "home process" and it has been 9837 // replaced by a third-party app, clear the package preferred activities from packages 9838 // with a home activity running in the process to prevent a repeatedly crashing app 9839 // from blocking the user to manually clear the list. 9840 final ArrayList<ActivityRecord> activities = app.activities; 9841 if (app == mHomeProcess && activities.size() > 0 9842 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9843 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9844 final ActivityRecord r = activities.get(activityNdx); 9845 if (r.isHomeActivity()) { 9846 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9847 try { 9848 ActivityThread.getPackageManager() 9849 .clearPackagePreferredActivities(r.packageName); 9850 } catch (RemoteException c) { 9851 // pm is in same process, this will never happen. 9852 } 9853 } 9854 } 9855 } 9856 9857 if (!app.isolated) { 9858 // XXX Can't keep track of crash times for isolated processes, 9859 // because they don't have a perisistent identity. 9860 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9861 } 9862 9863 return true; 9864 } 9865 9866 void startAppProblemLocked(ProcessRecord app) { 9867 if (app.userId == mCurrentUserId) { 9868 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9869 mContext, app.info.packageName, app.info.flags); 9870 } else { 9871 // If this app is not running under the current user, then we 9872 // can't give it a report button because that would require 9873 // launching the report UI under a different user. 9874 app.errorReportReceiver = null; 9875 } 9876 skipCurrentReceiverLocked(app); 9877 } 9878 9879 void skipCurrentReceiverLocked(ProcessRecord app) { 9880 for (BroadcastQueue queue : mBroadcastQueues) { 9881 queue.skipCurrentReceiverLocked(app); 9882 } 9883 } 9884 9885 /** 9886 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9887 * The application process will exit immediately after this call returns. 9888 * @param app object of the crashing app, null for the system server 9889 * @param crashInfo describing the exception 9890 */ 9891 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9892 ProcessRecord r = findAppProcess(app, "Crash"); 9893 final String processName = app == null ? "system_server" 9894 : (r == null ? "unknown" : r.processName); 9895 9896 handleApplicationCrashInner("crash", r, processName, crashInfo); 9897 } 9898 9899 /* Native crash reporting uses this inner version because it needs to be somewhat 9900 * decoupled from the AM-managed cleanup lifecycle 9901 */ 9902 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9903 ApplicationErrorReport.CrashInfo crashInfo) { 9904 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9905 UserHandle.getUserId(Binder.getCallingUid()), processName, 9906 r == null ? -1 : r.info.flags, 9907 crashInfo.exceptionClassName, 9908 crashInfo.exceptionMessage, 9909 crashInfo.throwFileName, 9910 crashInfo.throwLineNumber); 9911 9912 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9913 9914 crashApplication(r, crashInfo); 9915 } 9916 9917 public void handleApplicationStrictModeViolation( 9918 IBinder app, 9919 int violationMask, 9920 StrictMode.ViolationInfo info) { 9921 ProcessRecord r = findAppProcess(app, "StrictMode"); 9922 if (r == null) { 9923 return; 9924 } 9925 9926 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9927 Integer stackFingerprint = info.hashCode(); 9928 boolean logIt = true; 9929 synchronized (mAlreadyLoggedViolatedStacks) { 9930 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9931 logIt = false; 9932 // TODO: sub-sample into EventLog for these, with 9933 // the info.durationMillis? Then we'd get 9934 // the relative pain numbers, without logging all 9935 // the stack traces repeatedly. We'd want to do 9936 // likewise in the client code, which also does 9937 // dup suppression, before the Binder call. 9938 } else { 9939 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9940 mAlreadyLoggedViolatedStacks.clear(); 9941 } 9942 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9943 } 9944 } 9945 if (logIt) { 9946 logStrictModeViolationToDropBox(r, info); 9947 } 9948 } 9949 9950 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9951 AppErrorResult result = new AppErrorResult(); 9952 synchronized (this) { 9953 final long origId = Binder.clearCallingIdentity(); 9954 9955 Message msg = Message.obtain(); 9956 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9957 HashMap<String, Object> data = new HashMap<String, Object>(); 9958 data.put("result", result); 9959 data.put("app", r); 9960 data.put("violationMask", violationMask); 9961 data.put("info", info); 9962 msg.obj = data; 9963 mHandler.sendMessage(msg); 9964 9965 Binder.restoreCallingIdentity(origId); 9966 } 9967 int res = result.get(); 9968 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9969 } 9970 } 9971 9972 // Depending on the policy in effect, there could be a bunch of 9973 // these in quick succession so we try to batch these together to 9974 // minimize disk writes, number of dropbox entries, and maximize 9975 // compression, by having more fewer, larger records. 9976 private void logStrictModeViolationToDropBox( 9977 ProcessRecord process, 9978 StrictMode.ViolationInfo info) { 9979 if (info == null) { 9980 return; 9981 } 9982 final boolean isSystemApp = process == null || 9983 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9984 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9985 final String processName = process == null ? "unknown" : process.processName; 9986 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9987 final DropBoxManager dbox = (DropBoxManager) 9988 mContext.getSystemService(Context.DROPBOX_SERVICE); 9989 9990 // Exit early if the dropbox isn't configured to accept this report type. 9991 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9992 9993 boolean bufferWasEmpty; 9994 boolean needsFlush; 9995 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9996 synchronized (sb) { 9997 bufferWasEmpty = sb.length() == 0; 9998 appendDropBoxProcessHeaders(process, processName, sb); 9999 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10000 sb.append("System-App: ").append(isSystemApp).append("\n"); 10001 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10002 if (info.violationNumThisLoop != 0) { 10003 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10004 } 10005 if (info.numAnimationsRunning != 0) { 10006 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10007 } 10008 if (info.broadcastIntentAction != null) { 10009 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10010 } 10011 if (info.durationMillis != -1) { 10012 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10013 } 10014 if (info.numInstances != -1) { 10015 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10016 } 10017 if (info.tags != null) { 10018 for (String tag : info.tags) { 10019 sb.append("Span-Tag: ").append(tag).append("\n"); 10020 } 10021 } 10022 sb.append("\n"); 10023 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10024 sb.append(info.crashInfo.stackTrace); 10025 } 10026 sb.append("\n"); 10027 10028 // Only buffer up to ~64k. Various logging bits truncate 10029 // things at 128k. 10030 needsFlush = (sb.length() > 64 * 1024); 10031 } 10032 10033 // Flush immediately if the buffer's grown too large, or this 10034 // is a non-system app. Non-system apps are isolated with a 10035 // different tag & policy and not batched. 10036 // 10037 // Batching is useful during internal testing with 10038 // StrictMode settings turned up high. Without batching, 10039 // thousands of separate files could be created on boot. 10040 if (!isSystemApp || needsFlush) { 10041 new Thread("Error dump: " + dropboxTag) { 10042 @Override 10043 public void run() { 10044 String report; 10045 synchronized (sb) { 10046 report = sb.toString(); 10047 sb.delete(0, sb.length()); 10048 sb.trimToSize(); 10049 } 10050 if (report.length() != 0) { 10051 dbox.addText(dropboxTag, report); 10052 } 10053 } 10054 }.start(); 10055 return; 10056 } 10057 10058 // System app batching: 10059 if (!bufferWasEmpty) { 10060 // An existing dropbox-writing thread is outstanding, so 10061 // we don't need to start it up. The existing thread will 10062 // catch the buffer appends we just did. 10063 return; 10064 } 10065 10066 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10067 // (After this point, we shouldn't access AMS internal data structures.) 10068 new Thread("Error dump: " + dropboxTag) { 10069 @Override 10070 public void run() { 10071 // 5 second sleep to let stacks arrive and be batched together 10072 try { 10073 Thread.sleep(5000); // 5 seconds 10074 } catch (InterruptedException e) {} 10075 10076 String errorReport; 10077 synchronized (mStrictModeBuffer) { 10078 errorReport = mStrictModeBuffer.toString(); 10079 if (errorReport.length() == 0) { 10080 return; 10081 } 10082 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10083 mStrictModeBuffer.trimToSize(); 10084 } 10085 dbox.addText(dropboxTag, errorReport); 10086 } 10087 }.start(); 10088 } 10089 10090 /** 10091 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10092 * @param app object of the crashing app, null for the system server 10093 * @param tag reported by the caller 10094 * @param crashInfo describing the context of the error 10095 * @return true if the process should exit immediately (WTF is fatal) 10096 */ 10097 public boolean handleApplicationWtf(IBinder app, String tag, 10098 ApplicationErrorReport.CrashInfo crashInfo) { 10099 ProcessRecord r = findAppProcess(app, "WTF"); 10100 final String processName = app == null ? "system_server" 10101 : (r == null ? "unknown" : r.processName); 10102 10103 EventLog.writeEvent(EventLogTags.AM_WTF, 10104 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10105 processName, 10106 r == null ? -1 : r.info.flags, 10107 tag, crashInfo.exceptionMessage); 10108 10109 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10110 10111 if (r != null && r.pid != Process.myPid() && 10112 Settings.Global.getInt(mContext.getContentResolver(), 10113 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10114 crashApplication(r, crashInfo); 10115 return true; 10116 } else { 10117 return false; 10118 } 10119 } 10120 10121 /** 10122 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10123 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10124 */ 10125 private ProcessRecord findAppProcess(IBinder app, String reason) { 10126 if (app == null) { 10127 return null; 10128 } 10129 10130 synchronized (this) { 10131 final int NP = mProcessNames.getMap().size(); 10132 for (int ip=0; ip<NP; ip++) { 10133 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10134 final int NA = apps.size(); 10135 for (int ia=0; ia<NA; ia++) { 10136 ProcessRecord p = apps.valueAt(ia); 10137 if (p.thread != null && p.thread.asBinder() == app) { 10138 return p; 10139 } 10140 } 10141 } 10142 10143 Slog.w(TAG, "Can't find mystery application for " + reason 10144 + " from pid=" + Binder.getCallingPid() 10145 + " uid=" + Binder.getCallingUid() + ": " + app); 10146 return null; 10147 } 10148 } 10149 10150 /** 10151 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10152 * to append various headers to the dropbox log text. 10153 */ 10154 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10155 StringBuilder sb) { 10156 // Watchdog thread ends up invoking this function (with 10157 // a null ProcessRecord) to add the stack file to dropbox. 10158 // Do not acquire a lock on this (am) in such cases, as it 10159 // could cause a potential deadlock, if and when watchdog 10160 // is invoked due to unavailability of lock on am and it 10161 // would prevent watchdog from killing system_server. 10162 if (process == null) { 10163 sb.append("Process: ").append(processName).append("\n"); 10164 return; 10165 } 10166 // Note: ProcessRecord 'process' is guarded by the service 10167 // instance. (notably process.pkgList, which could otherwise change 10168 // concurrently during execution of this method) 10169 synchronized (this) { 10170 sb.append("Process: ").append(processName).append("\n"); 10171 int flags = process.info.flags; 10172 IPackageManager pm = AppGlobals.getPackageManager(); 10173 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10174 for (int ip=0; ip<process.pkgList.size(); ip++) { 10175 String pkg = process.pkgList.keyAt(ip); 10176 sb.append("Package: ").append(pkg); 10177 try { 10178 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10179 if (pi != null) { 10180 sb.append(" v").append(pi.versionCode); 10181 if (pi.versionName != null) { 10182 sb.append(" (").append(pi.versionName).append(")"); 10183 } 10184 } 10185 } catch (RemoteException e) { 10186 Slog.e(TAG, "Error getting package info: " + pkg, e); 10187 } 10188 sb.append("\n"); 10189 } 10190 } 10191 } 10192 10193 private static String processClass(ProcessRecord process) { 10194 if (process == null || process.pid == MY_PID) { 10195 return "system_server"; 10196 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10197 return "system_app"; 10198 } else { 10199 return "data_app"; 10200 } 10201 } 10202 10203 /** 10204 * Write a description of an error (crash, WTF, ANR) to the drop box. 10205 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10206 * @param process which caused the error, null means the system server 10207 * @param activity which triggered the error, null if unknown 10208 * @param parent activity related to the error, null if unknown 10209 * @param subject line related to the error, null if absent 10210 * @param report in long form describing the error, null if absent 10211 * @param logFile to include in the report, null if none 10212 * @param crashInfo giving an application stack trace, null if absent 10213 */ 10214 public void addErrorToDropBox(String eventType, 10215 ProcessRecord process, String processName, ActivityRecord activity, 10216 ActivityRecord parent, String subject, 10217 final String report, final File logFile, 10218 final ApplicationErrorReport.CrashInfo crashInfo) { 10219 // NOTE -- this must never acquire the ActivityManagerService lock, 10220 // otherwise the watchdog may be prevented from resetting the system. 10221 10222 final String dropboxTag = processClass(process) + "_" + eventType; 10223 final DropBoxManager dbox = (DropBoxManager) 10224 mContext.getSystemService(Context.DROPBOX_SERVICE); 10225 10226 // Exit early if the dropbox isn't configured to accept this report type. 10227 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10228 10229 final StringBuilder sb = new StringBuilder(1024); 10230 appendDropBoxProcessHeaders(process, processName, sb); 10231 if (activity != null) { 10232 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10233 } 10234 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10235 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10236 } 10237 if (parent != null && parent != activity) { 10238 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10239 } 10240 if (subject != null) { 10241 sb.append("Subject: ").append(subject).append("\n"); 10242 } 10243 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10244 if (Debug.isDebuggerConnected()) { 10245 sb.append("Debugger: Connected\n"); 10246 } 10247 sb.append("\n"); 10248 10249 // Do the rest in a worker thread to avoid blocking the caller on I/O 10250 // (After this point, we shouldn't access AMS internal data structures.) 10251 Thread worker = new Thread("Error dump: " + dropboxTag) { 10252 @Override 10253 public void run() { 10254 if (report != null) { 10255 sb.append(report); 10256 } 10257 if (logFile != null) { 10258 try { 10259 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10260 "\n\n[[TRUNCATED]]")); 10261 } catch (IOException e) { 10262 Slog.e(TAG, "Error reading " + logFile, e); 10263 } 10264 } 10265 if (crashInfo != null && crashInfo.stackTrace != null) { 10266 sb.append(crashInfo.stackTrace); 10267 } 10268 10269 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10270 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10271 if (lines > 0) { 10272 sb.append("\n"); 10273 10274 // Merge several logcat streams, and take the last N lines 10275 InputStreamReader input = null; 10276 try { 10277 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10278 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10279 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10280 10281 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10282 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10283 input = new InputStreamReader(logcat.getInputStream()); 10284 10285 int num; 10286 char[] buf = new char[8192]; 10287 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10288 } catch (IOException e) { 10289 Slog.e(TAG, "Error running logcat", e); 10290 } finally { 10291 if (input != null) try { input.close(); } catch (IOException e) {} 10292 } 10293 } 10294 10295 dbox.addText(dropboxTag, sb.toString()); 10296 } 10297 }; 10298 10299 if (process == null) { 10300 // If process is null, we are being called from some internal code 10301 // and may be about to die -- run this synchronously. 10302 worker.run(); 10303 } else { 10304 worker.start(); 10305 } 10306 } 10307 10308 /** 10309 * Bring up the "unexpected error" dialog box for a crashing app. 10310 * Deal with edge cases (intercepts from instrumented applications, 10311 * ActivityController, error intent receivers, that sort of thing). 10312 * @param r the application crashing 10313 * @param crashInfo describing the failure 10314 */ 10315 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10316 long timeMillis = System.currentTimeMillis(); 10317 String shortMsg = crashInfo.exceptionClassName; 10318 String longMsg = crashInfo.exceptionMessage; 10319 String stackTrace = crashInfo.stackTrace; 10320 if (shortMsg != null && longMsg != null) { 10321 longMsg = shortMsg + ": " + longMsg; 10322 } else if (shortMsg != null) { 10323 longMsg = shortMsg; 10324 } 10325 10326 AppErrorResult result = new AppErrorResult(); 10327 synchronized (this) { 10328 if (mController != null) { 10329 try { 10330 String name = r != null ? r.processName : null; 10331 int pid = r != null ? r.pid : Binder.getCallingPid(); 10332 if (!mController.appCrashed(name, pid, 10333 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10334 Slog.w(TAG, "Force-killing crashed app " + name 10335 + " at watcher's request"); 10336 Process.killProcess(pid); 10337 return; 10338 } 10339 } catch (RemoteException e) { 10340 mController = null; 10341 Watchdog.getInstance().setActivityController(null); 10342 } 10343 } 10344 10345 final long origId = Binder.clearCallingIdentity(); 10346 10347 // If this process is running instrumentation, finish it. 10348 if (r != null && r.instrumentationClass != null) { 10349 Slog.w(TAG, "Error in app " + r.processName 10350 + " running instrumentation " + r.instrumentationClass + ":"); 10351 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10352 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10353 Bundle info = new Bundle(); 10354 info.putString("shortMsg", shortMsg); 10355 info.putString("longMsg", longMsg); 10356 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10357 Binder.restoreCallingIdentity(origId); 10358 return; 10359 } 10360 10361 // If we can't identify the process or it's already exceeded its crash quota, 10362 // quit right away without showing a crash dialog. 10363 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10364 Binder.restoreCallingIdentity(origId); 10365 return; 10366 } 10367 10368 Message msg = Message.obtain(); 10369 msg.what = SHOW_ERROR_MSG; 10370 HashMap data = new HashMap(); 10371 data.put("result", result); 10372 data.put("app", r); 10373 msg.obj = data; 10374 mHandler.sendMessage(msg); 10375 10376 Binder.restoreCallingIdentity(origId); 10377 } 10378 10379 int res = result.get(); 10380 10381 Intent appErrorIntent = null; 10382 synchronized (this) { 10383 if (r != null && !r.isolated) { 10384 // XXX Can't keep track of crash time for isolated processes, 10385 // since they don't have a persistent identity. 10386 mProcessCrashTimes.put(r.info.processName, r.uid, 10387 SystemClock.uptimeMillis()); 10388 } 10389 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10390 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10391 } 10392 } 10393 10394 if (appErrorIntent != null) { 10395 try { 10396 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10397 } catch (ActivityNotFoundException e) { 10398 Slog.w(TAG, "bug report receiver dissappeared", e); 10399 } 10400 } 10401 } 10402 10403 Intent createAppErrorIntentLocked(ProcessRecord r, 10404 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10405 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10406 if (report == null) { 10407 return null; 10408 } 10409 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10410 result.setComponent(r.errorReportReceiver); 10411 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10412 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10413 return result; 10414 } 10415 10416 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10417 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10418 if (r.errorReportReceiver == null) { 10419 return null; 10420 } 10421 10422 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10423 return null; 10424 } 10425 10426 ApplicationErrorReport report = new ApplicationErrorReport(); 10427 report.packageName = r.info.packageName; 10428 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10429 report.processName = r.processName; 10430 report.time = timeMillis; 10431 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10432 10433 if (r.crashing || r.forceCrashReport) { 10434 report.type = ApplicationErrorReport.TYPE_CRASH; 10435 report.crashInfo = crashInfo; 10436 } else if (r.notResponding) { 10437 report.type = ApplicationErrorReport.TYPE_ANR; 10438 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10439 10440 report.anrInfo.activity = r.notRespondingReport.tag; 10441 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10442 report.anrInfo.info = r.notRespondingReport.longMsg; 10443 } 10444 10445 return report; 10446 } 10447 10448 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10449 enforceNotIsolatedCaller("getProcessesInErrorState"); 10450 // assume our apps are happy - lazy create the list 10451 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10452 10453 final boolean allUsers = ActivityManager.checkUidPermission( 10454 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10455 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10456 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10457 10458 synchronized (this) { 10459 10460 // iterate across all processes 10461 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10462 ProcessRecord app = mLruProcesses.get(i); 10463 if (!allUsers && app.userId != userId) { 10464 continue; 10465 } 10466 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10467 // This one's in trouble, so we'll generate a report for it 10468 // crashes are higher priority (in case there's a crash *and* an anr) 10469 ActivityManager.ProcessErrorStateInfo report = null; 10470 if (app.crashing) { 10471 report = app.crashingReport; 10472 } else if (app.notResponding) { 10473 report = app.notRespondingReport; 10474 } 10475 10476 if (report != null) { 10477 if (errList == null) { 10478 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10479 } 10480 errList.add(report); 10481 } else { 10482 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10483 " crashing = " + app.crashing + 10484 " notResponding = " + app.notResponding); 10485 } 10486 } 10487 } 10488 } 10489 10490 return errList; 10491 } 10492 10493 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10494 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10495 if (currApp != null) { 10496 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10497 } 10498 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10499 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10500 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10501 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10502 if (currApp != null) { 10503 currApp.lru = 0; 10504 } 10505 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10506 } else if (adj >= ProcessList.SERVICE_ADJ) { 10507 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10508 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10509 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10510 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10511 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10512 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10513 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10514 } else { 10515 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10516 } 10517 } 10518 10519 private void fillInProcMemInfo(ProcessRecord app, 10520 ActivityManager.RunningAppProcessInfo outInfo) { 10521 outInfo.pid = app.pid; 10522 outInfo.uid = app.info.uid; 10523 if (mHeavyWeightProcess == app) { 10524 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10525 } 10526 if (app.persistent) { 10527 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10528 } 10529 if (app.activities.size() > 0) { 10530 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10531 } 10532 outInfo.lastTrimLevel = app.trimMemoryLevel; 10533 int adj = app.curAdj; 10534 outInfo.importance = oomAdjToImportance(adj, outInfo); 10535 outInfo.importanceReasonCode = app.adjTypeCode; 10536 outInfo.processState = app.curProcState; 10537 } 10538 10539 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10540 enforceNotIsolatedCaller("getRunningAppProcesses"); 10541 // Lazy instantiation of list 10542 List<ActivityManager.RunningAppProcessInfo> runList = null; 10543 final boolean allUsers = ActivityManager.checkUidPermission( 10544 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10545 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10546 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10547 synchronized (this) { 10548 // Iterate across all processes 10549 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10550 ProcessRecord app = mLruProcesses.get(i); 10551 if (!allUsers && app.userId != userId) { 10552 continue; 10553 } 10554 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10555 // Generate process state info for running application 10556 ActivityManager.RunningAppProcessInfo currApp = 10557 new ActivityManager.RunningAppProcessInfo(app.processName, 10558 app.pid, app.getPackageList()); 10559 fillInProcMemInfo(app, currApp); 10560 if (app.adjSource instanceof ProcessRecord) { 10561 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10562 currApp.importanceReasonImportance = oomAdjToImportance( 10563 app.adjSourceOom, null); 10564 } else if (app.adjSource instanceof ActivityRecord) { 10565 ActivityRecord r = (ActivityRecord)app.adjSource; 10566 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10567 } 10568 if (app.adjTarget instanceof ComponentName) { 10569 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10570 } 10571 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10572 // + " lru=" + currApp.lru); 10573 if (runList == null) { 10574 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10575 } 10576 runList.add(currApp); 10577 } 10578 } 10579 } 10580 return runList; 10581 } 10582 10583 public List<ApplicationInfo> getRunningExternalApplications() { 10584 enforceNotIsolatedCaller("getRunningExternalApplications"); 10585 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10586 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10587 if (runningApps != null && runningApps.size() > 0) { 10588 Set<String> extList = new HashSet<String>(); 10589 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10590 if (app.pkgList != null) { 10591 for (String pkg : app.pkgList) { 10592 extList.add(pkg); 10593 } 10594 } 10595 } 10596 IPackageManager pm = AppGlobals.getPackageManager(); 10597 for (String pkg : extList) { 10598 try { 10599 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10600 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10601 retList.add(info); 10602 } 10603 } catch (RemoteException e) { 10604 } 10605 } 10606 } 10607 return retList; 10608 } 10609 10610 @Override 10611 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10612 enforceNotIsolatedCaller("getMyMemoryState"); 10613 synchronized (this) { 10614 ProcessRecord proc; 10615 synchronized (mPidsSelfLocked) { 10616 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10617 } 10618 fillInProcMemInfo(proc, outInfo); 10619 } 10620 } 10621 10622 @Override 10623 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10624 if (checkCallingPermission(android.Manifest.permission.DUMP) 10625 != PackageManager.PERMISSION_GRANTED) { 10626 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10627 + Binder.getCallingPid() 10628 + ", uid=" + Binder.getCallingUid() 10629 + " without permission " 10630 + android.Manifest.permission.DUMP); 10631 return; 10632 } 10633 10634 boolean dumpAll = false; 10635 boolean dumpClient = false; 10636 String dumpPackage = null; 10637 10638 int opti = 0; 10639 while (opti < args.length) { 10640 String opt = args[opti]; 10641 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10642 break; 10643 } 10644 opti++; 10645 if ("-a".equals(opt)) { 10646 dumpAll = true; 10647 } else if ("-c".equals(opt)) { 10648 dumpClient = true; 10649 } else if ("-h".equals(opt)) { 10650 pw.println("Activity manager dump options:"); 10651 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10652 pw.println(" cmd may be one of:"); 10653 pw.println(" a[ctivities]: activity stack state"); 10654 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10655 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10656 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10657 pw.println(" o[om]: out of memory management"); 10658 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10659 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10660 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10661 pw.println(" service [COMP_SPEC]: service client-side state"); 10662 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10663 pw.println(" all: dump all activities"); 10664 pw.println(" top: dump the top activity"); 10665 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10666 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10667 pw.println(" a partial substring in a component name, a"); 10668 pw.println(" hex object identifier."); 10669 pw.println(" -a: include all available server state."); 10670 pw.println(" -c: include client state."); 10671 return; 10672 } else { 10673 pw.println("Unknown argument: " + opt + "; use -h for help"); 10674 } 10675 } 10676 10677 long origId = Binder.clearCallingIdentity(); 10678 boolean more = false; 10679 // Is the caller requesting to dump a particular piece of data? 10680 if (opti < args.length) { 10681 String cmd = args[opti]; 10682 opti++; 10683 if ("activities".equals(cmd) || "a".equals(cmd)) { 10684 synchronized (this) { 10685 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10686 } 10687 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10688 String[] newArgs; 10689 String name; 10690 if (opti >= args.length) { 10691 name = null; 10692 newArgs = EMPTY_STRING_ARRAY; 10693 } else { 10694 name = args[opti]; 10695 opti++; 10696 newArgs = new String[args.length - opti]; 10697 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10698 args.length - opti); 10699 } 10700 synchronized (this) { 10701 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10702 } 10703 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10704 String[] newArgs; 10705 String name; 10706 if (opti >= args.length) { 10707 name = null; 10708 newArgs = EMPTY_STRING_ARRAY; 10709 } else { 10710 name = args[opti]; 10711 opti++; 10712 newArgs = new String[args.length - opti]; 10713 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10714 args.length - opti); 10715 } 10716 synchronized (this) { 10717 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10718 } 10719 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10720 String[] newArgs; 10721 String name; 10722 if (opti >= args.length) { 10723 name = null; 10724 newArgs = EMPTY_STRING_ARRAY; 10725 } else { 10726 name = args[opti]; 10727 opti++; 10728 newArgs = new String[args.length - opti]; 10729 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10730 args.length - opti); 10731 } 10732 synchronized (this) { 10733 dumpProcessesLocked(fd, pw, args, opti, true, name); 10734 } 10735 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10736 synchronized (this) { 10737 dumpOomLocked(fd, pw, args, opti, true); 10738 } 10739 } else if ("provider".equals(cmd)) { 10740 String[] newArgs; 10741 String name; 10742 if (opti >= args.length) { 10743 name = null; 10744 newArgs = EMPTY_STRING_ARRAY; 10745 } else { 10746 name = args[opti]; 10747 opti++; 10748 newArgs = new String[args.length - opti]; 10749 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10750 } 10751 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10752 pw.println("No providers match: " + name); 10753 pw.println("Use -h for help."); 10754 } 10755 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10756 synchronized (this) { 10757 dumpProvidersLocked(fd, pw, args, opti, true, null); 10758 } 10759 } else if ("service".equals(cmd)) { 10760 String[] newArgs; 10761 String name; 10762 if (opti >= args.length) { 10763 name = null; 10764 newArgs = EMPTY_STRING_ARRAY; 10765 } else { 10766 name = args[opti]; 10767 opti++; 10768 newArgs = new String[args.length - opti]; 10769 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10770 args.length - opti); 10771 } 10772 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10773 pw.println("No services match: " + name); 10774 pw.println("Use -h for help."); 10775 } 10776 } else if ("package".equals(cmd)) { 10777 String[] newArgs; 10778 if (opti >= args.length) { 10779 pw.println("package: no package name specified"); 10780 pw.println("Use -h for help."); 10781 } else { 10782 dumpPackage = args[opti]; 10783 opti++; 10784 newArgs = new String[args.length - opti]; 10785 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10786 args.length - opti); 10787 args = newArgs; 10788 opti = 0; 10789 more = true; 10790 } 10791 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10792 synchronized (this) { 10793 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10794 } 10795 } else { 10796 // Dumping a single activity? 10797 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10798 pw.println("Bad activity command, or no activities match: " + cmd); 10799 pw.println("Use -h for help."); 10800 } 10801 } 10802 if (!more) { 10803 Binder.restoreCallingIdentity(origId); 10804 return; 10805 } 10806 } 10807 10808 // No piece of data specified, dump everything. 10809 synchronized (this) { 10810 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10811 pw.println(); 10812 if (dumpAll) { 10813 pw.println("-------------------------------------------------------------------------------"); 10814 } 10815 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10816 pw.println(); 10817 if (dumpAll) { 10818 pw.println("-------------------------------------------------------------------------------"); 10819 } 10820 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10821 pw.println(); 10822 if (dumpAll) { 10823 pw.println("-------------------------------------------------------------------------------"); 10824 } 10825 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10826 pw.println(); 10827 if (dumpAll) { 10828 pw.println("-------------------------------------------------------------------------------"); 10829 } 10830 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10831 pw.println(); 10832 if (dumpAll) { 10833 pw.println("-------------------------------------------------------------------------------"); 10834 } 10835 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10836 } 10837 Binder.restoreCallingIdentity(origId); 10838 } 10839 10840 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10841 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10842 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10843 10844 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10845 dumpPackage); 10846 boolean needSep = printedAnything; 10847 10848 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10849 dumpPackage, needSep, " mFocusedActivity: "); 10850 if (printed) { 10851 printedAnything = true; 10852 needSep = false; 10853 } 10854 10855 if (dumpPackage == null) { 10856 if (needSep) { 10857 pw.println(); 10858 } 10859 needSep = true; 10860 printedAnything = true; 10861 mStackSupervisor.dump(pw, " "); 10862 } 10863 10864 if (mRecentTasks.size() > 0) { 10865 boolean printedHeader = false; 10866 10867 final int N = mRecentTasks.size(); 10868 for (int i=0; i<N; i++) { 10869 TaskRecord tr = mRecentTasks.get(i); 10870 if (dumpPackage != null) { 10871 if (tr.realActivity == null || 10872 !dumpPackage.equals(tr.realActivity)) { 10873 continue; 10874 } 10875 } 10876 if (!printedHeader) { 10877 if (needSep) { 10878 pw.println(); 10879 } 10880 pw.println(" Recent tasks:"); 10881 printedHeader = true; 10882 printedAnything = true; 10883 } 10884 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10885 pw.println(tr); 10886 if (dumpAll) { 10887 mRecentTasks.get(i).dump(pw, " "); 10888 } 10889 } 10890 } 10891 10892 if (!printedAnything) { 10893 pw.println(" (nothing)"); 10894 } 10895 } 10896 10897 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10898 int opti, boolean dumpAll, String dumpPackage) { 10899 boolean needSep = false; 10900 boolean printedAnything = false; 10901 int numPers = 0; 10902 10903 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10904 10905 if (dumpAll) { 10906 final int NP = mProcessNames.getMap().size(); 10907 for (int ip=0; ip<NP; ip++) { 10908 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10909 final int NA = procs.size(); 10910 for (int ia=0; ia<NA; ia++) { 10911 ProcessRecord r = procs.valueAt(ia); 10912 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10913 continue; 10914 } 10915 if (!needSep) { 10916 pw.println(" All known processes:"); 10917 needSep = true; 10918 printedAnything = true; 10919 } 10920 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10921 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10922 pw.print(" "); pw.println(r); 10923 r.dump(pw, " "); 10924 if (r.persistent) { 10925 numPers++; 10926 } 10927 } 10928 } 10929 } 10930 10931 if (mIsolatedProcesses.size() > 0) { 10932 boolean printed = false; 10933 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10934 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10935 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10936 continue; 10937 } 10938 if (!printed) { 10939 if (needSep) { 10940 pw.println(); 10941 } 10942 pw.println(" Isolated process list (sorted by uid):"); 10943 printedAnything = true; 10944 printed = true; 10945 needSep = true; 10946 } 10947 pw.println(String.format("%sIsolated #%2d: %s", 10948 " ", i, r.toString())); 10949 } 10950 } 10951 10952 if (mLruProcesses.size() > 0) { 10953 if (needSep) { 10954 pw.println(); 10955 } 10956 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10957 pw.print(" total, non-act at "); 10958 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10959 pw.print(", non-svc at "); 10960 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10961 pw.println("):"); 10962 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10963 needSep = true; 10964 printedAnything = true; 10965 } 10966 10967 if (dumpAll || dumpPackage != null) { 10968 synchronized (mPidsSelfLocked) { 10969 boolean printed = false; 10970 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10971 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10972 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10973 continue; 10974 } 10975 if (!printed) { 10976 if (needSep) pw.println(); 10977 needSep = true; 10978 pw.println(" PID mappings:"); 10979 printed = true; 10980 printedAnything = true; 10981 } 10982 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10983 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10984 } 10985 } 10986 } 10987 10988 if (mForegroundProcesses.size() > 0) { 10989 synchronized (mPidsSelfLocked) { 10990 boolean printed = false; 10991 for (int i=0; i<mForegroundProcesses.size(); i++) { 10992 ProcessRecord r = mPidsSelfLocked.get( 10993 mForegroundProcesses.valueAt(i).pid); 10994 if (dumpPackage != null && (r == null 10995 || !r.pkgList.containsKey(dumpPackage))) { 10996 continue; 10997 } 10998 if (!printed) { 10999 if (needSep) pw.println(); 11000 needSep = true; 11001 pw.println(" Foreground Processes:"); 11002 printed = true; 11003 printedAnything = true; 11004 } 11005 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11006 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11007 } 11008 } 11009 } 11010 11011 if (mPersistentStartingProcesses.size() > 0) { 11012 if (needSep) pw.println(); 11013 needSep = true; 11014 printedAnything = true; 11015 pw.println(" Persisent processes that are starting:"); 11016 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11017 "Starting Norm", "Restarting PERS", dumpPackage); 11018 } 11019 11020 if (mRemovedProcesses.size() > 0) { 11021 if (needSep) pw.println(); 11022 needSep = true; 11023 printedAnything = true; 11024 pw.println(" Processes that are being removed:"); 11025 dumpProcessList(pw, this, mRemovedProcesses, " ", 11026 "Removed Norm", "Removed PERS", dumpPackage); 11027 } 11028 11029 if (mProcessesOnHold.size() > 0) { 11030 if (needSep) pw.println(); 11031 needSep = true; 11032 printedAnything = true; 11033 pw.println(" Processes that are on old until the system is ready:"); 11034 dumpProcessList(pw, this, mProcessesOnHold, " ", 11035 "OnHold Norm", "OnHold PERS", dumpPackage); 11036 } 11037 11038 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11039 11040 if (mProcessCrashTimes.getMap().size() > 0) { 11041 boolean printed = false; 11042 long now = SystemClock.uptimeMillis(); 11043 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11044 final int NP = pmap.size(); 11045 for (int ip=0; ip<NP; ip++) { 11046 String pname = pmap.keyAt(ip); 11047 SparseArray<Long> uids = pmap.valueAt(ip); 11048 final int N = uids.size(); 11049 for (int i=0; i<N; i++) { 11050 int puid = uids.keyAt(i); 11051 ProcessRecord r = mProcessNames.get(pname, puid); 11052 if (dumpPackage != null && (r == null 11053 || !r.pkgList.containsKey(dumpPackage))) { 11054 continue; 11055 } 11056 if (!printed) { 11057 if (needSep) pw.println(); 11058 needSep = true; 11059 pw.println(" Time since processes crashed:"); 11060 printed = true; 11061 printedAnything = true; 11062 } 11063 pw.print(" Process "); pw.print(pname); 11064 pw.print(" uid "); pw.print(puid); 11065 pw.print(": last crashed "); 11066 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11067 pw.println(" ago"); 11068 } 11069 } 11070 } 11071 11072 if (mBadProcesses.getMap().size() > 0) { 11073 boolean printed = false; 11074 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11075 final int NP = pmap.size(); 11076 for (int ip=0; ip<NP; ip++) { 11077 String pname = pmap.keyAt(ip); 11078 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11079 final int N = uids.size(); 11080 for (int i=0; i<N; i++) { 11081 int puid = uids.keyAt(i); 11082 ProcessRecord r = mProcessNames.get(pname, puid); 11083 if (dumpPackage != null && (r == null 11084 || !r.pkgList.containsKey(dumpPackage))) { 11085 continue; 11086 } 11087 if (!printed) { 11088 if (needSep) pw.println(); 11089 needSep = true; 11090 pw.println(" Bad processes:"); 11091 printedAnything = true; 11092 } 11093 BadProcessInfo info = uids.valueAt(i); 11094 pw.print(" Bad process "); pw.print(pname); 11095 pw.print(" uid "); pw.print(puid); 11096 pw.print(": crashed at time "); pw.println(info.time); 11097 if (info.shortMsg != null) { 11098 pw.print(" Short msg: "); pw.println(info.shortMsg); 11099 } 11100 if (info.longMsg != null) { 11101 pw.print(" Long msg: "); pw.println(info.longMsg); 11102 } 11103 if (info.stack != null) { 11104 pw.println(" Stack:"); 11105 int lastPos = 0; 11106 for (int pos=0; pos<info.stack.length(); pos++) { 11107 if (info.stack.charAt(pos) == '\n') { 11108 pw.print(" "); 11109 pw.write(info.stack, lastPos, pos-lastPos); 11110 pw.println(); 11111 lastPos = pos+1; 11112 } 11113 } 11114 if (lastPos < info.stack.length()) { 11115 pw.print(" "); 11116 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11117 pw.println(); 11118 } 11119 } 11120 } 11121 } 11122 } 11123 11124 if (dumpPackage == null) { 11125 pw.println(); 11126 needSep = false; 11127 pw.println(" mStartedUsers:"); 11128 for (int i=0; i<mStartedUsers.size(); i++) { 11129 UserStartedState uss = mStartedUsers.valueAt(i); 11130 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11131 pw.print(": "); uss.dump("", pw); 11132 } 11133 pw.print(" mStartedUserArray: ["); 11134 for (int i=0; i<mStartedUserArray.length; i++) { 11135 if (i > 0) pw.print(", "); 11136 pw.print(mStartedUserArray[i]); 11137 } 11138 pw.println("]"); 11139 pw.print(" mUserLru: ["); 11140 for (int i=0; i<mUserLru.size(); i++) { 11141 if (i > 0) pw.print(", "); 11142 pw.print(mUserLru.get(i)); 11143 } 11144 pw.println("]"); 11145 if (dumpAll) { 11146 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11147 } 11148 } 11149 if (mHomeProcess != null && (dumpPackage == null 11150 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11151 if (needSep) { 11152 pw.println(); 11153 needSep = false; 11154 } 11155 pw.println(" mHomeProcess: " + mHomeProcess); 11156 } 11157 if (mPreviousProcess != null && (dumpPackage == null 11158 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11159 if (needSep) { 11160 pw.println(); 11161 needSep = false; 11162 } 11163 pw.println(" mPreviousProcess: " + mPreviousProcess); 11164 } 11165 if (dumpAll) { 11166 StringBuilder sb = new StringBuilder(128); 11167 sb.append(" mPreviousProcessVisibleTime: "); 11168 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11169 pw.println(sb); 11170 } 11171 if (mHeavyWeightProcess != null && (dumpPackage == null 11172 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11173 if (needSep) { 11174 pw.println(); 11175 needSep = false; 11176 } 11177 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11178 } 11179 if (dumpPackage == null) { 11180 pw.println(" mConfiguration: " + mConfiguration); 11181 } 11182 if (dumpAll) { 11183 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11184 if (mCompatModePackages.getPackages().size() > 0) { 11185 boolean printed = false; 11186 for (Map.Entry<String, Integer> entry 11187 : mCompatModePackages.getPackages().entrySet()) { 11188 String pkg = entry.getKey(); 11189 int mode = entry.getValue(); 11190 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11191 continue; 11192 } 11193 if (!printed) { 11194 pw.println(" mScreenCompatPackages:"); 11195 printed = true; 11196 } 11197 pw.print(" "); pw.print(pkg); pw.print(": "); 11198 pw.print(mode); pw.println(); 11199 } 11200 } 11201 } 11202 if (dumpPackage == null) { 11203 if (mSleeping || mWentToSleep || mLockScreenShown) { 11204 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11205 + " mLockScreenShown " + mLockScreenShown); 11206 } 11207 if (mShuttingDown || mRunningVoice) { 11208 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11209 } 11210 } 11211 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11212 || mOrigWaitForDebugger) { 11213 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11214 || dumpPackage.equals(mOrigDebugApp)) { 11215 if (needSep) { 11216 pw.println(); 11217 needSep = false; 11218 } 11219 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11220 + " mDebugTransient=" + mDebugTransient 11221 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11222 } 11223 } 11224 if (mOpenGlTraceApp != null) { 11225 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11226 if (needSep) { 11227 pw.println(); 11228 needSep = false; 11229 } 11230 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11231 } 11232 } 11233 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11234 || mProfileFd != null) { 11235 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11236 if (needSep) { 11237 pw.println(); 11238 needSep = false; 11239 } 11240 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11241 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11242 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11243 + mAutoStopProfiler); 11244 } 11245 } 11246 if (dumpPackage == null) { 11247 if (mAlwaysFinishActivities || mController != null) { 11248 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11249 + " mController=" + mController); 11250 } 11251 if (dumpAll) { 11252 pw.println(" Total persistent processes: " + numPers); 11253 pw.println(" mProcessesReady=" + mProcessesReady 11254 + " mSystemReady=" + mSystemReady); 11255 pw.println(" mBooting=" + mBooting 11256 + " mBooted=" + mBooted 11257 + " mFactoryTest=" + mFactoryTest); 11258 pw.print(" mLastPowerCheckRealtime="); 11259 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11260 pw.println(""); 11261 pw.print(" mLastPowerCheckUptime="); 11262 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11263 pw.println(""); 11264 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11265 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11266 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11267 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11268 + " (" + mLruProcesses.size() + " total)" 11269 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11270 + " mNumServiceProcs=" + mNumServiceProcs 11271 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11272 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11273 + " mLastMemoryLevel" + mLastMemoryLevel 11274 + " mLastNumProcesses" + mLastNumProcesses); 11275 long now = SystemClock.uptimeMillis(); 11276 pw.print(" mLastIdleTime="); 11277 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11278 pw.print(" mLowRamSinceLastIdle="); 11279 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11280 pw.println(); 11281 } 11282 } 11283 11284 if (!printedAnything) { 11285 pw.println(" (nothing)"); 11286 } 11287 } 11288 11289 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11290 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11291 if (mProcessesToGc.size() > 0) { 11292 boolean printed = false; 11293 long now = SystemClock.uptimeMillis(); 11294 for (int i=0; i<mProcessesToGc.size(); i++) { 11295 ProcessRecord proc = mProcessesToGc.get(i); 11296 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11297 continue; 11298 } 11299 if (!printed) { 11300 if (needSep) pw.println(); 11301 needSep = true; 11302 pw.println(" Processes that are waiting to GC:"); 11303 printed = true; 11304 } 11305 pw.print(" Process "); pw.println(proc); 11306 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11307 pw.print(", last gced="); 11308 pw.print(now-proc.lastRequestedGc); 11309 pw.print(" ms ago, last lowMem="); 11310 pw.print(now-proc.lastLowMemory); 11311 pw.println(" ms ago"); 11312 11313 } 11314 } 11315 return needSep; 11316 } 11317 11318 void printOomLevel(PrintWriter pw, String name, int adj) { 11319 pw.print(" "); 11320 if (adj >= 0) { 11321 pw.print(' '); 11322 if (adj < 10) pw.print(' '); 11323 } else { 11324 if (adj > -10) pw.print(' '); 11325 } 11326 pw.print(adj); 11327 pw.print(": "); 11328 pw.print(name); 11329 pw.print(" ("); 11330 pw.print(mProcessList.getMemLevel(adj)/1024); 11331 pw.println(" kB)"); 11332 } 11333 11334 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11335 int opti, boolean dumpAll) { 11336 boolean needSep = false; 11337 11338 if (mLruProcesses.size() > 0) { 11339 if (needSep) pw.println(); 11340 needSep = true; 11341 pw.println(" OOM levels:"); 11342 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11343 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11344 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11345 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11346 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11347 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11348 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11349 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11350 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11351 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11352 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11353 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11354 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11355 11356 if (needSep) pw.println(); 11357 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11358 pw.print(" total, non-act at "); 11359 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11360 pw.print(", non-svc at "); 11361 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11362 pw.println("):"); 11363 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11364 needSep = true; 11365 } 11366 11367 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11368 11369 pw.println(); 11370 pw.println(" mHomeProcess: " + mHomeProcess); 11371 pw.println(" mPreviousProcess: " + mPreviousProcess); 11372 if (mHeavyWeightProcess != null) { 11373 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11374 } 11375 11376 return true; 11377 } 11378 11379 /** 11380 * There are three ways to call this: 11381 * - no provider specified: dump all the providers 11382 * - a flattened component name that matched an existing provider was specified as the 11383 * first arg: dump that one provider 11384 * - the first arg isn't the flattened component name of an existing provider: 11385 * dump all providers whose component contains the first arg as a substring 11386 */ 11387 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11388 int opti, boolean dumpAll) { 11389 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11390 } 11391 11392 static class ItemMatcher { 11393 ArrayList<ComponentName> components; 11394 ArrayList<String> strings; 11395 ArrayList<Integer> objects; 11396 boolean all; 11397 11398 ItemMatcher() { 11399 all = true; 11400 } 11401 11402 void build(String name) { 11403 ComponentName componentName = ComponentName.unflattenFromString(name); 11404 if (componentName != null) { 11405 if (components == null) { 11406 components = new ArrayList<ComponentName>(); 11407 } 11408 components.add(componentName); 11409 all = false; 11410 } else { 11411 int objectId = 0; 11412 // Not a '/' separated full component name; maybe an object ID? 11413 try { 11414 objectId = Integer.parseInt(name, 16); 11415 if (objects == null) { 11416 objects = new ArrayList<Integer>(); 11417 } 11418 objects.add(objectId); 11419 all = false; 11420 } catch (RuntimeException e) { 11421 // Not an integer; just do string match. 11422 if (strings == null) { 11423 strings = new ArrayList<String>(); 11424 } 11425 strings.add(name); 11426 all = false; 11427 } 11428 } 11429 } 11430 11431 int build(String[] args, int opti) { 11432 for (; opti<args.length; opti++) { 11433 String name = args[opti]; 11434 if ("--".equals(name)) { 11435 return opti+1; 11436 } 11437 build(name); 11438 } 11439 return opti; 11440 } 11441 11442 boolean match(Object object, ComponentName comp) { 11443 if (all) { 11444 return true; 11445 } 11446 if (components != null) { 11447 for (int i=0; i<components.size(); i++) { 11448 if (components.get(i).equals(comp)) { 11449 return true; 11450 } 11451 } 11452 } 11453 if (objects != null) { 11454 for (int i=0; i<objects.size(); i++) { 11455 if (System.identityHashCode(object) == objects.get(i)) { 11456 return true; 11457 } 11458 } 11459 } 11460 if (strings != null) { 11461 String flat = comp.flattenToString(); 11462 for (int i=0; i<strings.size(); i++) { 11463 if (flat.contains(strings.get(i))) { 11464 return true; 11465 } 11466 } 11467 } 11468 return false; 11469 } 11470 } 11471 11472 /** 11473 * There are three things that cmd can be: 11474 * - a flattened component name that matches an existing activity 11475 * - the cmd arg isn't the flattened component name of an existing activity: 11476 * dump all activity whose component contains the cmd as a substring 11477 * - A hex number of the ActivityRecord object instance. 11478 */ 11479 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11480 int opti, boolean dumpAll) { 11481 ArrayList<ActivityRecord> activities; 11482 11483 synchronized (this) { 11484 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11485 } 11486 11487 if (activities.size() <= 0) { 11488 return false; 11489 } 11490 11491 String[] newArgs = new String[args.length - opti]; 11492 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11493 11494 TaskRecord lastTask = null; 11495 boolean needSep = false; 11496 for (int i=activities.size()-1; i>=0; i--) { 11497 ActivityRecord r = activities.get(i); 11498 if (needSep) { 11499 pw.println(); 11500 } 11501 needSep = true; 11502 synchronized (this) { 11503 if (lastTask != r.task) { 11504 lastTask = r.task; 11505 pw.print("TASK "); pw.print(lastTask.affinity); 11506 pw.print(" id="); pw.println(lastTask.taskId); 11507 if (dumpAll) { 11508 lastTask.dump(pw, " "); 11509 } 11510 } 11511 } 11512 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11513 } 11514 return true; 11515 } 11516 11517 /** 11518 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11519 * there is a thread associated with the activity. 11520 */ 11521 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11522 final ActivityRecord r, String[] args, boolean dumpAll) { 11523 String innerPrefix = prefix + " "; 11524 synchronized (this) { 11525 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11526 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11527 pw.print(" pid="); 11528 if (r.app != null) pw.println(r.app.pid); 11529 else pw.println("(not running)"); 11530 if (dumpAll) { 11531 r.dump(pw, innerPrefix); 11532 } 11533 } 11534 if (r.app != null && r.app.thread != null) { 11535 // flush anything that is already in the PrintWriter since the thread is going 11536 // to write to the file descriptor directly 11537 pw.flush(); 11538 try { 11539 TransferPipe tp = new TransferPipe(); 11540 try { 11541 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11542 r.appToken, innerPrefix, args); 11543 tp.go(fd); 11544 } finally { 11545 tp.kill(); 11546 } 11547 } catch (IOException e) { 11548 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11549 } catch (RemoteException e) { 11550 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11551 } 11552 } 11553 } 11554 11555 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11556 int opti, boolean dumpAll, String dumpPackage) { 11557 boolean needSep = false; 11558 boolean onlyHistory = false; 11559 boolean printedAnything = false; 11560 11561 if ("history".equals(dumpPackage)) { 11562 if (opti < args.length && "-s".equals(args[opti])) { 11563 dumpAll = false; 11564 } 11565 onlyHistory = true; 11566 dumpPackage = null; 11567 } 11568 11569 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11570 if (!onlyHistory && dumpAll) { 11571 if (mRegisteredReceivers.size() > 0) { 11572 boolean printed = false; 11573 Iterator it = mRegisteredReceivers.values().iterator(); 11574 while (it.hasNext()) { 11575 ReceiverList r = (ReceiverList)it.next(); 11576 if (dumpPackage != null && (r.app == null || 11577 !dumpPackage.equals(r.app.info.packageName))) { 11578 continue; 11579 } 11580 if (!printed) { 11581 pw.println(" Registered Receivers:"); 11582 needSep = true; 11583 printed = true; 11584 printedAnything = true; 11585 } 11586 pw.print(" * "); pw.println(r); 11587 r.dump(pw, " "); 11588 } 11589 } 11590 11591 if (mReceiverResolver.dump(pw, needSep ? 11592 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11593 " ", dumpPackage, false)) { 11594 needSep = true; 11595 printedAnything = true; 11596 } 11597 } 11598 11599 for (BroadcastQueue q : mBroadcastQueues) { 11600 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11601 printedAnything |= needSep; 11602 } 11603 11604 needSep = true; 11605 11606 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11607 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11608 if (needSep) { 11609 pw.println(); 11610 } 11611 needSep = true; 11612 printedAnything = true; 11613 pw.print(" Sticky broadcasts for user "); 11614 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11615 StringBuilder sb = new StringBuilder(128); 11616 for (Map.Entry<String, ArrayList<Intent>> ent 11617 : mStickyBroadcasts.valueAt(user).entrySet()) { 11618 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11619 if (dumpAll) { 11620 pw.println(":"); 11621 ArrayList<Intent> intents = ent.getValue(); 11622 final int N = intents.size(); 11623 for (int i=0; i<N; i++) { 11624 sb.setLength(0); 11625 sb.append(" Intent: "); 11626 intents.get(i).toShortString(sb, false, true, false, false); 11627 pw.println(sb.toString()); 11628 Bundle bundle = intents.get(i).getExtras(); 11629 if (bundle != null) { 11630 pw.print(" "); 11631 pw.println(bundle.toString()); 11632 } 11633 } 11634 } else { 11635 pw.println(""); 11636 } 11637 } 11638 } 11639 } 11640 11641 if (!onlyHistory && dumpAll) { 11642 pw.println(); 11643 for (BroadcastQueue queue : mBroadcastQueues) { 11644 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11645 + queue.mBroadcastsScheduled); 11646 } 11647 pw.println(" mHandler:"); 11648 mHandler.dump(new PrintWriterPrinter(pw), " "); 11649 needSep = true; 11650 printedAnything = true; 11651 } 11652 11653 if (!printedAnything) { 11654 pw.println(" (nothing)"); 11655 } 11656 } 11657 11658 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11659 int opti, boolean dumpAll, String dumpPackage) { 11660 boolean needSep; 11661 boolean printedAnything = false; 11662 11663 ItemMatcher matcher = new ItemMatcher(); 11664 matcher.build(args, opti); 11665 11666 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11667 11668 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11669 printedAnything |= needSep; 11670 11671 if (mLaunchingProviders.size() > 0) { 11672 boolean printed = false; 11673 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11674 ContentProviderRecord r = mLaunchingProviders.get(i); 11675 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11676 continue; 11677 } 11678 if (!printed) { 11679 if (needSep) pw.println(); 11680 needSep = true; 11681 pw.println(" Launching content providers:"); 11682 printed = true; 11683 printedAnything = true; 11684 } 11685 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11686 pw.println(r); 11687 } 11688 } 11689 11690 if (mGrantedUriPermissions.size() > 0) { 11691 boolean printed = false; 11692 int dumpUid = -2; 11693 if (dumpPackage != null) { 11694 try { 11695 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11696 } catch (NameNotFoundException e) { 11697 dumpUid = -1; 11698 } 11699 } 11700 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11701 int uid = mGrantedUriPermissions.keyAt(i); 11702 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11703 continue; 11704 } 11705 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11706 if (!printed) { 11707 if (needSep) pw.println(); 11708 needSep = true; 11709 pw.println(" Granted Uri Permissions:"); 11710 printed = true; 11711 printedAnything = true; 11712 } 11713 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11714 for (UriPermission perm : perms.values()) { 11715 pw.print(" "); pw.println(perm); 11716 if (dumpAll) { 11717 perm.dump(pw, " "); 11718 } 11719 } 11720 } 11721 } 11722 11723 if (!printedAnything) { 11724 pw.println(" (nothing)"); 11725 } 11726 } 11727 11728 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11729 int opti, boolean dumpAll, String dumpPackage) { 11730 boolean printed = false; 11731 11732 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11733 11734 if (mIntentSenderRecords.size() > 0) { 11735 Iterator<WeakReference<PendingIntentRecord>> it 11736 = mIntentSenderRecords.values().iterator(); 11737 while (it.hasNext()) { 11738 WeakReference<PendingIntentRecord> ref = it.next(); 11739 PendingIntentRecord rec = ref != null ? ref.get(): null; 11740 if (dumpPackage != null && (rec == null 11741 || !dumpPackage.equals(rec.key.packageName))) { 11742 continue; 11743 } 11744 printed = true; 11745 if (rec != null) { 11746 pw.print(" * "); pw.println(rec); 11747 if (dumpAll) { 11748 rec.dump(pw, " "); 11749 } 11750 } else { 11751 pw.print(" * "); pw.println(ref); 11752 } 11753 } 11754 } 11755 11756 if (!printed) { 11757 pw.println(" (nothing)"); 11758 } 11759 } 11760 11761 private static final int dumpProcessList(PrintWriter pw, 11762 ActivityManagerService service, List list, 11763 String prefix, String normalLabel, String persistentLabel, 11764 String dumpPackage) { 11765 int numPers = 0; 11766 final int N = list.size()-1; 11767 for (int i=N; i>=0; i--) { 11768 ProcessRecord r = (ProcessRecord)list.get(i); 11769 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11770 continue; 11771 } 11772 pw.println(String.format("%s%s #%2d: %s", 11773 prefix, (r.persistent ? persistentLabel : normalLabel), 11774 i, r.toString())); 11775 if (r.persistent) { 11776 numPers++; 11777 } 11778 } 11779 return numPers; 11780 } 11781 11782 private static final boolean dumpProcessOomList(PrintWriter pw, 11783 ActivityManagerService service, List<ProcessRecord> origList, 11784 String prefix, String normalLabel, String persistentLabel, 11785 boolean inclDetails, String dumpPackage) { 11786 11787 ArrayList<Pair<ProcessRecord, Integer>> list 11788 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11789 for (int i=0; i<origList.size(); i++) { 11790 ProcessRecord r = origList.get(i); 11791 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11792 continue; 11793 } 11794 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11795 } 11796 11797 if (list.size() <= 0) { 11798 return false; 11799 } 11800 11801 Comparator<Pair<ProcessRecord, Integer>> comparator 11802 = new Comparator<Pair<ProcessRecord, Integer>>() { 11803 @Override 11804 public int compare(Pair<ProcessRecord, Integer> object1, 11805 Pair<ProcessRecord, Integer> object2) { 11806 if (object1.first.setAdj != object2.first.setAdj) { 11807 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11808 } 11809 if (object1.second.intValue() != object2.second.intValue()) { 11810 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11811 } 11812 return 0; 11813 } 11814 }; 11815 11816 Collections.sort(list, comparator); 11817 11818 final long curRealtime = SystemClock.elapsedRealtime(); 11819 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11820 final long curUptime = SystemClock.uptimeMillis(); 11821 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11822 11823 for (int i=list.size()-1; i>=0; i--) { 11824 ProcessRecord r = list.get(i).first; 11825 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11826 char schedGroup; 11827 switch (r.setSchedGroup) { 11828 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11829 schedGroup = 'B'; 11830 break; 11831 case Process.THREAD_GROUP_DEFAULT: 11832 schedGroup = 'F'; 11833 break; 11834 default: 11835 schedGroup = '?'; 11836 break; 11837 } 11838 char foreground; 11839 if (r.foregroundActivities) { 11840 foreground = 'A'; 11841 } else if (r.foregroundServices) { 11842 foreground = 'S'; 11843 } else { 11844 foreground = ' '; 11845 } 11846 String procState = ProcessList.makeProcStateString(r.curProcState); 11847 pw.print(prefix); 11848 pw.print(r.persistent ? persistentLabel : normalLabel); 11849 pw.print(" #"); 11850 int num = (origList.size()-1)-list.get(i).second; 11851 if (num < 10) pw.print(' '); 11852 pw.print(num); 11853 pw.print(": "); 11854 pw.print(oomAdj); 11855 pw.print(' '); 11856 pw.print(schedGroup); 11857 pw.print('/'); 11858 pw.print(foreground); 11859 pw.print('/'); 11860 pw.print(procState); 11861 pw.print(" trm:"); 11862 if (r.trimMemoryLevel < 10) pw.print(' '); 11863 pw.print(r.trimMemoryLevel); 11864 pw.print(' '); 11865 pw.print(r.toShortString()); 11866 pw.print(" ("); 11867 pw.print(r.adjType); 11868 pw.println(')'); 11869 if (r.adjSource != null || r.adjTarget != null) { 11870 pw.print(prefix); 11871 pw.print(" "); 11872 if (r.adjTarget instanceof ComponentName) { 11873 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11874 } else if (r.adjTarget != null) { 11875 pw.print(r.adjTarget.toString()); 11876 } else { 11877 pw.print("{null}"); 11878 } 11879 pw.print("<="); 11880 if (r.adjSource instanceof ProcessRecord) { 11881 pw.print("Proc{"); 11882 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11883 pw.println("}"); 11884 } else if (r.adjSource != null) { 11885 pw.println(r.adjSource.toString()); 11886 } else { 11887 pw.println("{null}"); 11888 } 11889 } 11890 if (inclDetails) { 11891 pw.print(prefix); 11892 pw.print(" "); 11893 pw.print("oom: max="); pw.print(r.maxAdj); 11894 pw.print(" curRaw="); pw.print(r.curRawAdj); 11895 pw.print(" setRaw="); pw.print(r.setRawAdj); 11896 pw.print(" cur="); pw.print(r.curAdj); 11897 pw.print(" set="); pw.println(r.setAdj); 11898 pw.print(prefix); 11899 pw.print(" "); 11900 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11901 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11902 pw.print(" lastPss="); pw.print(r.lastPss); 11903 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11904 pw.print(prefix); 11905 pw.print(" "); 11906 pw.print("keeping="); pw.print(r.keeping); 11907 pw.print(" cached="); pw.print(r.cached); 11908 pw.print(" empty="); pw.print(r.empty); 11909 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11910 11911 if (!r.keeping) { 11912 if (r.lastWakeTime != 0) { 11913 long wtime; 11914 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11915 synchronized (stats) { 11916 wtime = stats.getProcessWakeTime(r.info.uid, 11917 r.pid, curRealtime); 11918 } 11919 long timeUsed = wtime - r.lastWakeTime; 11920 pw.print(prefix); 11921 pw.print(" "); 11922 pw.print("keep awake over "); 11923 TimeUtils.formatDuration(realtimeSince, pw); 11924 pw.print(" used "); 11925 TimeUtils.formatDuration(timeUsed, pw); 11926 pw.print(" ("); 11927 pw.print((timeUsed*100)/realtimeSince); 11928 pw.println("%)"); 11929 } 11930 if (r.lastCpuTime != 0) { 11931 long timeUsed = r.curCpuTime - r.lastCpuTime; 11932 pw.print(prefix); 11933 pw.print(" "); 11934 pw.print("run cpu over "); 11935 TimeUtils.formatDuration(uptimeSince, pw); 11936 pw.print(" used "); 11937 TimeUtils.formatDuration(timeUsed, pw); 11938 pw.print(" ("); 11939 pw.print((timeUsed*100)/uptimeSince); 11940 pw.println("%)"); 11941 } 11942 } 11943 } 11944 } 11945 return true; 11946 } 11947 11948 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11949 ArrayList<ProcessRecord> procs; 11950 synchronized (this) { 11951 if (args != null && args.length > start 11952 && args[start].charAt(0) != '-') { 11953 procs = new ArrayList<ProcessRecord>(); 11954 int pid = -1; 11955 try { 11956 pid = Integer.parseInt(args[start]); 11957 } catch (NumberFormatException e) { 11958 } 11959 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11960 ProcessRecord proc = mLruProcesses.get(i); 11961 if (proc.pid == pid) { 11962 procs.add(proc); 11963 } else if (proc.processName.equals(args[start])) { 11964 procs.add(proc); 11965 } 11966 } 11967 if (procs.size() <= 0) { 11968 return null; 11969 } 11970 } else { 11971 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11972 } 11973 } 11974 return procs; 11975 } 11976 11977 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11978 PrintWriter pw, String[] args) { 11979 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11980 if (procs == null) { 11981 pw.println("No process found for: " + args[0]); 11982 return; 11983 } 11984 11985 long uptime = SystemClock.uptimeMillis(); 11986 long realtime = SystemClock.elapsedRealtime(); 11987 pw.println("Applications Graphics Acceleration Info:"); 11988 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11989 11990 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11991 ProcessRecord r = procs.get(i); 11992 if (r.thread != null) { 11993 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11994 pw.flush(); 11995 try { 11996 TransferPipe tp = new TransferPipe(); 11997 try { 11998 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11999 tp.go(fd); 12000 } finally { 12001 tp.kill(); 12002 } 12003 } catch (IOException e) { 12004 pw.println("Failure while dumping the app: " + r); 12005 pw.flush(); 12006 } catch (RemoteException e) { 12007 pw.println("Got a RemoteException while dumping the app " + r); 12008 pw.flush(); 12009 } 12010 } 12011 } 12012 } 12013 12014 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12015 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12016 if (procs == null) { 12017 pw.println("No process found for: " + args[0]); 12018 return; 12019 } 12020 12021 pw.println("Applications Database Info:"); 12022 12023 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12024 ProcessRecord r = procs.get(i); 12025 if (r.thread != null) { 12026 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12027 pw.flush(); 12028 try { 12029 TransferPipe tp = new TransferPipe(); 12030 try { 12031 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12032 tp.go(fd); 12033 } finally { 12034 tp.kill(); 12035 } 12036 } catch (IOException e) { 12037 pw.println("Failure while dumping the app: " + r); 12038 pw.flush(); 12039 } catch (RemoteException e) { 12040 pw.println("Got a RemoteException while dumping the app " + r); 12041 pw.flush(); 12042 } 12043 } 12044 } 12045 } 12046 12047 final static class MemItem { 12048 final boolean isProc; 12049 final String label; 12050 final String shortLabel; 12051 final long pss; 12052 final int id; 12053 final boolean hasActivities; 12054 ArrayList<MemItem> subitems; 12055 12056 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12057 boolean _hasActivities) { 12058 isProc = true; 12059 label = _label; 12060 shortLabel = _shortLabel; 12061 pss = _pss; 12062 id = _id; 12063 hasActivities = _hasActivities; 12064 } 12065 12066 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12067 isProc = false; 12068 label = _label; 12069 shortLabel = _shortLabel; 12070 pss = _pss; 12071 id = _id; 12072 hasActivities = false; 12073 } 12074 } 12075 12076 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12077 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12078 if (sort && !isCompact) { 12079 Collections.sort(items, new Comparator<MemItem>() { 12080 @Override 12081 public int compare(MemItem lhs, MemItem rhs) { 12082 if (lhs.pss < rhs.pss) { 12083 return 1; 12084 } else if (lhs.pss > rhs.pss) { 12085 return -1; 12086 } 12087 return 0; 12088 } 12089 }); 12090 } 12091 12092 for (int i=0; i<items.size(); i++) { 12093 MemItem mi = items.get(i); 12094 if (!isCompact) { 12095 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12096 } else if (mi.isProc) { 12097 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12098 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12099 pw.println(mi.hasActivities ? ",a" : ",e"); 12100 } else { 12101 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12102 pw.println(mi.pss); 12103 } 12104 if (mi.subitems != null) { 12105 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12106 true, isCompact); 12107 } 12108 } 12109 } 12110 12111 // These are in KB. 12112 static final long[] DUMP_MEM_BUCKETS = new long[] { 12113 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12114 120*1024, 160*1024, 200*1024, 12115 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12116 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12117 }; 12118 12119 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12120 boolean stackLike) { 12121 int start = label.lastIndexOf('.'); 12122 if (start >= 0) start++; 12123 else start = 0; 12124 int end = label.length(); 12125 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12126 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12127 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12128 out.append(bucket); 12129 out.append(stackLike ? "MB." : "MB "); 12130 out.append(label, start, end); 12131 return; 12132 } 12133 } 12134 out.append(memKB/1024); 12135 out.append(stackLike ? "MB." : "MB "); 12136 out.append(label, start, end); 12137 } 12138 12139 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12140 ProcessList.NATIVE_ADJ, 12141 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12142 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12143 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12144 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12145 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12146 }; 12147 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12148 "Native", 12149 "System", "Persistent", "Foreground", 12150 "Visible", "Perceptible", 12151 "Heavy Weight", "Backup", 12152 "A Services", "Home", 12153 "Previous", "B Services", "Cached" 12154 }; 12155 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12156 "native", 12157 "sys", "pers", "fore", 12158 "vis", "percept", 12159 "heavy", "backup", 12160 "servicea", "home", 12161 "prev", "serviceb", "cached" 12162 }; 12163 12164 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12165 long realtime, boolean isCheckinRequest, boolean isCompact) { 12166 if (isCheckinRequest || isCompact) { 12167 // short checkin version 12168 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12169 } else { 12170 pw.println("Applications Memory Usage (kB):"); 12171 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12172 } 12173 } 12174 12175 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12176 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12177 boolean dumpDetails = false; 12178 boolean dumpFullDetails = false; 12179 boolean dumpDalvik = false; 12180 boolean oomOnly = false; 12181 boolean isCompact = false; 12182 boolean localOnly = false; 12183 12184 int opti = 0; 12185 while (opti < args.length) { 12186 String opt = args[opti]; 12187 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12188 break; 12189 } 12190 opti++; 12191 if ("-a".equals(opt)) { 12192 dumpDetails = true; 12193 dumpFullDetails = true; 12194 dumpDalvik = true; 12195 } else if ("-d".equals(opt)) { 12196 dumpDalvik = true; 12197 } else if ("-c".equals(opt)) { 12198 isCompact = true; 12199 } else if ("--oom".equals(opt)) { 12200 oomOnly = true; 12201 } else if ("--local".equals(opt)) { 12202 localOnly = true; 12203 } else if ("-h".equals(opt)) { 12204 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12205 pw.println(" -a: include all available information for each process."); 12206 pw.println(" -d: include dalvik details when dumping process details."); 12207 pw.println(" -c: dump in a compact machine-parseable representation."); 12208 pw.println(" --oom: only show processes organized by oom adj."); 12209 pw.println(" --local: only collect details locally, don't call process."); 12210 pw.println("If [process] is specified it can be the name or "); 12211 pw.println("pid of a specific process to dump."); 12212 return; 12213 } else { 12214 pw.println("Unknown argument: " + opt + "; use -h for help"); 12215 } 12216 } 12217 12218 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12219 long uptime = SystemClock.uptimeMillis(); 12220 long realtime = SystemClock.elapsedRealtime(); 12221 final long[] tmpLong = new long[1]; 12222 12223 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12224 if (procs == null) { 12225 // No Java processes. Maybe they want to print a native process. 12226 if (args != null && args.length > opti 12227 && args[opti].charAt(0) != '-') { 12228 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12229 = new ArrayList<ProcessCpuTracker.Stats>(); 12230 updateCpuStatsNow(); 12231 int findPid = -1; 12232 try { 12233 findPid = Integer.parseInt(args[opti]); 12234 } catch (NumberFormatException e) { 12235 } 12236 synchronized (mProcessCpuThread) { 12237 final int N = mProcessCpuTracker.countStats(); 12238 for (int i=0; i<N; i++) { 12239 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12240 if (st.pid == findPid || (st.baseName != null 12241 && st.baseName.equals(args[opti]))) { 12242 nativeProcs.add(st); 12243 } 12244 } 12245 } 12246 if (nativeProcs.size() > 0) { 12247 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12248 isCompact); 12249 Debug.MemoryInfo mi = null; 12250 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12251 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12252 final int pid = r.pid; 12253 if (!isCheckinRequest && dumpDetails) { 12254 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12255 } 12256 if (mi == null) { 12257 mi = new Debug.MemoryInfo(); 12258 } 12259 if (dumpDetails || (!brief && !oomOnly)) { 12260 Debug.getMemoryInfo(pid, mi); 12261 } else { 12262 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12263 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12264 } 12265 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12266 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12267 if (isCheckinRequest) { 12268 pw.println(); 12269 } 12270 } 12271 return; 12272 } 12273 } 12274 pw.println("No process found for: " + args[opti]); 12275 return; 12276 } 12277 12278 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12279 dumpDetails = true; 12280 } 12281 12282 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12283 12284 String[] innerArgs = new String[args.length-opti]; 12285 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12286 12287 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12288 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12289 long nativePss=0, dalvikPss=0, otherPss=0; 12290 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12291 12292 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12293 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12294 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12295 12296 long totalPss = 0; 12297 long cachedPss = 0; 12298 12299 Debug.MemoryInfo mi = null; 12300 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12301 final ProcessRecord r = procs.get(i); 12302 final IApplicationThread thread; 12303 final int pid; 12304 final int oomAdj; 12305 final boolean hasActivities; 12306 synchronized (this) { 12307 thread = r.thread; 12308 pid = r.pid; 12309 oomAdj = r.getSetAdjWithServices(); 12310 hasActivities = r.activities.size() > 0; 12311 } 12312 if (thread != null) { 12313 if (!isCheckinRequest && dumpDetails) { 12314 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12315 } 12316 if (mi == null) { 12317 mi = new Debug.MemoryInfo(); 12318 } 12319 if (dumpDetails || (!brief && !oomOnly)) { 12320 Debug.getMemoryInfo(pid, mi); 12321 } else { 12322 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12323 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12324 } 12325 if (dumpDetails) { 12326 if (localOnly) { 12327 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12328 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12329 if (isCheckinRequest) { 12330 pw.println(); 12331 } 12332 } else { 12333 try { 12334 pw.flush(); 12335 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12336 dumpDalvik, innerArgs); 12337 } catch (RemoteException e) { 12338 if (!isCheckinRequest) { 12339 pw.println("Got RemoteException!"); 12340 pw.flush(); 12341 } 12342 } 12343 } 12344 } 12345 12346 final long myTotalPss = mi.getTotalPss(); 12347 final long myTotalUss = mi.getTotalUss(); 12348 12349 synchronized (this) { 12350 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12351 // Record this for posterity if the process has been stable. 12352 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12353 } 12354 } 12355 12356 if (!isCheckinRequest && mi != null) { 12357 totalPss += myTotalPss; 12358 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12359 (hasActivities ? " / activities)" : ")"), 12360 r.processName, myTotalPss, pid, hasActivities); 12361 procMems.add(pssItem); 12362 procMemsMap.put(pid, pssItem); 12363 12364 nativePss += mi.nativePss; 12365 dalvikPss += mi.dalvikPss; 12366 otherPss += mi.otherPss; 12367 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12368 long mem = mi.getOtherPss(j); 12369 miscPss[j] += mem; 12370 otherPss -= mem; 12371 } 12372 12373 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12374 cachedPss += myTotalPss; 12375 } 12376 12377 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12378 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12379 || oomIndex == (oomPss.length-1)) { 12380 oomPss[oomIndex] += myTotalPss; 12381 if (oomProcs[oomIndex] == null) { 12382 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12383 } 12384 oomProcs[oomIndex].add(pssItem); 12385 break; 12386 } 12387 } 12388 } 12389 } 12390 } 12391 12392 if (!isCheckinRequest && procs.size() > 1) { 12393 // If we are showing aggregations, also look for native processes to 12394 // include so that our aggregations are more accurate. 12395 updateCpuStatsNow(); 12396 synchronized (mProcessCpuThread) { 12397 final int N = mProcessCpuTracker.countStats(); 12398 for (int i=0; i<N; i++) { 12399 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12400 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12401 if (mi == null) { 12402 mi = new Debug.MemoryInfo(); 12403 } 12404 if (!brief && !oomOnly) { 12405 Debug.getMemoryInfo(st.pid, mi); 12406 } else { 12407 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12408 mi.nativePrivateDirty = (int)tmpLong[0]; 12409 } 12410 12411 final long myTotalPss = mi.getTotalPss(); 12412 totalPss += myTotalPss; 12413 12414 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12415 st.name, myTotalPss, st.pid, false); 12416 procMems.add(pssItem); 12417 12418 nativePss += mi.nativePss; 12419 dalvikPss += mi.dalvikPss; 12420 otherPss += mi.otherPss; 12421 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12422 long mem = mi.getOtherPss(j); 12423 miscPss[j] += mem; 12424 otherPss -= mem; 12425 } 12426 oomPss[0] += myTotalPss; 12427 if (oomProcs[0] == null) { 12428 oomProcs[0] = new ArrayList<MemItem>(); 12429 } 12430 oomProcs[0].add(pssItem); 12431 } 12432 } 12433 } 12434 12435 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12436 12437 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12438 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12439 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12440 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12441 String label = Debug.MemoryInfo.getOtherLabel(j); 12442 catMems.add(new MemItem(label, label, miscPss[j], j)); 12443 } 12444 12445 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12446 for (int j=0; j<oomPss.length; j++) { 12447 if (oomPss[j] != 0) { 12448 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12449 : DUMP_MEM_OOM_LABEL[j]; 12450 MemItem item = new MemItem(label, label, oomPss[j], 12451 DUMP_MEM_OOM_ADJ[j]); 12452 item.subitems = oomProcs[j]; 12453 oomMems.add(item); 12454 } 12455 } 12456 12457 if (!brief && !oomOnly && !isCompact) { 12458 pw.println(); 12459 pw.println("Total PSS by process:"); 12460 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12461 pw.println(); 12462 } 12463 if (!isCompact) { 12464 pw.println("Total PSS by OOM adjustment:"); 12465 } 12466 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12467 if (!brief && !oomOnly) { 12468 PrintWriter out = categoryPw != null ? categoryPw : pw; 12469 if (!isCompact) { 12470 out.println(); 12471 out.println("Total PSS by category:"); 12472 } 12473 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12474 } 12475 if (!isCompact) { 12476 pw.println(); 12477 } 12478 MemInfoReader memInfo = new MemInfoReader(); 12479 memInfo.readMemInfo(); 12480 if (!brief) { 12481 if (!isCompact) { 12482 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12483 pw.print(" kB (status "); 12484 switch (mLastMemoryLevel) { 12485 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12486 pw.println("normal)"); 12487 break; 12488 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12489 pw.println("moderate)"); 12490 break; 12491 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12492 pw.println("low)"); 12493 break; 12494 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12495 pw.println("critical)"); 12496 break; 12497 default: 12498 pw.print(mLastMemoryLevel); 12499 pw.println(")"); 12500 break; 12501 } 12502 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12503 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12504 pw.print(cachedPss); pw.print(" cached pss + "); 12505 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12506 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12507 } else { 12508 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12509 pw.print(cachedPss + memInfo.getCachedSizeKb() 12510 + memInfo.getFreeSizeKb()); pw.print(","); 12511 pw.println(totalPss - cachedPss); 12512 } 12513 } 12514 if (!isCompact) { 12515 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12516 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12517 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12518 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12519 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12520 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12521 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12522 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12523 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12524 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12525 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12526 } 12527 if (!brief) { 12528 if (memInfo.getZramTotalSizeKb() != 0) { 12529 if (!isCompact) { 12530 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12531 pw.print(" kB physical used for "); 12532 pw.print(memInfo.getSwapTotalSizeKb() 12533 - memInfo.getSwapFreeSizeKb()); 12534 pw.print(" kB in swap ("); 12535 pw.print(memInfo.getSwapTotalSizeKb()); 12536 pw.println(" kB total swap)"); 12537 } else { 12538 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12539 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12540 pw.println(memInfo.getSwapFreeSizeKb()); 12541 } 12542 } 12543 final int[] SINGLE_LONG_FORMAT = new int[] { 12544 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12545 }; 12546 long[] longOut = new long[1]; 12547 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12548 SINGLE_LONG_FORMAT, null, longOut, null); 12549 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12550 longOut[0] = 0; 12551 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12552 SINGLE_LONG_FORMAT, null, longOut, null); 12553 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12554 longOut[0] = 0; 12555 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12556 SINGLE_LONG_FORMAT, null, longOut, null); 12557 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12558 longOut[0] = 0; 12559 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12560 SINGLE_LONG_FORMAT, null, longOut, null); 12561 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12562 if (!isCompact) { 12563 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12564 pw.print(" KSM: "); pw.print(sharing); 12565 pw.print(" kB saved from shared "); 12566 pw.print(shared); pw.println(" kB"); 12567 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12568 pw.print(voltile); pw.println(" kB volatile"); 12569 } 12570 pw.print(" Tuning: "); 12571 pw.print(ActivityManager.staticGetMemoryClass()); 12572 pw.print(" (large "); 12573 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12574 pw.print("), oom "); 12575 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12576 pw.print(" kB"); 12577 pw.print(", restore limit "); 12578 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12579 pw.print(" kB"); 12580 if (ActivityManager.isLowRamDeviceStatic()) { 12581 pw.print(" (low-ram)"); 12582 } 12583 if (ActivityManager.isHighEndGfx()) { 12584 pw.print(" (high-end-gfx)"); 12585 } 12586 pw.println(); 12587 } else { 12588 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12589 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12590 pw.println(voltile); 12591 pw.print("tuning,"); 12592 pw.print(ActivityManager.staticGetMemoryClass()); 12593 pw.print(','); 12594 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12595 pw.print(','); 12596 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12597 if (ActivityManager.isLowRamDeviceStatic()) { 12598 pw.print(",low-ram"); 12599 } 12600 if (ActivityManager.isHighEndGfx()) { 12601 pw.print(",high-end-gfx"); 12602 } 12603 pw.println(); 12604 } 12605 } 12606 } 12607 } 12608 12609 /** 12610 * Searches array of arguments for the specified string 12611 * @param args array of argument strings 12612 * @param value value to search for 12613 * @return true if the value is contained in the array 12614 */ 12615 private static boolean scanArgs(String[] args, String value) { 12616 if (args != null) { 12617 for (String arg : args) { 12618 if (value.equals(arg)) { 12619 return true; 12620 } 12621 } 12622 } 12623 return false; 12624 } 12625 12626 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12627 ContentProviderRecord cpr, boolean always) { 12628 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12629 12630 if (!inLaunching || always) { 12631 synchronized (cpr) { 12632 cpr.launchingApp = null; 12633 cpr.notifyAll(); 12634 } 12635 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12636 String names[] = cpr.info.authority.split(";"); 12637 for (int j = 0; j < names.length; j++) { 12638 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12639 } 12640 } 12641 12642 for (int i=0; i<cpr.connections.size(); i++) { 12643 ContentProviderConnection conn = cpr.connections.get(i); 12644 if (conn.waiting) { 12645 // If this connection is waiting for the provider, then we don't 12646 // need to mess with its process unless we are always removing 12647 // or for some reason the provider is not currently launching. 12648 if (inLaunching && !always) { 12649 continue; 12650 } 12651 } 12652 ProcessRecord capp = conn.client; 12653 conn.dead = true; 12654 if (conn.stableCount > 0) { 12655 if (!capp.persistent && capp.thread != null 12656 && capp.pid != 0 12657 && capp.pid != MY_PID) { 12658 killUnneededProcessLocked(capp, "depends on provider " 12659 + cpr.name.flattenToShortString() 12660 + " in dying proc " + (proc != null ? proc.processName : "??")); 12661 } 12662 } else if (capp.thread != null && conn.provider.provider != null) { 12663 try { 12664 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12665 } catch (RemoteException e) { 12666 } 12667 // In the protocol here, we don't expect the client to correctly 12668 // clean up this connection, we'll just remove it. 12669 cpr.connections.remove(i); 12670 conn.client.conProviders.remove(conn); 12671 } 12672 } 12673 12674 if (inLaunching && always) { 12675 mLaunchingProviders.remove(cpr); 12676 } 12677 return inLaunching; 12678 } 12679 12680 /** 12681 * Main code for cleaning up a process when it has gone away. This is 12682 * called both as a result of the process dying, or directly when stopping 12683 * a process when running in single process mode. 12684 */ 12685 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12686 boolean restarting, boolean allowRestart, int index) { 12687 if (index >= 0) { 12688 removeLruProcessLocked(app); 12689 ProcessList.remove(app.pid); 12690 } 12691 12692 mProcessesToGc.remove(app); 12693 mPendingPssProcesses.remove(app); 12694 12695 // Dismiss any open dialogs. 12696 if (app.crashDialog != null && !app.forceCrashReport) { 12697 app.crashDialog.dismiss(); 12698 app.crashDialog = null; 12699 } 12700 if (app.anrDialog != null) { 12701 app.anrDialog.dismiss(); 12702 app.anrDialog = null; 12703 } 12704 if (app.waitDialog != null) { 12705 app.waitDialog.dismiss(); 12706 app.waitDialog = null; 12707 } 12708 12709 app.crashing = false; 12710 app.notResponding = false; 12711 12712 app.resetPackageList(mProcessStats); 12713 app.unlinkDeathRecipient(); 12714 app.makeInactive(mProcessStats); 12715 app.forcingToForeground = null; 12716 updateProcessForegroundLocked(app, false, false); 12717 app.foregroundActivities = false; 12718 app.hasShownUi = false; 12719 app.treatLikeActivity = false; 12720 app.hasAboveClient = false; 12721 app.hasClientActivities = false; 12722 12723 mServices.killServicesLocked(app, allowRestart); 12724 12725 boolean restart = false; 12726 12727 // Remove published content providers. 12728 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12729 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12730 final boolean always = app.bad || !allowRestart; 12731 if (removeDyingProviderLocked(app, cpr, always) || always) { 12732 // We left the provider in the launching list, need to 12733 // restart it. 12734 restart = true; 12735 } 12736 12737 cpr.provider = null; 12738 cpr.proc = null; 12739 } 12740 app.pubProviders.clear(); 12741 12742 // Take care of any launching providers waiting for this process. 12743 if (checkAppInLaunchingProvidersLocked(app, false)) { 12744 restart = true; 12745 } 12746 12747 // Unregister from connected content providers. 12748 if (!app.conProviders.isEmpty()) { 12749 for (int i=0; i<app.conProviders.size(); i++) { 12750 ContentProviderConnection conn = app.conProviders.get(i); 12751 conn.provider.connections.remove(conn); 12752 } 12753 app.conProviders.clear(); 12754 } 12755 12756 // At this point there may be remaining entries in mLaunchingProviders 12757 // where we were the only one waiting, so they are no longer of use. 12758 // Look for these and clean up if found. 12759 // XXX Commented out for now. Trying to figure out a way to reproduce 12760 // the actual situation to identify what is actually going on. 12761 if (false) { 12762 for (int i=0; i<mLaunchingProviders.size(); i++) { 12763 ContentProviderRecord cpr = (ContentProviderRecord) 12764 mLaunchingProviders.get(i); 12765 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12766 synchronized (cpr) { 12767 cpr.launchingApp = null; 12768 cpr.notifyAll(); 12769 } 12770 } 12771 } 12772 } 12773 12774 skipCurrentReceiverLocked(app); 12775 12776 // Unregister any receivers. 12777 for (int i=app.receivers.size()-1; i>=0; i--) { 12778 removeReceiverLocked(app.receivers.valueAt(i)); 12779 } 12780 app.receivers.clear(); 12781 12782 // If the app is undergoing backup, tell the backup manager about it 12783 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12784 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12785 + mBackupTarget.appInfo + " died during backup"); 12786 try { 12787 IBackupManager bm = IBackupManager.Stub.asInterface( 12788 ServiceManager.getService(Context.BACKUP_SERVICE)); 12789 bm.agentDisconnected(app.info.packageName); 12790 } catch (RemoteException e) { 12791 // can't happen; backup manager is local 12792 } 12793 } 12794 12795 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12796 ProcessChangeItem item = mPendingProcessChanges.get(i); 12797 if (item.pid == app.pid) { 12798 mPendingProcessChanges.remove(i); 12799 mAvailProcessChanges.add(item); 12800 } 12801 } 12802 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12803 12804 // If the caller is restarting this app, then leave it in its 12805 // current lists and let the caller take care of it. 12806 if (restarting) { 12807 return; 12808 } 12809 12810 if (!app.persistent || app.isolated) { 12811 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12812 "Removing non-persistent process during cleanup: " + app); 12813 mProcessNames.remove(app.processName, app.uid); 12814 mIsolatedProcesses.remove(app.uid); 12815 if (mHeavyWeightProcess == app) { 12816 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12817 mHeavyWeightProcess.userId, 0)); 12818 mHeavyWeightProcess = null; 12819 } 12820 } else if (!app.removed) { 12821 // This app is persistent, so we need to keep its record around. 12822 // If it is not already on the pending app list, add it there 12823 // and start a new process for it. 12824 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12825 mPersistentStartingProcesses.add(app); 12826 restart = true; 12827 } 12828 } 12829 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12830 "Clean-up removing on hold: " + app); 12831 mProcessesOnHold.remove(app); 12832 12833 if (app == mHomeProcess) { 12834 mHomeProcess = null; 12835 } 12836 if (app == mPreviousProcess) { 12837 mPreviousProcess = null; 12838 } 12839 12840 if (restart && !app.isolated) { 12841 // We have components that still need to be running in the 12842 // process, so re-launch it. 12843 mProcessNames.put(app.processName, app.uid, app); 12844 startProcessLocked(app, "restart", app.processName); 12845 } else if (app.pid > 0 && app.pid != MY_PID) { 12846 // Goodbye! 12847 boolean removed; 12848 synchronized (mPidsSelfLocked) { 12849 mPidsSelfLocked.remove(app.pid); 12850 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12851 } 12852 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12853 app.processName, app.info.uid); 12854 if (app.isolated) { 12855 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12856 } 12857 app.setPid(0); 12858 } 12859 } 12860 12861 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12862 // Look through the content providers we are waiting to have launched, 12863 // and if any run in this process then either schedule a restart of 12864 // the process or kill the client waiting for it if this process has 12865 // gone bad. 12866 int NL = mLaunchingProviders.size(); 12867 boolean restart = false; 12868 for (int i=0; i<NL; i++) { 12869 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12870 if (cpr.launchingApp == app) { 12871 if (!alwaysBad && !app.bad) { 12872 restart = true; 12873 } else { 12874 removeDyingProviderLocked(app, cpr, true); 12875 // cpr should have been removed from mLaunchingProviders 12876 NL = mLaunchingProviders.size(); 12877 i--; 12878 } 12879 } 12880 } 12881 return restart; 12882 } 12883 12884 // ========================================================= 12885 // SERVICES 12886 // ========================================================= 12887 12888 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12889 int flags) { 12890 enforceNotIsolatedCaller("getServices"); 12891 synchronized (this) { 12892 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12893 } 12894 } 12895 12896 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12897 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12898 synchronized (this) { 12899 return mServices.getRunningServiceControlPanelLocked(name); 12900 } 12901 } 12902 12903 public ComponentName startService(IApplicationThread caller, Intent service, 12904 String resolvedType, int userId) { 12905 enforceNotIsolatedCaller("startService"); 12906 // Refuse possible leaked file descriptors 12907 if (service != null && service.hasFileDescriptors() == true) { 12908 throw new IllegalArgumentException("File descriptors passed in Intent"); 12909 } 12910 12911 if (DEBUG_SERVICE) 12912 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12913 synchronized(this) { 12914 final int callingPid = Binder.getCallingPid(); 12915 final int callingUid = Binder.getCallingUid(); 12916 final long origId = Binder.clearCallingIdentity(); 12917 ComponentName res = mServices.startServiceLocked(caller, service, 12918 resolvedType, callingPid, callingUid, userId); 12919 Binder.restoreCallingIdentity(origId); 12920 return res; 12921 } 12922 } 12923 12924 ComponentName startServiceInPackage(int uid, 12925 Intent service, String resolvedType, int userId) { 12926 synchronized(this) { 12927 if (DEBUG_SERVICE) 12928 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12929 final long origId = Binder.clearCallingIdentity(); 12930 ComponentName res = mServices.startServiceLocked(null, service, 12931 resolvedType, -1, uid, userId); 12932 Binder.restoreCallingIdentity(origId); 12933 return res; 12934 } 12935 } 12936 12937 public int stopService(IApplicationThread caller, Intent service, 12938 String resolvedType, int userId) { 12939 enforceNotIsolatedCaller("stopService"); 12940 // Refuse possible leaked file descriptors 12941 if (service != null && service.hasFileDescriptors() == true) { 12942 throw new IllegalArgumentException("File descriptors passed in Intent"); 12943 } 12944 12945 synchronized(this) { 12946 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12947 } 12948 } 12949 12950 public IBinder peekService(Intent service, String resolvedType) { 12951 enforceNotIsolatedCaller("peekService"); 12952 // Refuse possible leaked file descriptors 12953 if (service != null && service.hasFileDescriptors() == true) { 12954 throw new IllegalArgumentException("File descriptors passed in Intent"); 12955 } 12956 synchronized(this) { 12957 return mServices.peekServiceLocked(service, resolvedType); 12958 } 12959 } 12960 12961 public boolean stopServiceToken(ComponentName className, IBinder token, 12962 int startId) { 12963 synchronized(this) { 12964 return mServices.stopServiceTokenLocked(className, token, startId); 12965 } 12966 } 12967 12968 public void setServiceForeground(ComponentName className, IBinder token, 12969 int id, Notification notification, boolean removeNotification) { 12970 synchronized(this) { 12971 mServices.setServiceForegroundLocked(className, token, id, notification, 12972 removeNotification); 12973 } 12974 } 12975 12976 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12977 boolean requireFull, String name, String callerPackage) { 12978 final int callingUserId = UserHandle.getUserId(callingUid); 12979 if (callingUserId != userId) { 12980 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12981 if ((requireFull || checkComponentPermission( 12982 android.Manifest.permission.INTERACT_ACROSS_USERS, 12983 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12984 && checkComponentPermission( 12985 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12986 callingPid, callingUid, -1, true) 12987 != PackageManager.PERMISSION_GRANTED) { 12988 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12989 // In this case, they would like to just execute as their 12990 // owner user instead of failing. 12991 userId = callingUserId; 12992 } else { 12993 StringBuilder builder = new StringBuilder(128); 12994 builder.append("Permission Denial: "); 12995 builder.append(name); 12996 if (callerPackage != null) { 12997 builder.append(" from "); 12998 builder.append(callerPackage); 12999 } 13000 builder.append(" asks to run as user "); 13001 builder.append(userId); 13002 builder.append(" but is calling from user "); 13003 builder.append(UserHandle.getUserId(callingUid)); 13004 builder.append("; this requires "); 13005 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 13006 if (!requireFull) { 13007 builder.append(" or "); 13008 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13009 } 13010 String msg = builder.toString(); 13011 Slog.w(TAG, msg); 13012 throw new SecurityException(msg); 13013 } 13014 } 13015 } 13016 if (userId == UserHandle.USER_CURRENT 13017 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13018 // Note that we may be accessing this outside of a lock... 13019 // shouldn't be a big deal, if this is being called outside 13020 // of a locked context there is intrinsically a race with 13021 // the value the caller will receive and someone else changing it. 13022 userId = mCurrentUserId; 13023 } 13024 if (!allowAll && userId < 0) { 13025 throw new IllegalArgumentException( 13026 "Call does not support special user #" + userId); 13027 } 13028 } 13029 return userId; 13030 } 13031 13032 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13033 String className, int flags) { 13034 boolean result = false; 13035 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13036 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 13037 if (ActivityManager.checkUidPermission( 13038 android.Manifest.permission.INTERACT_ACROSS_USERS, 13039 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13040 ComponentName comp = new ComponentName(aInfo.packageName, className); 13041 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13042 + " requests FLAG_SINGLE_USER, but app does not hold " 13043 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13044 Slog.w(TAG, msg); 13045 throw new SecurityException(msg); 13046 } 13047 result = true; 13048 } 13049 } else if (componentProcessName == aInfo.packageName) { 13050 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13051 } else if ("system".equals(componentProcessName)) { 13052 result = true; 13053 } 13054 if (DEBUG_MU) { 13055 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13056 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13057 } 13058 return result; 13059 } 13060 13061 public int bindService(IApplicationThread caller, IBinder token, 13062 Intent service, String resolvedType, 13063 IServiceConnection connection, int flags, int userId) { 13064 enforceNotIsolatedCaller("bindService"); 13065 // Refuse possible leaked file descriptors 13066 if (service != null && service.hasFileDescriptors() == true) { 13067 throw new IllegalArgumentException("File descriptors passed in Intent"); 13068 } 13069 13070 synchronized(this) { 13071 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13072 connection, flags, userId); 13073 } 13074 } 13075 13076 public boolean unbindService(IServiceConnection connection) { 13077 synchronized (this) { 13078 return mServices.unbindServiceLocked(connection); 13079 } 13080 } 13081 13082 public void publishService(IBinder token, Intent intent, IBinder service) { 13083 // Refuse possible leaked file descriptors 13084 if (intent != null && intent.hasFileDescriptors() == true) { 13085 throw new IllegalArgumentException("File descriptors passed in Intent"); 13086 } 13087 13088 synchronized(this) { 13089 if (!(token instanceof ServiceRecord)) { 13090 throw new IllegalArgumentException("Invalid service token"); 13091 } 13092 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13093 } 13094 } 13095 13096 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13097 // Refuse possible leaked file descriptors 13098 if (intent != null && intent.hasFileDescriptors() == true) { 13099 throw new IllegalArgumentException("File descriptors passed in Intent"); 13100 } 13101 13102 synchronized(this) { 13103 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13104 } 13105 } 13106 13107 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13108 synchronized(this) { 13109 if (!(token instanceof ServiceRecord)) { 13110 throw new IllegalArgumentException("Invalid service token"); 13111 } 13112 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13113 } 13114 } 13115 13116 // ========================================================= 13117 // BACKUP AND RESTORE 13118 // ========================================================= 13119 13120 // Cause the target app to be launched if necessary and its backup agent 13121 // instantiated. The backup agent will invoke backupAgentCreated() on the 13122 // activity manager to announce its creation. 13123 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13124 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13125 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13126 13127 synchronized(this) { 13128 // !!! TODO: currently no check here that we're already bound 13129 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13130 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13131 synchronized (stats) { 13132 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13133 } 13134 13135 // Backup agent is now in use, its package can't be stopped. 13136 try { 13137 AppGlobals.getPackageManager().setPackageStoppedState( 13138 app.packageName, false, UserHandle.getUserId(app.uid)); 13139 } catch (RemoteException e) { 13140 } catch (IllegalArgumentException e) { 13141 Slog.w(TAG, "Failed trying to unstop package " 13142 + app.packageName + ": " + e); 13143 } 13144 13145 BackupRecord r = new BackupRecord(ss, app, backupMode); 13146 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13147 ? new ComponentName(app.packageName, app.backupAgentName) 13148 : new ComponentName("android", "FullBackupAgent"); 13149 // startProcessLocked() returns existing proc's record if it's already running 13150 ProcessRecord proc = startProcessLocked(app.processName, app, 13151 false, 0, "backup", hostingName, false, false, false); 13152 if (proc == null) { 13153 Slog.e(TAG, "Unable to start backup agent process " + r); 13154 return false; 13155 } 13156 13157 r.app = proc; 13158 mBackupTarget = r; 13159 mBackupAppName = app.packageName; 13160 13161 // Try not to kill the process during backup 13162 updateOomAdjLocked(proc); 13163 13164 // If the process is already attached, schedule the creation of the backup agent now. 13165 // If it is not yet live, this will be done when it attaches to the framework. 13166 if (proc.thread != null) { 13167 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13168 try { 13169 proc.thread.scheduleCreateBackupAgent(app, 13170 compatibilityInfoForPackageLocked(app), backupMode); 13171 } catch (RemoteException e) { 13172 // Will time out on the backup manager side 13173 } 13174 } else { 13175 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13176 } 13177 // Invariants: at this point, the target app process exists and the application 13178 // is either already running or in the process of coming up. mBackupTarget and 13179 // mBackupAppName describe the app, so that when it binds back to the AM we 13180 // know that it's scheduled for a backup-agent operation. 13181 } 13182 13183 return true; 13184 } 13185 13186 @Override 13187 public void clearPendingBackup() { 13188 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13189 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13190 13191 synchronized (this) { 13192 mBackupTarget = null; 13193 mBackupAppName = null; 13194 } 13195 } 13196 13197 // A backup agent has just come up 13198 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13199 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13200 + " = " + agent); 13201 13202 synchronized(this) { 13203 if (!agentPackageName.equals(mBackupAppName)) { 13204 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13205 return; 13206 } 13207 } 13208 13209 long oldIdent = Binder.clearCallingIdentity(); 13210 try { 13211 IBackupManager bm = IBackupManager.Stub.asInterface( 13212 ServiceManager.getService(Context.BACKUP_SERVICE)); 13213 bm.agentConnected(agentPackageName, agent); 13214 } catch (RemoteException e) { 13215 // can't happen; the backup manager service is local 13216 } catch (Exception e) { 13217 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13218 e.printStackTrace(); 13219 } finally { 13220 Binder.restoreCallingIdentity(oldIdent); 13221 } 13222 } 13223 13224 // done with this agent 13225 public void unbindBackupAgent(ApplicationInfo appInfo) { 13226 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13227 if (appInfo == null) { 13228 Slog.w(TAG, "unbind backup agent for null app"); 13229 return; 13230 } 13231 13232 synchronized(this) { 13233 try { 13234 if (mBackupAppName == null) { 13235 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13236 return; 13237 } 13238 13239 if (!mBackupAppName.equals(appInfo.packageName)) { 13240 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13241 return; 13242 } 13243 13244 // Not backing this app up any more; reset its OOM adjustment 13245 final ProcessRecord proc = mBackupTarget.app; 13246 updateOomAdjLocked(proc); 13247 13248 // If the app crashed during backup, 'thread' will be null here 13249 if (proc.thread != null) { 13250 try { 13251 proc.thread.scheduleDestroyBackupAgent(appInfo, 13252 compatibilityInfoForPackageLocked(appInfo)); 13253 } catch (Exception e) { 13254 Slog.e(TAG, "Exception when unbinding backup agent:"); 13255 e.printStackTrace(); 13256 } 13257 } 13258 } finally { 13259 mBackupTarget = null; 13260 mBackupAppName = null; 13261 } 13262 } 13263 } 13264 // ========================================================= 13265 // BROADCASTS 13266 // ========================================================= 13267 13268 private final List getStickiesLocked(String action, IntentFilter filter, 13269 List cur, int userId) { 13270 final ContentResolver resolver = mContext.getContentResolver(); 13271 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13272 if (stickies == null) { 13273 return cur; 13274 } 13275 final ArrayList<Intent> list = stickies.get(action); 13276 if (list == null) { 13277 return cur; 13278 } 13279 int N = list.size(); 13280 for (int i=0; i<N; i++) { 13281 Intent intent = list.get(i); 13282 if (filter.match(resolver, intent, true, TAG) >= 0) { 13283 if (cur == null) { 13284 cur = new ArrayList<Intent>(); 13285 } 13286 cur.add(intent); 13287 } 13288 } 13289 return cur; 13290 } 13291 13292 boolean isPendingBroadcastProcessLocked(int pid) { 13293 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13294 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13295 } 13296 13297 void skipPendingBroadcastLocked(int pid) { 13298 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13299 for (BroadcastQueue queue : mBroadcastQueues) { 13300 queue.skipPendingBroadcastLocked(pid); 13301 } 13302 } 13303 13304 // The app just attached; send any pending broadcasts that it should receive 13305 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13306 boolean didSomething = false; 13307 for (BroadcastQueue queue : mBroadcastQueues) { 13308 didSomething |= queue.sendPendingBroadcastsLocked(app); 13309 } 13310 return didSomething; 13311 } 13312 13313 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13314 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13315 enforceNotIsolatedCaller("registerReceiver"); 13316 int callingUid; 13317 int callingPid; 13318 synchronized(this) { 13319 ProcessRecord callerApp = null; 13320 if (caller != null) { 13321 callerApp = getRecordForAppLocked(caller); 13322 if (callerApp == null) { 13323 throw new SecurityException( 13324 "Unable to find app for caller " + caller 13325 + " (pid=" + Binder.getCallingPid() 13326 + ") when registering receiver " + receiver); 13327 } 13328 if (callerApp.info.uid != Process.SYSTEM_UID && 13329 !callerApp.pkgList.containsKey(callerPackage) && 13330 !"android".equals(callerPackage)) { 13331 throw new SecurityException("Given caller package " + callerPackage 13332 + " is not running in process " + callerApp); 13333 } 13334 callingUid = callerApp.info.uid; 13335 callingPid = callerApp.pid; 13336 } else { 13337 callerPackage = null; 13338 callingUid = Binder.getCallingUid(); 13339 callingPid = Binder.getCallingPid(); 13340 } 13341 13342 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13343 true, true, "registerReceiver", callerPackage); 13344 13345 List allSticky = null; 13346 13347 // Look for any matching sticky broadcasts... 13348 Iterator actions = filter.actionsIterator(); 13349 if (actions != null) { 13350 while (actions.hasNext()) { 13351 String action = (String)actions.next(); 13352 allSticky = getStickiesLocked(action, filter, allSticky, 13353 UserHandle.USER_ALL); 13354 allSticky = getStickiesLocked(action, filter, allSticky, 13355 UserHandle.getUserId(callingUid)); 13356 } 13357 } else { 13358 allSticky = getStickiesLocked(null, filter, allSticky, 13359 UserHandle.USER_ALL); 13360 allSticky = getStickiesLocked(null, filter, allSticky, 13361 UserHandle.getUserId(callingUid)); 13362 } 13363 13364 // The first sticky in the list is returned directly back to 13365 // the client. 13366 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13367 13368 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13369 + ": " + sticky); 13370 13371 if (receiver == null) { 13372 return sticky; 13373 } 13374 13375 ReceiverList rl 13376 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13377 if (rl == null) { 13378 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13379 userId, receiver); 13380 if (rl.app != null) { 13381 rl.app.receivers.add(rl); 13382 } else { 13383 try { 13384 receiver.asBinder().linkToDeath(rl, 0); 13385 } catch (RemoteException e) { 13386 return sticky; 13387 } 13388 rl.linkedToDeath = true; 13389 } 13390 mRegisteredReceivers.put(receiver.asBinder(), rl); 13391 } else if (rl.uid != callingUid) { 13392 throw new IllegalArgumentException( 13393 "Receiver requested to register for uid " + callingUid 13394 + " was previously registered for uid " + rl.uid); 13395 } else if (rl.pid != callingPid) { 13396 throw new IllegalArgumentException( 13397 "Receiver requested to register for pid " + callingPid 13398 + " was previously registered for pid " + rl.pid); 13399 } else if (rl.userId != userId) { 13400 throw new IllegalArgumentException( 13401 "Receiver requested to register for user " + userId 13402 + " was previously registered for user " + rl.userId); 13403 } 13404 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13405 permission, callingUid, userId); 13406 rl.add(bf); 13407 if (!bf.debugCheck()) { 13408 Slog.w(TAG, "==> For Dynamic broadast"); 13409 } 13410 mReceiverResolver.addFilter(bf); 13411 13412 // Enqueue broadcasts for all existing stickies that match 13413 // this filter. 13414 if (allSticky != null) { 13415 ArrayList receivers = new ArrayList(); 13416 receivers.add(bf); 13417 13418 int N = allSticky.size(); 13419 for (int i=0; i<N; i++) { 13420 Intent intent = (Intent)allSticky.get(i); 13421 BroadcastQueue queue = broadcastQueueForIntent(intent); 13422 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13423 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13424 null, null, false, true, true, -1); 13425 queue.enqueueParallelBroadcastLocked(r); 13426 queue.scheduleBroadcastsLocked(); 13427 } 13428 } 13429 13430 return sticky; 13431 } 13432 } 13433 13434 public void unregisterReceiver(IIntentReceiver receiver) { 13435 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13436 13437 final long origId = Binder.clearCallingIdentity(); 13438 try { 13439 boolean doTrim = false; 13440 13441 synchronized(this) { 13442 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13443 if (rl != null) { 13444 if (rl.curBroadcast != null) { 13445 BroadcastRecord r = rl.curBroadcast; 13446 final boolean doNext = finishReceiverLocked( 13447 receiver.asBinder(), r.resultCode, r.resultData, 13448 r.resultExtras, r.resultAbort); 13449 if (doNext) { 13450 doTrim = true; 13451 r.queue.processNextBroadcast(false); 13452 } 13453 } 13454 13455 if (rl.app != null) { 13456 rl.app.receivers.remove(rl); 13457 } 13458 removeReceiverLocked(rl); 13459 if (rl.linkedToDeath) { 13460 rl.linkedToDeath = false; 13461 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13462 } 13463 } 13464 } 13465 13466 // If we actually concluded any broadcasts, we might now be able 13467 // to trim the recipients' apps from our working set 13468 if (doTrim) { 13469 trimApplications(); 13470 return; 13471 } 13472 13473 } finally { 13474 Binder.restoreCallingIdentity(origId); 13475 } 13476 } 13477 13478 void removeReceiverLocked(ReceiverList rl) { 13479 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13480 int N = rl.size(); 13481 for (int i=0; i<N; i++) { 13482 mReceiverResolver.removeFilter(rl.get(i)); 13483 } 13484 } 13485 13486 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13487 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13488 ProcessRecord r = mLruProcesses.get(i); 13489 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13490 try { 13491 r.thread.dispatchPackageBroadcast(cmd, packages); 13492 } catch (RemoteException ex) { 13493 } 13494 } 13495 } 13496 } 13497 13498 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13499 int[] users) { 13500 List<ResolveInfo> receivers = null; 13501 try { 13502 HashSet<ComponentName> singleUserReceivers = null; 13503 boolean scannedFirstReceivers = false; 13504 for (int user : users) { 13505 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13506 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13507 if (user != 0 && newReceivers != null) { 13508 // If this is not the primary user, we need to check for 13509 // any receivers that should be filtered out. 13510 for (int i=0; i<newReceivers.size(); i++) { 13511 ResolveInfo ri = newReceivers.get(i); 13512 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13513 newReceivers.remove(i); 13514 i--; 13515 } 13516 } 13517 } 13518 if (newReceivers != null && newReceivers.size() == 0) { 13519 newReceivers = null; 13520 } 13521 if (receivers == null) { 13522 receivers = newReceivers; 13523 } else if (newReceivers != null) { 13524 // We need to concatenate the additional receivers 13525 // found with what we have do far. This would be easy, 13526 // but we also need to de-dup any receivers that are 13527 // singleUser. 13528 if (!scannedFirstReceivers) { 13529 // Collect any single user receivers we had already retrieved. 13530 scannedFirstReceivers = true; 13531 for (int i=0; i<receivers.size(); i++) { 13532 ResolveInfo ri = receivers.get(i); 13533 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13534 ComponentName cn = new ComponentName( 13535 ri.activityInfo.packageName, ri.activityInfo.name); 13536 if (singleUserReceivers == null) { 13537 singleUserReceivers = new HashSet<ComponentName>(); 13538 } 13539 singleUserReceivers.add(cn); 13540 } 13541 } 13542 } 13543 // Add the new results to the existing results, tracking 13544 // and de-dupping single user receivers. 13545 for (int i=0; i<newReceivers.size(); i++) { 13546 ResolveInfo ri = newReceivers.get(i); 13547 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13548 ComponentName cn = new ComponentName( 13549 ri.activityInfo.packageName, ri.activityInfo.name); 13550 if (singleUserReceivers == null) { 13551 singleUserReceivers = new HashSet<ComponentName>(); 13552 } 13553 if (!singleUserReceivers.contains(cn)) { 13554 singleUserReceivers.add(cn); 13555 receivers.add(ri); 13556 } 13557 } else { 13558 receivers.add(ri); 13559 } 13560 } 13561 } 13562 } 13563 } catch (RemoteException ex) { 13564 // pm is in same process, this will never happen. 13565 } 13566 return receivers; 13567 } 13568 13569 private final int broadcastIntentLocked(ProcessRecord callerApp, 13570 String callerPackage, Intent intent, String resolvedType, 13571 IIntentReceiver resultTo, int resultCode, String resultData, 13572 Bundle map, String requiredPermission, int appOp, 13573 boolean ordered, boolean sticky, int callingPid, int callingUid, 13574 int userId) { 13575 intent = new Intent(intent); 13576 13577 // By default broadcasts do not go to stopped apps. 13578 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13579 13580 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13581 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13582 + " ordered=" + ordered + " userid=" + userId); 13583 if ((resultTo != null) && !ordered) { 13584 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13585 } 13586 13587 userId = handleIncomingUser(callingPid, callingUid, userId, 13588 true, false, "broadcast", callerPackage); 13589 13590 // Make sure that the user who is receiving this broadcast is started. 13591 // If not, we will just skip it. 13592 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13593 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13594 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13595 Slog.w(TAG, "Skipping broadcast of " + intent 13596 + ": user " + userId + " is stopped"); 13597 return ActivityManager.BROADCAST_SUCCESS; 13598 } 13599 } 13600 13601 /* 13602 * Prevent non-system code (defined here to be non-persistent 13603 * processes) from sending protected broadcasts. 13604 */ 13605 int callingAppId = UserHandle.getAppId(callingUid); 13606 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13607 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13608 callingUid == 0) { 13609 // Always okay. 13610 } else if (callerApp == null || !callerApp.persistent) { 13611 try { 13612 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13613 intent.getAction())) { 13614 String msg = "Permission Denial: not allowed to send broadcast " 13615 + intent.getAction() + " from pid=" 13616 + callingPid + ", uid=" + callingUid; 13617 Slog.w(TAG, msg); 13618 throw new SecurityException(msg); 13619 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13620 // Special case for compatibility: we don't want apps to send this, 13621 // but historically it has not been protected and apps may be using it 13622 // to poke their own app widget. So, instead of making it protected, 13623 // just limit it to the caller. 13624 if (callerApp == null) { 13625 String msg = "Permission Denial: not allowed to send broadcast " 13626 + intent.getAction() + " from unknown caller."; 13627 Slog.w(TAG, msg); 13628 throw new SecurityException(msg); 13629 } else if (intent.getComponent() != null) { 13630 // They are good enough to send to an explicit component... verify 13631 // it is being sent to the calling app. 13632 if (!intent.getComponent().getPackageName().equals( 13633 callerApp.info.packageName)) { 13634 String msg = "Permission Denial: not allowed to send broadcast " 13635 + intent.getAction() + " to " 13636 + intent.getComponent().getPackageName() + " from " 13637 + callerApp.info.packageName; 13638 Slog.w(TAG, msg); 13639 throw new SecurityException(msg); 13640 } 13641 } else { 13642 // Limit broadcast to their own package. 13643 intent.setPackage(callerApp.info.packageName); 13644 } 13645 } 13646 } catch (RemoteException e) { 13647 Slog.w(TAG, "Remote exception", e); 13648 return ActivityManager.BROADCAST_SUCCESS; 13649 } 13650 } 13651 13652 // Handle special intents: if this broadcast is from the package 13653 // manager about a package being removed, we need to remove all of 13654 // its activities from the history stack. 13655 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13656 intent.getAction()); 13657 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13658 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13659 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13660 || uidRemoved) { 13661 if (checkComponentPermission( 13662 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13663 callingPid, callingUid, -1, true) 13664 == PackageManager.PERMISSION_GRANTED) { 13665 if (uidRemoved) { 13666 final Bundle intentExtras = intent.getExtras(); 13667 final int uid = intentExtras != null 13668 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13669 if (uid >= 0) { 13670 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13671 synchronized (bs) { 13672 bs.removeUidStatsLocked(uid); 13673 } 13674 mAppOpsService.uidRemoved(uid); 13675 } 13676 } else { 13677 // If resources are unavailable just force stop all 13678 // those packages and flush the attribute cache as well. 13679 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13680 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13681 if (list != null && (list.length > 0)) { 13682 for (String pkg : list) { 13683 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13684 "storage unmount"); 13685 } 13686 sendPackageBroadcastLocked( 13687 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13688 } 13689 } else { 13690 Uri data = intent.getData(); 13691 String ssp; 13692 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13693 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13694 intent.getAction()); 13695 boolean fullUninstall = removed && 13696 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13697 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13698 forceStopPackageLocked(ssp, UserHandle.getAppId( 13699 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13700 false, fullUninstall, userId, 13701 removed ? "pkg removed" : "pkg changed"); 13702 } 13703 if (removed) { 13704 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13705 new String[] {ssp}, userId); 13706 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13707 mAppOpsService.packageRemoved( 13708 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13709 13710 // Remove all permissions granted from/to this package 13711 removeUriPermissionsForPackageLocked(ssp, userId, true); 13712 } 13713 } 13714 } 13715 } 13716 } 13717 } else { 13718 String msg = "Permission Denial: " + intent.getAction() 13719 + " broadcast from " + callerPackage + " (pid=" + callingPid 13720 + ", uid=" + callingUid + ")" 13721 + " requires " 13722 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13723 Slog.w(TAG, msg); 13724 throw new SecurityException(msg); 13725 } 13726 13727 // Special case for adding a package: by default turn on compatibility 13728 // mode. 13729 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13730 Uri data = intent.getData(); 13731 String ssp; 13732 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13733 mCompatModePackages.handlePackageAddedLocked(ssp, 13734 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13735 } 13736 } 13737 13738 /* 13739 * If this is the time zone changed action, queue up a message that will reset the timezone 13740 * of all currently running processes. This message will get queued up before the broadcast 13741 * happens. 13742 */ 13743 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13744 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13745 } 13746 13747 /* 13748 * If the user set the time, let all running processes know. 13749 */ 13750 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13751 final int is24Hour = intent.getBooleanExtra( 13752 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13753 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13754 } 13755 13756 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13757 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13758 } 13759 13760 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13761 ProxyInfo proxy = intent.getParcelableExtra("proxy"); 13762 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13763 } 13764 13765 // Add to the sticky list if requested. 13766 if (sticky) { 13767 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13768 callingPid, callingUid) 13769 != PackageManager.PERMISSION_GRANTED) { 13770 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13771 + callingPid + ", uid=" + callingUid 13772 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13773 Slog.w(TAG, msg); 13774 throw new SecurityException(msg); 13775 } 13776 if (requiredPermission != null) { 13777 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13778 + " and enforce permission " + requiredPermission); 13779 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13780 } 13781 if (intent.getComponent() != null) { 13782 throw new SecurityException( 13783 "Sticky broadcasts can't target a specific component"); 13784 } 13785 // We use userId directly here, since the "all" target is maintained 13786 // as a separate set of sticky broadcasts. 13787 if (userId != UserHandle.USER_ALL) { 13788 // But first, if this is not a broadcast to all users, then 13789 // make sure it doesn't conflict with an existing broadcast to 13790 // all users. 13791 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13792 UserHandle.USER_ALL); 13793 if (stickies != null) { 13794 ArrayList<Intent> list = stickies.get(intent.getAction()); 13795 if (list != null) { 13796 int N = list.size(); 13797 int i; 13798 for (i=0; i<N; i++) { 13799 if (intent.filterEquals(list.get(i))) { 13800 throw new IllegalArgumentException( 13801 "Sticky broadcast " + intent + " for user " 13802 + userId + " conflicts with existing global broadcast"); 13803 } 13804 } 13805 } 13806 } 13807 } 13808 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13809 if (stickies == null) { 13810 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13811 mStickyBroadcasts.put(userId, stickies); 13812 } 13813 ArrayList<Intent> list = stickies.get(intent.getAction()); 13814 if (list == null) { 13815 list = new ArrayList<Intent>(); 13816 stickies.put(intent.getAction(), list); 13817 } 13818 int N = list.size(); 13819 int i; 13820 for (i=0; i<N; i++) { 13821 if (intent.filterEquals(list.get(i))) { 13822 // This sticky already exists, replace it. 13823 list.set(i, new Intent(intent)); 13824 break; 13825 } 13826 } 13827 if (i >= N) { 13828 list.add(new Intent(intent)); 13829 } 13830 } 13831 13832 int[] users; 13833 if (userId == UserHandle.USER_ALL) { 13834 // Caller wants broadcast to go to all started users. 13835 users = mStartedUserArray; 13836 } else { 13837 // Caller wants broadcast to go to one specific user. 13838 users = new int[] {userId}; 13839 } 13840 13841 // Figure out who all will receive this broadcast. 13842 List receivers = null; 13843 List<BroadcastFilter> registeredReceivers = null; 13844 // Need to resolve the intent to interested receivers... 13845 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13846 == 0) { 13847 receivers = collectReceiverComponents(intent, resolvedType, users); 13848 } 13849 if (intent.getComponent() == null) { 13850 registeredReceivers = mReceiverResolver.queryIntent(intent, 13851 resolvedType, false, userId); 13852 } 13853 13854 final boolean replacePending = 13855 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13856 13857 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13858 + " replacePending=" + replacePending); 13859 13860 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13861 if (!ordered && NR > 0) { 13862 // If we are not serializing this broadcast, then send the 13863 // registered receivers separately so they don't wait for the 13864 // components to be launched. 13865 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13866 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13867 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13868 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13869 ordered, sticky, false, userId); 13870 if (DEBUG_BROADCAST) Slog.v( 13871 TAG, "Enqueueing parallel broadcast " + r); 13872 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13873 if (!replaced) { 13874 queue.enqueueParallelBroadcastLocked(r); 13875 queue.scheduleBroadcastsLocked(); 13876 } 13877 registeredReceivers = null; 13878 NR = 0; 13879 } 13880 13881 // Merge into one list. 13882 int ir = 0; 13883 if (receivers != null) { 13884 // A special case for PACKAGE_ADDED: do not allow the package 13885 // being added to see this broadcast. This prevents them from 13886 // using this as a back door to get run as soon as they are 13887 // installed. Maybe in the future we want to have a special install 13888 // broadcast or such for apps, but we'd like to deliberately make 13889 // this decision. 13890 String skipPackages[] = null; 13891 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13892 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13893 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13894 Uri data = intent.getData(); 13895 if (data != null) { 13896 String pkgName = data.getSchemeSpecificPart(); 13897 if (pkgName != null) { 13898 skipPackages = new String[] { pkgName }; 13899 } 13900 } 13901 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13902 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13903 } 13904 if (skipPackages != null && (skipPackages.length > 0)) { 13905 for (String skipPackage : skipPackages) { 13906 if (skipPackage != null) { 13907 int NT = receivers.size(); 13908 for (int it=0; it<NT; it++) { 13909 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13910 if (curt.activityInfo.packageName.equals(skipPackage)) { 13911 receivers.remove(it); 13912 it--; 13913 NT--; 13914 } 13915 } 13916 } 13917 } 13918 } 13919 13920 int NT = receivers != null ? receivers.size() : 0; 13921 int it = 0; 13922 ResolveInfo curt = null; 13923 BroadcastFilter curr = null; 13924 while (it < NT && ir < NR) { 13925 if (curt == null) { 13926 curt = (ResolveInfo)receivers.get(it); 13927 } 13928 if (curr == null) { 13929 curr = registeredReceivers.get(ir); 13930 } 13931 if (curr.getPriority() >= curt.priority) { 13932 // Insert this broadcast record into the final list. 13933 receivers.add(it, curr); 13934 ir++; 13935 curr = null; 13936 it++; 13937 NT++; 13938 } else { 13939 // Skip to the next ResolveInfo in the final list. 13940 it++; 13941 curt = null; 13942 } 13943 } 13944 } 13945 while (ir < NR) { 13946 if (receivers == null) { 13947 receivers = new ArrayList(); 13948 } 13949 receivers.add(registeredReceivers.get(ir)); 13950 ir++; 13951 } 13952 13953 if ((receivers != null && receivers.size() > 0) 13954 || resultTo != null) { 13955 BroadcastQueue queue = broadcastQueueForIntent(intent); 13956 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13957 callerPackage, callingPid, callingUid, resolvedType, 13958 requiredPermission, appOp, receivers, resultTo, resultCode, 13959 resultData, map, ordered, sticky, false, userId); 13960 if (DEBUG_BROADCAST) Slog.v( 13961 TAG, "Enqueueing ordered broadcast " + r 13962 + ": prev had " + queue.mOrderedBroadcasts.size()); 13963 if (DEBUG_BROADCAST) { 13964 int seq = r.intent.getIntExtra("seq", -1); 13965 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13966 } 13967 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13968 if (!replaced) { 13969 queue.enqueueOrderedBroadcastLocked(r); 13970 queue.scheduleBroadcastsLocked(); 13971 } 13972 } 13973 13974 return ActivityManager.BROADCAST_SUCCESS; 13975 } 13976 13977 final Intent verifyBroadcastLocked(Intent intent) { 13978 // Refuse possible leaked file descriptors 13979 if (intent != null && intent.hasFileDescriptors() == true) { 13980 throw new IllegalArgumentException("File descriptors passed in Intent"); 13981 } 13982 13983 int flags = intent.getFlags(); 13984 13985 if (!mProcessesReady) { 13986 // if the caller really truly claims to know what they're doing, go 13987 // ahead and allow the broadcast without launching any receivers 13988 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13989 intent = new Intent(intent); 13990 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13991 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13992 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13993 + " before boot completion"); 13994 throw new IllegalStateException("Cannot broadcast before boot completed"); 13995 } 13996 } 13997 13998 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13999 throw new IllegalArgumentException( 14000 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14001 } 14002 14003 return intent; 14004 } 14005 14006 public final int broadcastIntent(IApplicationThread caller, 14007 Intent intent, String resolvedType, IIntentReceiver resultTo, 14008 int resultCode, String resultData, Bundle map, 14009 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14010 enforceNotIsolatedCaller("broadcastIntent"); 14011 synchronized(this) { 14012 intent = verifyBroadcastLocked(intent); 14013 14014 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14015 final int callingPid = Binder.getCallingPid(); 14016 final int callingUid = Binder.getCallingUid(); 14017 final long origId = Binder.clearCallingIdentity(); 14018 int res = broadcastIntentLocked(callerApp, 14019 callerApp != null ? callerApp.info.packageName : null, 14020 intent, resolvedType, resultTo, 14021 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14022 callingPid, callingUid, userId); 14023 Binder.restoreCallingIdentity(origId); 14024 return res; 14025 } 14026 } 14027 14028 int broadcastIntentInPackage(String packageName, int uid, 14029 Intent intent, String resolvedType, IIntentReceiver resultTo, 14030 int resultCode, String resultData, Bundle map, 14031 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14032 synchronized(this) { 14033 intent = verifyBroadcastLocked(intent); 14034 14035 final long origId = Binder.clearCallingIdentity(); 14036 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14037 resultTo, resultCode, resultData, map, requiredPermission, 14038 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14039 Binder.restoreCallingIdentity(origId); 14040 return res; 14041 } 14042 } 14043 14044 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14045 // Refuse possible leaked file descriptors 14046 if (intent != null && intent.hasFileDescriptors() == true) { 14047 throw new IllegalArgumentException("File descriptors passed in Intent"); 14048 } 14049 14050 userId = handleIncomingUser(Binder.getCallingPid(), 14051 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14052 14053 synchronized(this) { 14054 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14055 != PackageManager.PERMISSION_GRANTED) { 14056 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14057 + Binder.getCallingPid() 14058 + ", uid=" + Binder.getCallingUid() 14059 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14060 Slog.w(TAG, msg); 14061 throw new SecurityException(msg); 14062 } 14063 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14064 if (stickies != null) { 14065 ArrayList<Intent> list = stickies.get(intent.getAction()); 14066 if (list != null) { 14067 int N = list.size(); 14068 int i; 14069 for (i=0; i<N; i++) { 14070 if (intent.filterEquals(list.get(i))) { 14071 list.remove(i); 14072 break; 14073 } 14074 } 14075 if (list.size() <= 0) { 14076 stickies.remove(intent.getAction()); 14077 } 14078 } 14079 if (stickies.size() <= 0) { 14080 mStickyBroadcasts.remove(userId); 14081 } 14082 } 14083 } 14084 } 14085 14086 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14087 String resultData, Bundle resultExtras, boolean resultAbort) { 14088 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14089 if (r == null) { 14090 Slog.w(TAG, "finishReceiver called but not found on queue"); 14091 return false; 14092 } 14093 14094 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14095 } 14096 14097 void backgroundServicesFinishedLocked(int userId) { 14098 for (BroadcastQueue queue : mBroadcastQueues) { 14099 queue.backgroundServicesFinishedLocked(userId); 14100 } 14101 } 14102 14103 public void finishReceiver(IBinder who, int resultCode, String resultData, 14104 Bundle resultExtras, boolean resultAbort) { 14105 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14106 14107 // Refuse possible leaked file descriptors 14108 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14109 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14110 } 14111 14112 final long origId = Binder.clearCallingIdentity(); 14113 try { 14114 boolean doNext = false; 14115 BroadcastRecord r; 14116 14117 synchronized(this) { 14118 r = broadcastRecordForReceiverLocked(who); 14119 if (r != null) { 14120 doNext = r.queue.finishReceiverLocked(r, resultCode, 14121 resultData, resultExtras, resultAbort, true); 14122 } 14123 } 14124 14125 if (doNext) { 14126 r.queue.processNextBroadcast(false); 14127 } 14128 trimApplications(); 14129 } finally { 14130 Binder.restoreCallingIdentity(origId); 14131 } 14132 } 14133 14134 // ========================================================= 14135 // INSTRUMENTATION 14136 // ========================================================= 14137 14138 public boolean startInstrumentation(ComponentName className, 14139 String profileFile, int flags, Bundle arguments, 14140 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14141 int userId) { 14142 enforceNotIsolatedCaller("startInstrumentation"); 14143 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14144 userId, false, true, "startInstrumentation", null); 14145 // Refuse possible leaked file descriptors 14146 if (arguments != null && arguments.hasFileDescriptors()) { 14147 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14148 } 14149 14150 synchronized(this) { 14151 InstrumentationInfo ii = null; 14152 ApplicationInfo ai = null; 14153 try { 14154 ii = mContext.getPackageManager().getInstrumentationInfo( 14155 className, STOCK_PM_FLAGS); 14156 ai = AppGlobals.getPackageManager().getApplicationInfo( 14157 ii.targetPackage, STOCK_PM_FLAGS, userId); 14158 } catch (PackageManager.NameNotFoundException e) { 14159 } catch (RemoteException e) { 14160 } 14161 if (ii == null) { 14162 reportStartInstrumentationFailure(watcher, className, 14163 "Unable to find instrumentation info for: " + className); 14164 return false; 14165 } 14166 if (ai == null) { 14167 reportStartInstrumentationFailure(watcher, className, 14168 "Unable to find instrumentation target package: " + ii.targetPackage); 14169 return false; 14170 } 14171 14172 int match = mContext.getPackageManager().checkSignatures( 14173 ii.targetPackage, ii.packageName); 14174 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14175 String msg = "Permission Denial: starting instrumentation " 14176 + className + " from pid=" 14177 + Binder.getCallingPid() 14178 + ", uid=" + Binder.getCallingPid() 14179 + " not allowed because package " + ii.packageName 14180 + " does not have a signature matching the target " 14181 + ii.targetPackage; 14182 reportStartInstrumentationFailure(watcher, className, msg); 14183 throw new SecurityException(msg); 14184 } 14185 14186 final long origId = Binder.clearCallingIdentity(); 14187 // Instrumentation can kill and relaunch even persistent processes 14188 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14189 "start instr"); 14190 ProcessRecord app = addAppLocked(ai, false); 14191 app.instrumentationClass = className; 14192 app.instrumentationInfo = ai; 14193 app.instrumentationProfileFile = profileFile; 14194 app.instrumentationArguments = arguments; 14195 app.instrumentationWatcher = watcher; 14196 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14197 app.instrumentationResultClass = className; 14198 Binder.restoreCallingIdentity(origId); 14199 } 14200 14201 return true; 14202 } 14203 14204 /** 14205 * Report errors that occur while attempting to start Instrumentation. Always writes the 14206 * error to the logs, but if somebody is watching, send the report there too. This enables 14207 * the "am" command to report errors with more information. 14208 * 14209 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14210 * @param cn The component name of the instrumentation. 14211 * @param report The error report. 14212 */ 14213 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14214 ComponentName cn, String report) { 14215 Slog.w(TAG, report); 14216 try { 14217 if (watcher != null) { 14218 Bundle results = new Bundle(); 14219 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14220 results.putString("Error", report); 14221 watcher.instrumentationStatus(cn, -1, results); 14222 } 14223 } catch (RemoteException e) { 14224 Slog.w(TAG, e); 14225 } 14226 } 14227 14228 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14229 if (app.instrumentationWatcher != null) { 14230 try { 14231 // NOTE: IInstrumentationWatcher *must* be oneway here 14232 app.instrumentationWatcher.instrumentationFinished( 14233 app.instrumentationClass, 14234 resultCode, 14235 results); 14236 } catch (RemoteException e) { 14237 } 14238 } 14239 if (app.instrumentationUiAutomationConnection != null) { 14240 try { 14241 app.instrumentationUiAutomationConnection.shutdown(); 14242 } catch (RemoteException re) { 14243 /* ignore */ 14244 } 14245 // Only a UiAutomation can set this flag and now that 14246 // it is finished we make sure it is reset to its default. 14247 mUserIsMonkey = false; 14248 } 14249 app.instrumentationWatcher = null; 14250 app.instrumentationUiAutomationConnection = null; 14251 app.instrumentationClass = null; 14252 app.instrumentationInfo = null; 14253 app.instrumentationProfileFile = null; 14254 app.instrumentationArguments = null; 14255 14256 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14257 "finished inst"); 14258 } 14259 14260 public void finishInstrumentation(IApplicationThread target, 14261 int resultCode, Bundle results) { 14262 int userId = UserHandle.getCallingUserId(); 14263 // Refuse possible leaked file descriptors 14264 if (results != null && results.hasFileDescriptors()) { 14265 throw new IllegalArgumentException("File descriptors passed in Intent"); 14266 } 14267 14268 synchronized(this) { 14269 ProcessRecord app = getRecordForAppLocked(target); 14270 if (app == null) { 14271 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14272 return; 14273 } 14274 final long origId = Binder.clearCallingIdentity(); 14275 finishInstrumentationLocked(app, resultCode, results); 14276 Binder.restoreCallingIdentity(origId); 14277 } 14278 } 14279 14280 // ========================================================= 14281 // CONFIGURATION 14282 // ========================================================= 14283 14284 public ConfigurationInfo getDeviceConfigurationInfo() { 14285 ConfigurationInfo config = new ConfigurationInfo(); 14286 synchronized (this) { 14287 config.reqTouchScreen = mConfiguration.touchscreen; 14288 config.reqKeyboardType = mConfiguration.keyboard; 14289 config.reqNavigation = mConfiguration.navigation; 14290 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14291 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14292 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14293 } 14294 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14295 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14296 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14297 } 14298 config.reqGlEsVersion = GL_ES_VERSION; 14299 } 14300 return config; 14301 } 14302 14303 ActivityStack getFocusedStack() { 14304 return mStackSupervisor.getFocusedStack(); 14305 } 14306 14307 public Configuration getConfiguration() { 14308 Configuration ci; 14309 synchronized(this) { 14310 ci = new Configuration(mConfiguration); 14311 } 14312 return ci; 14313 } 14314 14315 public void updatePersistentConfiguration(Configuration values) { 14316 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14317 "updateConfiguration()"); 14318 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14319 "updateConfiguration()"); 14320 if (values == null) { 14321 throw new NullPointerException("Configuration must not be null"); 14322 } 14323 14324 synchronized(this) { 14325 final long origId = Binder.clearCallingIdentity(); 14326 updateConfigurationLocked(values, null, true, false); 14327 Binder.restoreCallingIdentity(origId); 14328 } 14329 } 14330 14331 public void updateConfiguration(Configuration values) { 14332 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14333 "updateConfiguration()"); 14334 14335 synchronized(this) { 14336 if (values == null && mWindowManager != null) { 14337 // sentinel: fetch the current configuration from the window manager 14338 values = mWindowManager.computeNewConfiguration(); 14339 } 14340 14341 if (mWindowManager != null) { 14342 mProcessList.applyDisplaySize(mWindowManager); 14343 } 14344 14345 final long origId = Binder.clearCallingIdentity(); 14346 if (values != null) { 14347 Settings.System.clearConfiguration(values); 14348 } 14349 updateConfigurationLocked(values, null, false, false); 14350 Binder.restoreCallingIdentity(origId); 14351 } 14352 } 14353 14354 /** 14355 * Do either or both things: (1) change the current configuration, and (2) 14356 * make sure the given activity is running with the (now) current 14357 * configuration. Returns true if the activity has been left running, or 14358 * false if <var>starting</var> is being destroyed to match the new 14359 * configuration. 14360 * @param persistent TODO 14361 */ 14362 boolean updateConfigurationLocked(Configuration values, 14363 ActivityRecord starting, boolean persistent, boolean initLocale) { 14364 int changes = 0; 14365 14366 if (values != null) { 14367 Configuration newConfig = new Configuration(mConfiguration); 14368 changes = newConfig.updateFrom(values); 14369 if (changes != 0) { 14370 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14371 Slog.i(TAG, "Updating configuration to: " + values); 14372 } 14373 14374 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14375 14376 if (values.locale != null && !initLocale) { 14377 saveLocaleLocked(values.locale, 14378 !values.locale.equals(mConfiguration.locale), 14379 values.userSetLocale); 14380 } 14381 14382 mConfigurationSeq++; 14383 if (mConfigurationSeq <= 0) { 14384 mConfigurationSeq = 1; 14385 } 14386 newConfig.seq = mConfigurationSeq; 14387 mConfiguration = newConfig; 14388 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14389 14390 final Configuration configCopy = new Configuration(mConfiguration); 14391 14392 // TODO: If our config changes, should we auto dismiss any currently 14393 // showing dialogs? 14394 mShowDialogs = shouldShowDialogs(newConfig); 14395 14396 AttributeCache ac = AttributeCache.instance(); 14397 if (ac != null) { 14398 ac.updateConfiguration(configCopy); 14399 } 14400 14401 // Make sure all resources in our process are updated 14402 // right now, so that anyone who is going to retrieve 14403 // resource values after we return will be sure to get 14404 // the new ones. This is especially important during 14405 // boot, where the first config change needs to guarantee 14406 // all resources have that config before following boot 14407 // code is executed. 14408 mSystemThread.applyConfigurationToResources(configCopy); 14409 14410 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14411 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14412 msg.obj = new Configuration(configCopy); 14413 mHandler.sendMessage(msg); 14414 } 14415 14416 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14417 ProcessRecord app = mLruProcesses.get(i); 14418 try { 14419 if (app.thread != null) { 14420 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14421 + app.processName + " new config " + mConfiguration); 14422 app.thread.scheduleConfigurationChanged(configCopy); 14423 } 14424 } catch (Exception e) { 14425 } 14426 } 14427 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14428 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14429 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14430 | Intent.FLAG_RECEIVER_FOREGROUND); 14431 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14432 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14433 Process.SYSTEM_UID, UserHandle.USER_ALL); 14434 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14435 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14436 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14437 broadcastIntentLocked(null, null, intent, 14438 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14439 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14440 } 14441 } 14442 } 14443 14444 boolean kept = true; 14445 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14446 // mainStack is null during startup. 14447 if (mainStack != null) { 14448 if (changes != 0 && starting == null) { 14449 // If the configuration changed, and the caller is not already 14450 // in the process of starting an activity, then find the top 14451 // activity to check if its configuration needs to change. 14452 starting = mainStack.topRunningActivityLocked(null); 14453 } 14454 14455 if (starting != null) { 14456 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14457 // And we need to make sure at this point that all other activities 14458 // are made visible with the correct configuration. 14459 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14460 } 14461 } 14462 14463 if (values != null && mWindowManager != null) { 14464 mWindowManager.setNewConfiguration(mConfiguration); 14465 } 14466 14467 return kept; 14468 } 14469 14470 /** 14471 * Decide based on the configuration whether we should shouw the ANR, 14472 * crash, etc dialogs. The idea is that if there is no affordnace to 14473 * press the on-screen buttons, we shouldn't show the dialog. 14474 * 14475 * A thought: SystemUI might also want to get told about this, the Power 14476 * dialog / global actions also might want different behaviors. 14477 */ 14478 private static final boolean shouldShowDialogs(Configuration config) { 14479 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14480 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14481 } 14482 14483 /** 14484 * Save the locale. You must be inside a synchronized (this) block. 14485 */ 14486 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14487 if(isDiff) { 14488 SystemProperties.set("user.language", l.getLanguage()); 14489 SystemProperties.set("user.region", l.getCountry()); 14490 } 14491 14492 if(isPersist) { 14493 SystemProperties.set("persist.sys.language", l.getLanguage()); 14494 SystemProperties.set("persist.sys.country", l.getCountry()); 14495 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14496 } 14497 } 14498 14499 @Override 14500 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14501 ActivityRecord srec = ActivityRecord.forToken(token); 14502 return srec != null && srec.task.affinity != null && 14503 srec.task.affinity.equals(destAffinity); 14504 } 14505 14506 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14507 Intent resultData) { 14508 14509 synchronized (this) { 14510 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14511 if (stack != null) { 14512 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14513 } 14514 return false; 14515 } 14516 } 14517 14518 public int getLaunchedFromUid(IBinder activityToken) { 14519 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14520 if (srec == null) { 14521 return -1; 14522 } 14523 return srec.launchedFromUid; 14524 } 14525 14526 public String getLaunchedFromPackage(IBinder activityToken) { 14527 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14528 if (srec == null) { 14529 return null; 14530 } 14531 return srec.launchedFromPackage; 14532 } 14533 14534 // ========================================================= 14535 // LIFETIME MANAGEMENT 14536 // ========================================================= 14537 14538 // Returns which broadcast queue the app is the current [or imminent] receiver 14539 // on, or 'null' if the app is not an active broadcast recipient. 14540 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14541 BroadcastRecord r = app.curReceiver; 14542 if (r != null) { 14543 return r.queue; 14544 } 14545 14546 // It's not the current receiver, but it might be starting up to become one 14547 synchronized (this) { 14548 for (BroadcastQueue queue : mBroadcastQueues) { 14549 r = queue.mPendingBroadcast; 14550 if (r != null && r.curApp == app) { 14551 // found it; report which queue it's in 14552 return queue; 14553 } 14554 } 14555 } 14556 14557 return null; 14558 } 14559 14560 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14561 boolean doingAll, long now) { 14562 if (mAdjSeq == app.adjSeq) { 14563 // This adjustment has already been computed. 14564 return app.curRawAdj; 14565 } 14566 14567 if (app.thread == null) { 14568 app.adjSeq = mAdjSeq; 14569 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14570 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14571 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14572 } 14573 14574 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14575 app.adjSource = null; 14576 app.adjTarget = null; 14577 app.empty = false; 14578 app.cached = false; 14579 14580 final int activitiesSize = app.activities.size(); 14581 14582 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14583 // The max adjustment doesn't allow this app to be anything 14584 // below foreground, so it is not worth doing work for it. 14585 app.adjType = "fixed"; 14586 app.adjSeq = mAdjSeq; 14587 app.curRawAdj = app.maxAdj; 14588 app.foregroundActivities = false; 14589 app.keeping = true; 14590 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14591 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14592 // System processes can do UI, and when they do we want to have 14593 // them trim their memory after the user leaves the UI. To 14594 // facilitate this, here we need to determine whether or not it 14595 // is currently showing UI. 14596 app.systemNoUi = true; 14597 if (app == TOP_APP) { 14598 app.systemNoUi = false; 14599 } else if (activitiesSize > 0) { 14600 for (int j = 0; j < activitiesSize; j++) { 14601 final ActivityRecord r = app.activities.get(j); 14602 if (r.visible) { 14603 app.systemNoUi = false; 14604 } 14605 } 14606 } 14607 if (!app.systemNoUi) { 14608 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14609 } 14610 return (app.curAdj=app.maxAdj); 14611 } 14612 14613 app.keeping = false; 14614 app.systemNoUi = false; 14615 14616 // Determine the importance of the process, starting with most 14617 // important to least, and assign an appropriate OOM adjustment. 14618 int adj; 14619 int schedGroup; 14620 int procState; 14621 boolean foregroundActivities = false; 14622 boolean interesting = false; 14623 BroadcastQueue queue; 14624 if (app == TOP_APP) { 14625 // The last app on the list is the foreground app. 14626 adj = ProcessList.FOREGROUND_APP_ADJ; 14627 schedGroup = Process.THREAD_GROUP_DEFAULT; 14628 app.adjType = "top-activity"; 14629 foregroundActivities = true; 14630 interesting = true; 14631 procState = ActivityManager.PROCESS_STATE_TOP; 14632 } else if (app.instrumentationClass != null) { 14633 // Don't want to kill running instrumentation. 14634 adj = ProcessList.FOREGROUND_APP_ADJ; 14635 schedGroup = Process.THREAD_GROUP_DEFAULT; 14636 app.adjType = "instrumentation"; 14637 interesting = true; 14638 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14639 } else if ((queue = isReceivingBroadcast(app)) != null) { 14640 // An app that is currently receiving a broadcast also 14641 // counts as being in the foreground for OOM killer purposes. 14642 // It's placed in a sched group based on the nature of the 14643 // broadcast as reflected by which queue it's active in. 14644 adj = ProcessList.FOREGROUND_APP_ADJ; 14645 schedGroup = (queue == mFgBroadcastQueue) 14646 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14647 app.adjType = "broadcast"; 14648 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14649 } else if (app.executingServices.size() > 0) { 14650 // An app that is currently executing a service callback also 14651 // counts as being in the foreground. 14652 adj = ProcessList.FOREGROUND_APP_ADJ; 14653 schedGroup = app.execServicesFg ? 14654 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14655 app.adjType = "exec-service"; 14656 procState = ActivityManager.PROCESS_STATE_SERVICE; 14657 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14658 } else { 14659 // As far as we know the process is empty. We may change our mind later. 14660 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14661 // At this point we don't actually know the adjustment. Use the cached adj 14662 // value that the caller wants us to. 14663 adj = cachedAdj; 14664 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14665 app.cached = true; 14666 app.empty = true; 14667 app.adjType = "cch-empty"; 14668 } 14669 14670 // Examine all activities if not already foreground. 14671 if (!foregroundActivities && activitiesSize > 0) { 14672 for (int j = 0; j < activitiesSize; j++) { 14673 final ActivityRecord r = app.activities.get(j); 14674 if (r.app != app) { 14675 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14676 + app + "?!?"); 14677 continue; 14678 } 14679 if (r.visible) { 14680 // App has a visible activity; only upgrade adjustment. 14681 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14682 adj = ProcessList.VISIBLE_APP_ADJ; 14683 app.adjType = "visible"; 14684 } 14685 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14686 procState = ActivityManager.PROCESS_STATE_TOP; 14687 } 14688 schedGroup = Process.THREAD_GROUP_DEFAULT; 14689 app.cached = false; 14690 app.empty = false; 14691 foregroundActivities = true; 14692 break; 14693 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14694 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14695 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14696 app.adjType = "pausing"; 14697 } 14698 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14699 procState = ActivityManager.PROCESS_STATE_TOP; 14700 } 14701 schedGroup = Process.THREAD_GROUP_DEFAULT; 14702 app.cached = false; 14703 app.empty = false; 14704 foregroundActivities = true; 14705 } else if (r.state == ActivityState.STOPPING) { 14706 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14707 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14708 app.adjType = "stopping"; 14709 } 14710 // For the process state, we will at this point consider the 14711 // process to be cached. It will be cached either as an activity 14712 // or empty depending on whether the activity is finishing. We do 14713 // this so that we can treat the process as cached for purposes of 14714 // memory trimming (determing current memory level, trim command to 14715 // send to process) since there can be an arbitrary number of stopping 14716 // processes and they should soon all go into the cached state. 14717 if (!r.finishing) { 14718 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14719 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14720 } 14721 } 14722 app.cached = false; 14723 app.empty = false; 14724 foregroundActivities = true; 14725 } else { 14726 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14727 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14728 app.adjType = "cch-act"; 14729 } 14730 } 14731 } 14732 } 14733 14734 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14735 if (app.foregroundServices) { 14736 // The user is aware of this app, so make it visible. 14737 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14738 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14739 app.cached = false; 14740 app.adjType = "fg-service"; 14741 schedGroup = Process.THREAD_GROUP_DEFAULT; 14742 } else if (app.forcingToForeground != null) { 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 = "force-fg"; 14748 app.adjSource = app.forcingToForeground; 14749 schedGroup = Process.THREAD_GROUP_DEFAULT; 14750 } 14751 } 14752 14753 if (app.foregroundServices) { 14754 interesting = true; 14755 } 14756 14757 if (app == mHeavyWeightProcess) { 14758 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14759 // We don't want to kill the current heavy-weight process. 14760 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14761 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14762 app.cached = false; 14763 app.adjType = "heavy"; 14764 } 14765 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14766 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14767 } 14768 } 14769 14770 if (app == mHomeProcess) { 14771 if (adj > ProcessList.HOME_APP_ADJ) { 14772 // This process is hosting what we currently consider to be the 14773 // home app, so we don't want to let it go into the background. 14774 adj = ProcessList.HOME_APP_ADJ; 14775 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14776 app.cached = false; 14777 app.adjType = "home"; 14778 } 14779 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14780 procState = ActivityManager.PROCESS_STATE_HOME; 14781 } 14782 } 14783 14784 if (app == mPreviousProcess && app.activities.size() > 0) { 14785 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14786 // This was the previous process that showed UI to the user. 14787 // We want to try to keep it around more aggressively, to give 14788 // a good experience around switching between two apps. 14789 adj = ProcessList.PREVIOUS_APP_ADJ; 14790 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14791 app.cached = false; 14792 app.adjType = "previous"; 14793 } 14794 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14795 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14796 } 14797 } 14798 14799 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14800 + " reason=" + app.adjType); 14801 14802 // By default, we use the computed adjustment. It may be changed if 14803 // there are applications dependent on our services or providers, but 14804 // this gives us a baseline and makes sure we don't get into an 14805 // infinite recursion. 14806 app.adjSeq = mAdjSeq; 14807 app.curRawAdj = adj; 14808 app.hasStartedServices = false; 14809 14810 if (mBackupTarget != null && app == mBackupTarget.app) { 14811 // If possible we want to avoid killing apps while they're being backed up 14812 if (adj > ProcessList.BACKUP_APP_ADJ) { 14813 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14814 adj = ProcessList.BACKUP_APP_ADJ; 14815 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14816 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14817 } 14818 app.adjType = "backup"; 14819 app.cached = false; 14820 } 14821 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14822 procState = ActivityManager.PROCESS_STATE_BACKUP; 14823 } 14824 } 14825 14826 boolean mayBeTop = false; 14827 14828 for (int is = app.services.size()-1; 14829 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14830 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14831 || procState > ActivityManager.PROCESS_STATE_TOP); 14832 is--) { 14833 ServiceRecord s = app.services.valueAt(is); 14834 if (s.startRequested) { 14835 app.hasStartedServices = true; 14836 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14837 procState = ActivityManager.PROCESS_STATE_SERVICE; 14838 } 14839 if (app.hasShownUi && app != mHomeProcess) { 14840 // If this process has shown some UI, let it immediately 14841 // go to the LRU list because it may be pretty heavy with 14842 // UI stuff. We'll tag it with a label just to help 14843 // debug and understand what is going on. 14844 if (adj > ProcessList.SERVICE_ADJ) { 14845 app.adjType = "cch-started-ui-services"; 14846 } 14847 } else { 14848 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14849 // This service has seen some activity within 14850 // recent memory, so we will keep its process ahead 14851 // of the background processes. 14852 if (adj > ProcessList.SERVICE_ADJ) { 14853 adj = ProcessList.SERVICE_ADJ; 14854 app.adjType = "started-services"; 14855 app.cached = false; 14856 } 14857 } 14858 // If we have let the service slide into the background 14859 // state, still have some text describing what it is doing 14860 // even though the service no longer has an impact. 14861 if (adj > ProcessList.SERVICE_ADJ) { 14862 app.adjType = "cch-started-services"; 14863 } 14864 } 14865 // Don't kill this process because it is doing work; it 14866 // has said it is doing work. 14867 app.keeping = true; 14868 } 14869 for (int conni = s.connections.size()-1; 14870 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14871 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14872 || procState > ActivityManager.PROCESS_STATE_TOP); 14873 conni--) { 14874 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14875 for (int i = 0; 14876 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14877 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14878 || procState > ActivityManager.PROCESS_STATE_TOP); 14879 i++) { 14880 // XXX should compute this based on the max of 14881 // all connected clients. 14882 ConnectionRecord cr = clist.get(i); 14883 if (cr.binding.client == app) { 14884 // Binding to ourself is not interesting. 14885 continue; 14886 } 14887 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14888 ProcessRecord client = cr.binding.client; 14889 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14890 TOP_APP, doingAll, now); 14891 int clientProcState = client.curProcState; 14892 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14893 // If the other app is cached for any reason, for purposes here 14894 // we are going to consider it empty. The specific cached state 14895 // doesn't propagate except under certain conditions. 14896 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14897 } 14898 String adjType = null; 14899 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14900 // Not doing bind OOM management, so treat 14901 // this guy more like a started service. 14902 if (app.hasShownUi && app != mHomeProcess) { 14903 // If this process has shown some UI, let it immediately 14904 // go to the LRU list because it may be pretty heavy with 14905 // UI stuff. We'll tag it with a label just to help 14906 // debug and understand what is going on. 14907 if (adj > clientAdj) { 14908 adjType = "cch-bound-ui-services"; 14909 } 14910 app.cached = false; 14911 clientAdj = adj; 14912 clientProcState = procState; 14913 } else { 14914 if (now >= (s.lastActivity 14915 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14916 // This service has not seen activity within 14917 // recent memory, so allow it to drop to the 14918 // LRU list if there is no other reason to keep 14919 // it around. We'll also tag it with a label just 14920 // to help debug and undertand what is going on. 14921 if (adj > clientAdj) { 14922 adjType = "cch-bound-services"; 14923 } 14924 clientAdj = adj; 14925 } 14926 } 14927 } 14928 if (adj > clientAdj) { 14929 // If this process has recently shown UI, and 14930 // the process that is binding to it is less 14931 // important than being visible, then we don't 14932 // care about the binding as much as we care 14933 // about letting this process get into the LRU 14934 // list to be killed and restarted if needed for 14935 // memory. 14936 if (app.hasShownUi && app != mHomeProcess 14937 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14938 adjType = "cch-bound-ui-services"; 14939 } else { 14940 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14941 |Context.BIND_IMPORTANT)) != 0) { 14942 adj = clientAdj; 14943 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14944 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14945 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14946 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14947 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14948 adj = clientAdj; 14949 } else { 14950 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14951 adj = ProcessList.VISIBLE_APP_ADJ; 14952 } 14953 } 14954 if (!client.cached) { 14955 app.cached = false; 14956 } 14957 if (client.keeping) { 14958 app.keeping = true; 14959 } 14960 adjType = "service"; 14961 } 14962 } 14963 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14964 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14965 schedGroup = Process.THREAD_GROUP_DEFAULT; 14966 } 14967 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14968 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14969 // Special handling of clients who are in the top state. 14970 // We *may* want to consider this process to be in the 14971 // top state as well, but only if there is not another 14972 // reason for it to be running. Being on the top is a 14973 // special state, meaning you are specifically running 14974 // for the current top app. If the process is already 14975 // running in the background for some other reason, it 14976 // is more important to continue considering it to be 14977 // in the background state. 14978 mayBeTop = true; 14979 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14980 } else { 14981 // Special handling for above-top states (persistent 14982 // processes). These should not bring the current process 14983 // into the top state, since they are not on top. Instead 14984 // give them the best state after that. 14985 clientProcState = 14986 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14987 } 14988 } 14989 } else { 14990 if (clientProcState < 14991 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14992 clientProcState = 14993 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14994 } 14995 } 14996 if (procState > clientProcState) { 14997 procState = clientProcState; 14998 } 14999 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15000 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15001 app.pendingUiClean = true; 15002 } 15003 if (adjType != null) { 15004 app.adjType = adjType; 15005 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15006 .REASON_SERVICE_IN_USE; 15007 app.adjSource = cr.binding.client; 15008 app.adjSourceOom = clientAdj; 15009 app.adjTarget = s.name; 15010 } 15011 } 15012 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15013 app.treatLikeActivity = true; 15014 } 15015 final ActivityRecord a = cr.activity; 15016 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15017 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15018 (a.visible || a.state == ActivityState.RESUMED 15019 || a.state == ActivityState.PAUSING)) { 15020 adj = ProcessList.FOREGROUND_APP_ADJ; 15021 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15022 schedGroup = Process.THREAD_GROUP_DEFAULT; 15023 } 15024 app.cached = false; 15025 app.adjType = "service"; 15026 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15027 .REASON_SERVICE_IN_USE; 15028 app.adjSource = a; 15029 app.adjSourceOom = adj; 15030 app.adjTarget = s.name; 15031 } 15032 } 15033 } 15034 } 15035 } 15036 15037 for (int provi = app.pubProviders.size()-1; 15038 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15039 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15040 || procState > ActivityManager.PROCESS_STATE_TOP); 15041 provi--) { 15042 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15043 for (int i = cpr.connections.size()-1; 15044 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15045 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15046 || procState > ActivityManager.PROCESS_STATE_TOP); 15047 i--) { 15048 ContentProviderConnection conn = cpr.connections.get(i); 15049 ProcessRecord client = conn.client; 15050 if (client == app) { 15051 // Being our own client is not interesting. 15052 continue; 15053 } 15054 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15055 int clientProcState = client.curProcState; 15056 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15057 // If the other app is cached for any reason, for purposes here 15058 // we are going to consider it empty. 15059 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15060 } 15061 if (adj > clientAdj) { 15062 if (app.hasShownUi && app != mHomeProcess 15063 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15064 app.adjType = "cch-ui-provider"; 15065 } else { 15066 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15067 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15068 app.adjType = "provider"; 15069 } 15070 app.cached &= client.cached; 15071 app.keeping |= client.keeping; 15072 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15073 .REASON_PROVIDER_IN_USE; 15074 app.adjSource = client; 15075 app.adjSourceOom = clientAdj; 15076 app.adjTarget = cpr.name; 15077 } 15078 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15079 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15080 // Special handling of clients who are in the top state. 15081 // We *may* want to consider this process to be in the 15082 // top state as well, but only if there is not another 15083 // reason for it to be running. Being on the top is a 15084 // special state, meaning you are specifically running 15085 // for the current top app. If the process is already 15086 // running in the background for some other reason, it 15087 // is more important to continue considering it to be 15088 // in the background state. 15089 mayBeTop = true; 15090 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15091 } else { 15092 // Special handling for above-top states (persistent 15093 // processes). These should not bring the current process 15094 // into the top state, since they are not on top. Instead 15095 // give them the best state after that. 15096 clientProcState = 15097 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15098 } 15099 } 15100 if (procState > clientProcState) { 15101 procState = clientProcState; 15102 } 15103 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15104 schedGroup = Process.THREAD_GROUP_DEFAULT; 15105 } 15106 } 15107 // If the provider has external (non-framework) process 15108 // dependencies, ensure that its adjustment is at least 15109 // FOREGROUND_APP_ADJ. 15110 if (cpr.hasExternalProcessHandles()) { 15111 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15112 adj = ProcessList.FOREGROUND_APP_ADJ; 15113 schedGroup = Process.THREAD_GROUP_DEFAULT; 15114 app.cached = false; 15115 app.keeping = true; 15116 app.adjType = "provider"; 15117 app.adjTarget = cpr.name; 15118 } 15119 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15120 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15121 } 15122 } 15123 } 15124 15125 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15126 // A client of one of our services or providers is in the top state. We 15127 // *may* want to be in the top state, but not if we are already running in 15128 // the background for some other reason. For the decision here, we are going 15129 // to pick out a few specific states that we want to remain in when a client 15130 // is top (states that tend to be longer-term) and otherwise allow it to go 15131 // to the top state. 15132 switch (procState) { 15133 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15134 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15135 case ActivityManager.PROCESS_STATE_SERVICE: 15136 // These all are longer-term states, so pull them up to the top 15137 // of the background states, but not all the way to the top state. 15138 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15139 break; 15140 default: 15141 // Otherwise, top is a better choice, so take it. 15142 procState = ActivityManager.PROCESS_STATE_TOP; 15143 break; 15144 } 15145 } 15146 15147 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15148 if (app.hasClientActivities) { 15149 // This is a cached process, but with client activities. Mark it so. 15150 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15151 app.adjType = "cch-client-act"; 15152 } else if (app.treatLikeActivity) { 15153 // This is a cached process, but somebody wants us to treat it like it has 15154 // an activity, okay! 15155 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15156 app.adjType = "cch-as-act"; 15157 } 15158 } 15159 15160 if (adj == ProcessList.SERVICE_ADJ) { 15161 if (doingAll) { 15162 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15163 mNewNumServiceProcs++; 15164 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15165 if (!app.serviceb) { 15166 // This service isn't far enough down on the LRU list to 15167 // normally be a B service, but if we are low on RAM and it 15168 // is large we want to force it down since we would prefer to 15169 // keep launcher over it. 15170 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15171 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15172 app.serviceHighRam = true; 15173 app.serviceb = true; 15174 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15175 } else { 15176 mNewNumAServiceProcs++; 15177 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15178 } 15179 } else { 15180 app.serviceHighRam = false; 15181 } 15182 } 15183 if (app.serviceb) { 15184 adj = ProcessList.SERVICE_B_ADJ; 15185 } 15186 } 15187 15188 app.curRawAdj = adj; 15189 15190 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15191 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15192 if (adj > app.maxAdj) { 15193 adj = app.maxAdj; 15194 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15195 schedGroup = Process.THREAD_GROUP_DEFAULT; 15196 } 15197 } 15198 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15199 app.keeping = true; 15200 } 15201 15202 // Do final modification to adj. Everything we do between here and applying 15203 // the final setAdj must be done in this function, because we will also use 15204 // it when computing the final cached adj later. Note that we don't need to 15205 // worry about this for max adj above, since max adj will always be used to 15206 // keep it out of the cached vaues. 15207 app.curAdj = app.modifyRawOomAdj(adj); 15208 app.curSchedGroup = schedGroup; 15209 app.curProcState = procState; 15210 app.foregroundActivities = foregroundActivities; 15211 15212 return app.curRawAdj; 15213 } 15214 15215 /** 15216 * Schedule PSS collection of a process. 15217 */ 15218 void requestPssLocked(ProcessRecord proc, int procState) { 15219 if (mPendingPssProcesses.contains(proc)) { 15220 return; 15221 } 15222 if (mPendingPssProcesses.size() == 0) { 15223 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15224 } 15225 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15226 proc.pssProcState = procState; 15227 mPendingPssProcesses.add(proc); 15228 } 15229 15230 /** 15231 * Schedule PSS collection of all processes. 15232 */ 15233 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15234 if (!always) { 15235 if (now < (mLastFullPssTime + 15236 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15237 return; 15238 } 15239 } 15240 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15241 mLastFullPssTime = now; 15242 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15243 mPendingPssProcesses.clear(); 15244 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15245 ProcessRecord app = mLruProcesses.get(i); 15246 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15247 app.pssProcState = app.setProcState; 15248 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15249 isSleeping(), now); 15250 mPendingPssProcesses.add(app); 15251 } 15252 } 15253 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15254 } 15255 15256 /** 15257 * Ask a given process to GC right now. 15258 */ 15259 final void performAppGcLocked(ProcessRecord app) { 15260 try { 15261 app.lastRequestedGc = SystemClock.uptimeMillis(); 15262 if (app.thread != null) { 15263 if (app.reportLowMemory) { 15264 app.reportLowMemory = false; 15265 app.thread.scheduleLowMemory(); 15266 } else { 15267 app.thread.processInBackground(); 15268 } 15269 } 15270 } catch (Exception e) { 15271 // whatever. 15272 } 15273 } 15274 15275 /** 15276 * Returns true if things are idle enough to perform GCs. 15277 */ 15278 private final boolean canGcNowLocked() { 15279 boolean processingBroadcasts = false; 15280 for (BroadcastQueue q : mBroadcastQueues) { 15281 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15282 processingBroadcasts = true; 15283 } 15284 } 15285 return !processingBroadcasts 15286 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15287 } 15288 15289 /** 15290 * Perform GCs on all processes that are waiting for it, but only 15291 * if things are idle. 15292 */ 15293 final void performAppGcsLocked() { 15294 final int N = mProcessesToGc.size(); 15295 if (N <= 0) { 15296 return; 15297 } 15298 if (canGcNowLocked()) { 15299 while (mProcessesToGc.size() > 0) { 15300 ProcessRecord proc = mProcessesToGc.remove(0); 15301 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15302 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15303 <= SystemClock.uptimeMillis()) { 15304 // To avoid spamming the system, we will GC processes one 15305 // at a time, waiting a few seconds between each. 15306 performAppGcLocked(proc); 15307 scheduleAppGcsLocked(); 15308 return; 15309 } else { 15310 // It hasn't been long enough since we last GCed this 15311 // process... put it in the list to wait for its time. 15312 addProcessToGcListLocked(proc); 15313 break; 15314 } 15315 } 15316 } 15317 15318 scheduleAppGcsLocked(); 15319 } 15320 } 15321 15322 /** 15323 * If all looks good, perform GCs on all processes waiting for them. 15324 */ 15325 final void performAppGcsIfAppropriateLocked() { 15326 if (canGcNowLocked()) { 15327 performAppGcsLocked(); 15328 return; 15329 } 15330 // Still not idle, wait some more. 15331 scheduleAppGcsLocked(); 15332 } 15333 15334 /** 15335 * Schedule the execution of all pending app GCs. 15336 */ 15337 final void scheduleAppGcsLocked() { 15338 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15339 15340 if (mProcessesToGc.size() > 0) { 15341 // Schedule a GC for the time to the next process. 15342 ProcessRecord proc = mProcessesToGc.get(0); 15343 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15344 15345 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15346 long now = SystemClock.uptimeMillis(); 15347 if (when < (now+GC_TIMEOUT)) { 15348 when = now + GC_TIMEOUT; 15349 } 15350 mHandler.sendMessageAtTime(msg, when); 15351 } 15352 } 15353 15354 /** 15355 * Add a process to the array of processes waiting to be GCed. Keeps the 15356 * list in sorted order by the last GC time. The process can't already be 15357 * on the list. 15358 */ 15359 final void addProcessToGcListLocked(ProcessRecord proc) { 15360 boolean added = false; 15361 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15362 if (mProcessesToGc.get(i).lastRequestedGc < 15363 proc.lastRequestedGc) { 15364 added = true; 15365 mProcessesToGc.add(i+1, proc); 15366 break; 15367 } 15368 } 15369 if (!added) { 15370 mProcessesToGc.add(0, proc); 15371 } 15372 } 15373 15374 /** 15375 * Set up to ask a process to GC itself. This will either do it 15376 * immediately, or put it on the list of processes to gc the next 15377 * time things are idle. 15378 */ 15379 final void scheduleAppGcLocked(ProcessRecord app) { 15380 long now = SystemClock.uptimeMillis(); 15381 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15382 return; 15383 } 15384 if (!mProcessesToGc.contains(app)) { 15385 addProcessToGcListLocked(app); 15386 scheduleAppGcsLocked(); 15387 } 15388 } 15389 15390 final void checkExcessivePowerUsageLocked(boolean doKills) { 15391 updateCpuStatsNow(); 15392 15393 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15394 boolean doWakeKills = doKills; 15395 boolean doCpuKills = doKills; 15396 if (mLastPowerCheckRealtime == 0) { 15397 doWakeKills = false; 15398 } 15399 if (mLastPowerCheckUptime == 0) { 15400 doCpuKills = false; 15401 } 15402 if (stats.isScreenOn()) { 15403 doWakeKills = false; 15404 } 15405 final long curRealtime = SystemClock.elapsedRealtime(); 15406 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15407 final long curUptime = SystemClock.uptimeMillis(); 15408 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15409 mLastPowerCheckRealtime = curRealtime; 15410 mLastPowerCheckUptime = curUptime; 15411 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15412 doWakeKills = false; 15413 } 15414 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15415 doCpuKills = false; 15416 } 15417 int i = mLruProcesses.size(); 15418 while (i > 0) { 15419 i--; 15420 ProcessRecord app = mLruProcesses.get(i); 15421 if (!app.keeping) { 15422 long wtime; 15423 synchronized (stats) { 15424 wtime = stats.getProcessWakeTime(app.info.uid, 15425 app.pid, curRealtime); 15426 } 15427 long wtimeUsed = wtime - app.lastWakeTime; 15428 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15429 if (DEBUG_POWER) { 15430 StringBuilder sb = new StringBuilder(128); 15431 sb.append("Wake for "); 15432 app.toShortString(sb); 15433 sb.append(": over "); 15434 TimeUtils.formatDuration(realtimeSince, sb); 15435 sb.append(" used "); 15436 TimeUtils.formatDuration(wtimeUsed, sb); 15437 sb.append(" ("); 15438 sb.append((wtimeUsed*100)/realtimeSince); 15439 sb.append("%)"); 15440 Slog.i(TAG, sb.toString()); 15441 sb.setLength(0); 15442 sb.append("CPU for "); 15443 app.toShortString(sb); 15444 sb.append(": over "); 15445 TimeUtils.formatDuration(uptimeSince, sb); 15446 sb.append(" used "); 15447 TimeUtils.formatDuration(cputimeUsed, sb); 15448 sb.append(" ("); 15449 sb.append((cputimeUsed*100)/uptimeSince); 15450 sb.append("%)"); 15451 Slog.i(TAG, sb.toString()); 15452 } 15453 // If a process has held a wake lock for more 15454 // than 50% of the time during this period, 15455 // that sounds bad. Kill! 15456 if (doWakeKills && realtimeSince > 0 15457 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15458 synchronized (stats) { 15459 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15460 realtimeSince, wtimeUsed); 15461 } 15462 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15463 + " during " + realtimeSince); 15464 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15465 } else if (doCpuKills && uptimeSince > 0 15466 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15467 synchronized (stats) { 15468 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15469 uptimeSince, cputimeUsed); 15470 } 15471 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15472 + " during " + uptimeSince); 15473 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15474 } else { 15475 app.lastWakeTime = wtime; 15476 app.lastCpuTime = app.curCpuTime; 15477 } 15478 } 15479 } 15480 } 15481 15482 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15483 ProcessRecord TOP_APP, boolean doingAll, long now) { 15484 boolean success = true; 15485 15486 if (app.curRawAdj != app.setRawAdj) { 15487 if (wasKeeping && !app.keeping) { 15488 // This app is no longer something we want to keep. Note 15489 // its current wake lock time to later know to kill it if 15490 // it is not behaving well. 15491 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15492 synchronized (stats) { 15493 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15494 app.pid, SystemClock.elapsedRealtime()); 15495 } 15496 app.lastCpuTime = app.curCpuTime; 15497 } 15498 15499 app.setRawAdj = app.curRawAdj; 15500 } 15501 15502 int changes = 0; 15503 15504 if (app.curAdj != app.setAdj) { 15505 ProcessList.setOomAdj(app.pid, app.curAdj); 15506 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15507 TAG, "Set " + app.pid + " " + app.processName + 15508 " adj " + app.curAdj + ": " + app.adjType); 15509 app.setAdj = app.curAdj; 15510 } 15511 15512 if (app.setSchedGroup != app.curSchedGroup) { 15513 app.setSchedGroup = app.curSchedGroup; 15514 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15515 "Setting process group of " + app.processName 15516 + " to " + app.curSchedGroup); 15517 if (app.waitingToKill != null && 15518 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15519 killUnneededProcessLocked(app, app.waitingToKill); 15520 success = false; 15521 } else { 15522 if (true) { 15523 long oldId = Binder.clearCallingIdentity(); 15524 try { 15525 Process.setProcessGroup(app.pid, app.curSchedGroup); 15526 } catch (Exception e) { 15527 Slog.w(TAG, "Failed setting process group of " + app.pid 15528 + " to " + app.curSchedGroup); 15529 e.printStackTrace(); 15530 } finally { 15531 Binder.restoreCallingIdentity(oldId); 15532 } 15533 } else { 15534 if (app.thread != null) { 15535 try { 15536 app.thread.setSchedulingGroup(app.curSchedGroup); 15537 } catch (RemoteException e) { 15538 } 15539 } 15540 } 15541 Process.setSwappiness(app.pid, 15542 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15543 } 15544 } 15545 if (app.repForegroundActivities != app.foregroundActivities) { 15546 app.repForegroundActivities = app.foregroundActivities; 15547 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15548 } 15549 if (app.repProcState != app.curProcState) { 15550 app.repProcState = app.curProcState; 15551 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15552 if (app.thread != null) { 15553 try { 15554 if (false) { 15555 //RuntimeException h = new RuntimeException("here"); 15556 Slog.i(TAG, "Sending new process state " + app.repProcState 15557 + " to " + app /*, h*/); 15558 } 15559 app.thread.setProcessState(app.repProcState); 15560 } catch (RemoteException e) { 15561 } 15562 } 15563 } 15564 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15565 app.setProcState)) { 15566 app.lastStateTime = now; 15567 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15568 isSleeping(), now); 15569 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15570 + ProcessList.makeProcStateString(app.setProcState) + " to " 15571 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15572 + (app.nextPssTime-now) + ": " + app); 15573 } else { 15574 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15575 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15576 requestPssLocked(app, app.setProcState); 15577 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15578 isSleeping(), now); 15579 } else if (false && DEBUG_PSS) { 15580 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15581 } 15582 } 15583 if (app.setProcState != app.curProcState) { 15584 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15585 "Proc state change of " + app.processName 15586 + " to " + app.curProcState); 15587 app.setProcState = app.curProcState; 15588 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15589 app.notCachedSinceIdle = false; 15590 } 15591 if (!doingAll) { 15592 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15593 } else { 15594 app.procStateChanged = true; 15595 } 15596 } 15597 15598 if (changes != 0) { 15599 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15600 int i = mPendingProcessChanges.size()-1; 15601 ProcessChangeItem item = null; 15602 while (i >= 0) { 15603 item = mPendingProcessChanges.get(i); 15604 if (item.pid == app.pid) { 15605 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15606 break; 15607 } 15608 i--; 15609 } 15610 if (i < 0) { 15611 // No existing item in pending changes; need a new one. 15612 final int NA = mAvailProcessChanges.size(); 15613 if (NA > 0) { 15614 item = mAvailProcessChanges.remove(NA-1); 15615 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15616 } else { 15617 item = new ProcessChangeItem(); 15618 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15619 } 15620 item.changes = 0; 15621 item.pid = app.pid; 15622 item.uid = app.info.uid; 15623 if (mPendingProcessChanges.size() == 0) { 15624 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15625 "*** Enqueueing dispatch processes changed!"); 15626 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15627 } 15628 mPendingProcessChanges.add(item); 15629 } 15630 item.changes |= changes; 15631 item.processState = app.repProcState; 15632 item.foregroundActivities = app.repForegroundActivities; 15633 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15634 + Integer.toHexString(System.identityHashCode(item)) 15635 + " " + app.toShortString() + ": changes=" + item.changes 15636 + " procState=" + item.processState 15637 + " foreground=" + item.foregroundActivities 15638 + " type=" + app.adjType + " source=" + app.adjSource 15639 + " target=" + app.adjTarget); 15640 } 15641 15642 return success; 15643 } 15644 15645 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15646 if (proc.thread != null && proc.baseProcessTracker != null) { 15647 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15648 } 15649 } 15650 15651 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15652 ProcessRecord TOP_APP, boolean doingAll, long now) { 15653 if (app.thread == null) { 15654 return false; 15655 } 15656 15657 final boolean wasKeeping = app.keeping; 15658 15659 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15660 15661 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 15662 } 15663 15664 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15665 boolean oomAdj) { 15666 if (isForeground != proc.foregroundServices) { 15667 proc.foregroundServices = isForeground; 15668 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15669 proc.info.uid); 15670 if (isForeground) { 15671 if (curProcs == null) { 15672 curProcs = new ArrayList<ProcessRecord>(); 15673 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15674 } 15675 if (!curProcs.contains(proc)) { 15676 curProcs.add(proc); 15677 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15678 proc.info.packageName, proc.info.uid); 15679 } 15680 } else { 15681 if (curProcs != null) { 15682 if (curProcs.remove(proc)) { 15683 mBatteryStatsService.noteEvent( 15684 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15685 proc.info.packageName, proc.info.uid); 15686 if (curProcs.size() <= 0) { 15687 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15688 } 15689 } 15690 } 15691 } 15692 if (oomAdj) { 15693 updateOomAdjLocked(); 15694 } 15695 } 15696 } 15697 15698 private final ActivityRecord resumedAppLocked() { 15699 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15700 String pkg; 15701 int uid; 15702 if (act != null && !act.sleeping) { 15703 pkg = act.packageName; 15704 uid = act.info.applicationInfo.uid; 15705 } else { 15706 pkg = null; 15707 uid = -1; 15708 } 15709 // Has the UID or resumed package name changed? 15710 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15711 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15712 if (mCurResumedPackage != null) { 15713 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15714 mCurResumedPackage, mCurResumedUid); 15715 } 15716 mCurResumedPackage = pkg; 15717 mCurResumedUid = uid; 15718 if (mCurResumedPackage != null) { 15719 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15720 mCurResumedPackage, mCurResumedUid); 15721 } 15722 } 15723 return act; 15724 } 15725 15726 final boolean updateOomAdjLocked(ProcessRecord app) { 15727 final ActivityRecord TOP_ACT = resumedAppLocked(); 15728 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15729 final boolean wasCached = app.cached; 15730 15731 mAdjSeq++; 15732 15733 // This is the desired cached adjusment we want to tell it to use. 15734 // If our app is currently cached, we know it, and that is it. Otherwise, 15735 // we don't know it yet, and it needs to now be cached we will then 15736 // need to do a complete oom adj. 15737 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15738 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15739 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 15740 SystemClock.uptimeMillis()); 15741 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15742 // Changed to/from cached state, so apps after it in the LRU 15743 // list may also be changed. 15744 updateOomAdjLocked(); 15745 } 15746 return success; 15747 } 15748 15749 final void updateOomAdjLocked() { 15750 final ActivityRecord TOP_ACT = resumedAppLocked(); 15751 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15752 final long now = SystemClock.uptimeMillis(); 15753 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15754 final int N = mLruProcesses.size(); 15755 15756 if (false) { 15757 RuntimeException e = new RuntimeException(); 15758 e.fillInStackTrace(); 15759 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15760 } 15761 15762 mAdjSeq++; 15763 mNewNumServiceProcs = 0; 15764 mNewNumAServiceProcs = 0; 15765 15766 final int emptyProcessLimit; 15767 final int cachedProcessLimit; 15768 if (mProcessLimit <= 0) { 15769 emptyProcessLimit = cachedProcessLimit = 0; 15770 } else if (mProcessLimit == 1) { 15771 emptyProcessLimit = 1; 15772 cachedProcessLimit = 0; 15773 } else { 15774 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15775 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15776 } 15777 15778 // Let's determine how many processes we have running vs. 15779 // how many slots we have for background processes; we may want 15780 // to put multiple processes in a slot of there are enough of 15781 // them. 15782 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15783 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15784 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15785 if (numEmptyProcs > cachedProcessLimit) { 15786 // If there are more empty processes than our limit on cached 15787 // processes, then use the cached process limit for the factor. 15788 // This ensures that the really old empty processes get pushed 15789 // down to the bottom, so if we are running low on memory we will 15790 // have a better chance at keeping around more cached processes 15791 // instead of a gazillion empty processes. 15792 numEmptyProcs = cachedProcessLimit; 15793 } 15794 int emptyFactor = numEmptyProcs/numSlots; 15795 if (emptyFactor < 1) emptyFactor = 1; 15796 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15797 if (cachedFactor < 1) cachedFactor = 1; 15798 int stepCached = 0; 15799 int stepEmpty = 0; 15800 int numCached = 0; 15801 int numEmpty = 0; 15802 int numTrimming = 0; 15803 15804 mNumNonCachedProcs = 0; 15805 mNumCachedHiddenProcs = 0; 15806 15807 // First update the OOM adjustment for each of the 15808 // application processes based on their current state. 15809 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15810 int nextCachedAdj = curCachedAdj+1; 15811 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15812 int nextEmptyAdj = curEmptyAdj+2; 15813 for (int i=N-1; i>=0; i--) { 15814 ProcessRecord app = mLruProcesses.get(i); 15815 if (!app.killedByAm && app.thread != null) { 15816 app.procStateChanged = false; 15817 final boolean wasKeeping = app.keeping; 15818 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15819 15820 // If we haven't yet assigned the final cached adj 15821 // to the process, do that now. 15822 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15823 switch (app.curProcState) { 15824 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15825 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15826 // This process is a cached process holding activities... 15827 // assign it the next cached value for that type, and then 15828 // step that cached level. 15829 app.curRawAdj = curCachedAdj; 15830 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15831 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15832 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15833 + ")"); 15834 if (curCachedAdj != nextCachedAdj) { 15835 stepCached++; 15836 if (stepCached >= cachedFactor) { 15837 stepCached = 0; 15838 curCachedAdj = nextCachedAdj; 15839 nextCachedAdj += 2; 15840 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15841 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15842 } 15843 } 15844 } 15845 break; 15846 default: 15847 // For everything else, assign next empty cached process 15848 // level and bump that up. Note that this means that 15849 // long-running services that have dropped down to the 15850 // cached level will be treated as empty (since their process 15851 // state is still as a service), which is what we want. 15852 app.curRawAdj = curEmptyAdj; 15853 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15854 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15855 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15856 + ")"); 15857 if (curEmptyAdj != nextEmptyAdj) { 15858 stepEmpty++; 15859 if (stepEmpty >= emptyFactor) { 15860 stepEmpty = 0; 15861 curEmptyAdj = nextEmptyAdj; 15862 nextEmptyAdj += 2; 15863 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15864 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15865 } 15866 } 15867 } 15868 break; 15869 } 15870 } 15871 15872 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 15873 15874 // Count the number of process types. 15875 switch (app.curProcState) { 15876 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15877 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15878 mNumCachedHiddenProcs++; 15879 numCached++; 15880 if (numCached > cachedProcessLimit) { 15881 killUnneededProcessLocked(app, "cached #" + numCached); 15882 } 15883 break; 15884 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15885 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15886 && app.lastActivityTime < oldTime) { 15887 killUnneededProcessLocked(app, "empty for " 15888 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15889 / 1000) + "s"); 15890 } else { 15891 numEmpty++; 15892 if (numEmpty > emptyProcessLimit) { 15893 killUnneededProcessLocked(app, "empty #" + numEmpty); 15894 } 15895 } 15896 break; 15897 default: 15898 mNumNonCachedProcs++; 15899 break; 15900 } 15901 15902 if (app.isolated && app.services.size() <= 0) { 15903 // If this is an isolated process, and there are no 15904 // services running in it, then the process is no longer 15905 // needed. We agressively kill these because we can by 15906 // definition not re-use the same process again, and it is 15907 // good to avoid having whatever code was running in them 15908 // left sitting around after no longer needed. 15909 killUnneededProcessLocked(app, "isolated not needed"); 15910 } 15911 15912 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15913 && !app.killedByAm) { 15914 numTrimming++; 15915 } 15916 } 15917 } 15918 15919 mNumServiceProcs = mNewNumServiceProcs; 15920 15921 // Now determine the memory trimming level of background processes. 15922 // Unfortunately we need to start at the back of the list to do this 15923 // properly. We only do this if the number of background apps we 15924 // are managing to keep around is less than half the maximum we desire; 15925 // if we are keeping a good number around, we'll let them use whatever 15926 // memory they want. 15927 final int numCachedAndEmpty = numCached + numEmpty; 15928 int memFactor; 15929 if (numCached <= ProcessList.TRIM_CACHED_APPS 15930 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15931 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15932 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15933 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15934 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15935 } else { 15936 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15937 } 15938 } else { 15939 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15940 } 15941 // We always allow the memory level to go up (better). We only allow it to go 15942 // down if we are in a state where that is allowed, *and* the total number of processes 15943 // has gone down since last time. 15944 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15945 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15946 + " last=" + mLastNumProcesses); 15947 if (memFactor > mLastMemoryLevel) { 15948 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15949 memFactor = mLastMemoryLevel; 15950 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15951 } 15952 } 15953 mLastMemoryLevel = memFactor; 15954 mLastNumProcesses = mLruProcesses.size(); 15955 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 15956 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15957 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15958 if (mLowRamStartTime == 0) { 15959 mLowRamStartTime = now; 15960 } 15961 int step = 0; 15962 int fgTrimLevel; 15963 switch (memFactor) { 15964 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15965 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15966 break; 15967 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15968 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15969 break; 15970 default: 15971 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15972 break; 15973 } 15974 int factor = numTrimming/3; 15975 int minFactor = 2; 15976 if (mHomeProcess != null) minFactor++; 15977 if (mPreviousProcess != null) minFactor++; 15978 if (factor < minFactor) factor = minFactor; 15979 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15980 for (int i=N-1; i>=0; i--) { 15981 ProcessRecord app = mLruProcesses.get(i); 15982 if (allChanged || app.procStateChanged) { 15983 setProcessTrackerState(app, trackerMemFactor, now); 15984 app.procStateChanged = false; 15985 } 15986 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15987 && !app.killedByAm) { 15988 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15989 try { 15990 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15991 "Trimming memory of " + app.processName 15992 + " to " + curLevel); 15993 app.thread.scheduleTrimMemory(curLevel); 15994 } catch (RemoteException e) { 15995 } 15996 if (false) { 15997 // For now we won't do this; our memory trimming seems 15998 // to be good enough at this point that destroying 15999 // activities causes more harm than good. 16000 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16001 && app != mHomeProcess && app != mPreviousProcess) { 16002 // Need to do this on its own message because the stack may not 16003 // be in a consistent state at this point. 16004 // For these apps we will also finish their activities 16005 // to help them free memory. 16006 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16007 } 16008 } 16009 } 16010 app.trimMemoryLevel = curLevel; 16011 step++; 16012 if (step >= factor) { 16013 step = 0; 16014 switch (curLevel) { 16015 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16016 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16017 break; 16018 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16019 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16020 break; 16021 } 16022 } 16023 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16024 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16025 && app.thread != null) { 16026 try { 16027 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16028 "Trimming memory of heavy-weight " + app.processName 16029 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16030 app.thread.scheduleTrimMemory( 16031 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16032 } catch (RemoteException e) { 16033 } 16034 } 16035 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16036 } else { 16037 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16038 || app.systemNoUi) && app.pendingUiClean) { 16039 // If this application is now in the background and it 16040 // had done UI, then give it the special trim level to 16041 // have it free UI resources. 16042 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16043 if (app.trimMemoryLevel < level && app.thread != null) { 16044 try { 16045 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16046 "Trimming memory of bg-ui " + app.processName 16047 + " to " + level); 16048 app.thread.scheduleTrimMemory(level); 16049 } catch (RemoteException e) { 16050 } 16051 } 16052 app.pendingUiClean = false; 16053 } 16054 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16055 try { 16056 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16057 "Trimming memory of fg " + app.processName 16058 + " to " + fgTrimLevel); 16059 app.thread.scheduleTrimMemory(fgTrimLevel); 16060 } catch (RemoteException e) { 16061 } 16062 } 16063 app.trimMemoryLevel = fgTrimLevel; 16064 } 16065 } 16066 } else { 16067 if (mLowRamStartTime != 0) { 16068 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16069 mLowRamStartTime = 0; 16070 } 16071 for (int i=N-1; i>=0; i--) { 16072 ProcessRecord app = mLruProcesses.get(i); 16073 if (allChanged || app.procStateChanged) { 16074 setProcessTrackerState(app, trackerMemFactor, now); 16075 app.procStateChanged = false; 16076 } 16077 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16078 || app.systemNoUi) && app.pendingUiClean) { 16079 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16080 && app.thread != null) { 16081 try { 16082 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16083 "Trimming memory of ui hidden " + app.processName 16084 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16085 app.thread.scheduleTrimMemory( 16086 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16087 } catch (RemoteException e) { 16088 } 16089 } 16090 app.pendingUiClean = false; 16091 } 16092 app.trimMemoryLevel = 0; 16093 } 16094 } 16095 16096 if (mAlwaysFinishActivities) { 16097 // Need to do this on its own message because the stack may not 16098 // be in a consistent state at this point. 16099 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16100 } 16101 16102 if (allChanged) { 16103 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16104 } 16105 16106 if (mProcessStats.shouldWriteNowLocked(now)) { 16107 mHandler.post(new Runnable() { 16108 @Override public void run() { 16109 synchronized (ActivityManagerService.this) { 16110 mProcessStats.writeStateAsyncLocked(); 16111 } 16112 } 16113 }); 16114 } 16115 16116 if (DEBUG_OOM_ADJ) { 16117 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16118 } 16119 } 16120 16121 final void trimApplications() { 16122 synchronized (this) { 16123 int i; 16124 16125 // First remove any unused application processes whose package 16126 // has been removed. 16127 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16128 final ProcessRecord app = mRemovedProcesses.get(i); 16129 if (app.activities.size() == 0 16130 && app.curReceiver == null && app.services.size() == 0) { 16131 Slog.i( 16132 TAG, "Exiting empty application process " 16133 + app.processName + " (" 16134 + (app.thread != null ? app.thread.asBinder() : null) 16135 + ")\n"); 16136 if (app.pid > 0 && app.pid != MY_PID) { 16137 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16138 app.processName, app.setAdj, "empty"); 16139 app.killedByAm = true; 16140 Process.killProcessQuiet(app.pid); 16141 } else { 16142 try { 16143 app.thread.scheduleExit(); 16144 } catch (Exception e) { 16145 // Ignore exceptions. 16146 } 16147 } 16148 cleanUpApplicationRecordLocked(app, false, true, -1); 16149 mRemovedProcesses.remove(i); 16150 16151 if (app.persistent) { 16152 if (app.persistent) { 16153 addAppLocked(app.info, false); 16154 } 16155 } 16156 } 16157 } 16158 16159 // Now update the oom adj for all processes. 16160 updateOomAdjLocked(); 16161 } 16162 } 16163 16164 /** This method sends the specified signal to each of the persistent apps */ 16165 public void signalPersistentProcesses(int sig) throws RemoteException { 16166 if (sig != Process.SIGNAL_USR1) { 16167 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16168 } 16169 16170 synchronized (this) { 16171 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16172 != PackageManager.PERMISSION_GRANTED) { 16173 throw new SecurityException("Requires permission " 16174 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16175 } 16176 16177 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16178 ProcessRecord r = mLruProcesses.get(i); 16179 if (r.thread != null && r.persistent) { 16180 Process.sendSignal(r.pid, sig); 16181 } 16182 } 16183 } 16184 } 16185 16186 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16187 if (proc == null || proc == mProfileProc) { 16188 proc = mProfileProc; 16189 path = mProfileFile; 16190 profileType = mProfileType; 16191 clearProfilerLocked(); 16192 } 16193 if (proc == null) { 16194 return; 16195 } 16196 try { 16197 proc.thread.profilerControl(false, path, null, profileType); 16198 } catch (RemoteException e) { 16199 throw new IllegalStateException("Process disappeared"); 16200 } 16201 } 16202 16203 private void clearProfilerLocked() { 16204 if (mProfileFd != null) { 16205 try { 16206 mProfileFd.close(); 16207 } catch (IOException e) { 16208 } 16209 } 16210 mProfileApp = null; 16211 mProfileProc = null; 16212 mProfileFile = null; 16213 mProfileType = 0; 16214 mAutoStopProfiler = false; 16215 } 16216 16217 public boolean profileControl(String process, int userId, boolean start, 16218 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16219 16220 try { 16221 synchronized (this) { 16222 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16223 // its own permission. 16224 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16225 != PackageManager.PERMISSION_GRANTED) { 16226 throw new SecurityException("Requires permission " 16227 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16228 } 16229 16230 if (start && fd == null) { 16231 throw new IllegalArgumentException("null fd"); 16232 } 16233 16234 ProcessRecord proc = null; 16235 if (process != null) { 16236 proc = findProcessLocked(process, userId, "profileControl"); 16237 } 16238 16239 if (start && (proc == null || proc.thread == null)) { 16240 throw new IllegalArgumentException("Unknown process: " + process); 16241 } 16242 16243 if (start) { 16244 stopProfilerLocked(null, null, 0); 16245 setProfileApp(proc.info, proc.processName, path, fd, false); 16246 mProfileProc = proc; 16247 mProfileType = profileType; 16248 try { 16249 fd = fd.dup(); 16250 } catch (IOException e) { 16251 fd = null; 16252 } 16253 proc.thread.profilerControl(start, path, fd, profileType); 16254 fd = null; 16255 mProfileFd = null; 16256 } else { 16257 stopProfilerLocked(proc, path, profileType); 16258 if (fd != null) { 16259 try { 16260 fd.close(); 16261 } catch (IOException e) { 16262 } 16263 } 16264 } 16265 16266 return true; 16267 } 16268 } catch (RemoteException e) { 16269 throw new IllegalStateException("Process disappeared"); 16270 } finally { 16271 if (fd != null) { 16272 try { 16273 fd.close(); 16274 } catch (IOException e) { 16275 } 16276 } 16277 } 16278 } 16279 16280 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16281 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16282 userId, true, true, callName, null); 16283 ProcessRecord proc = null; 16284 try { 16285 int pid = Integer.parseInt(process); 16286 synchronized (mPidsSelfLocked) { 16287 proc = mPidsSelfLocked.get(pid); 16288 } 16289 } catch (NumberFormatException e) { 16290 } 16291 16292 if (proc == null) { 16293 ArrayMap<String, SparseArray<ProcessRecord>> all 16294 = mProcessNames.getMap(); 16295 SparseArray<ProcessRecord> procs = all.get(process); 16296 if (procs != null && procs.size() > 0) { 16297 proc = procs.valueAt(0); 16298 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16299 for (int i=1; i<procs.size(); i++) { 16300 ProcessRecord thisProc = procs.valueAt(i); 16301 if (thisProc.userId == userId) { 16302 proc = thisProc; 16303 break; 16304 } 16305 } 16306 } 16307 } 16308 } 16309 16310 return proc; 16311 } 16312 16313 public boolean dumpHeap(String process, int userId, boolean managed, 16314 String path, ParcelFileDescriptor fd) throws RemoteException { 16315 16316 try { 16317 synchronized (this) { 16318 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16319 // its own permission (same as profileControl). 16320 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16321 != PackageManager.PERMISSION_GRANTED) { 16322 throw new SecurityException("Requires permission " 16323 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16324 } 16325 16326 if (fd == null) { 16327 throw new IllegalArgumentException("null fd"); 16328 } 16329 16330 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16331 if (proc == null || proc.thread == null) { 16332 throw new IllegalArgumentException("Unknown process: " + process); 16333 } 16334 16335 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16336 if (!isDebuggable) { 16337 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16338 throw new SecurityException("Process not debuggable: " + proc); 16339 } 16340 } 16341 16342 proc.thread.dumpHeap(managed, path, fd); 16343 fd = null; 16344 return true; 16345 } 16346 } catch (RemoteException e) { 16347 throw new IllegalStateException("Process disappeared"); 16348 } finally { 16349 if (fd != null) { 16350 try { 16351 fd.close(); 16352 } catch (IOException e) { 16353 } 16354 } 16355 } 16356 } 16357 16358 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16359 public void monitor() { 16360 synchronized (this) { } 16361 } 16362 16363 void onCoreSettingsChange(Bundle settings) { 16364 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16365 ProcessRecord processRecord = mLruProcesses.get(i); 16366 try { 16367 if (processRecord.thread != null) { 16368 processRecord.thread.setCoreSettings(settings); 16369 } 16370 } catch (RemoteException re) { 16371 /* ignore */ 16372 } 16373 } 16374 } 16375 16376 // Multi-user methods 16377 16378 /** 16379 * Start user, if its not already running, but don't bring it to foreground. 16380 */ 16381 @Override 16382 public boolean startUserInBackground(final int userId) { 16383 return startUser(userId, /* foreground */ false); 16384 } 16385 16386 /** 16387 * Refreshes the list of users related to the current user when either a 16388 * user switch happens or when a new related user is started in the 16389 * background. 16390 */ 16391 private void updateCurrentProfileIdsLocked() { 16392 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16393 mCurrentUserId, false /* enabledOnly */); 16394 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16395 for (int i = 0; i < currentProfileIds.length; i++) { 16396 currentProfileIds[i] = profiles.get(i).id; 16397 } 16398 mCurrentProfileIds = currentProfileIds; 16399 } 16400 16401 private Set getProfileIdsLocked(int userId) { 16402 Set userIds = new HashSet<Integer>(); 16403 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16404 userId, false /* enabledOnly */); 16405 for (UserInfo user : profiles) { 16406 userIds.add(Integer.valueOf(user.id)); 16407 } 16408 return userIds; 16409 } 16410 16411 @Override 16412 public boolean switchUser(final int userId) { 16413 return startUser(userId, /* foregound */ true); 16414 } 16415 16416 private boolean startUser(final int userId, boolean foreground) { 16417 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16418 != PackageManager.PERMISSION_GRANTED) { 16419 String msg = "Permission Denial: switchUser() from pid=" 16420 + Binder.getCallingPid() 16421 + ", uid=" + Binder.getCallingUid() 16422 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16423 Slog.w(TAG, msg); 16424 throw new SecurityException(msg); 16425 } 16426 16427 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16428 16429 final long ident = Binder.clearCallingIdentity(); 16430 try { 16431 synchronized (this) { 16432 final int oldUserId = mCurrentUserId; 16433 if (oldUserId == userId) { 16434 return true; 16435 } 16436 16437 mStackSupervisor.setLockTaskModeLocked(null); 16438 16439 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16440 if (userInfo == null) { 16441 Slog.w(TAG, "No user info for user #" + userId); 16442 return false; 16443 } 16444 16445 if (foreground) { 16446 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16447 R.anim.screen_user_enter); 16448 } 16449 16450 boolean needStart = false; 16451 16452 // If the user we are switching to is not currently started, then 16453 // we need to start it now. 16454 if (mStartedUsers.get(userId) == null) { 16455 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16456 updateStartedUserArrayLocked(); 16457 needStart = true; 16458 } 16459 16460 final Integer userIdInt = Integer.valueOf(userId); 16461 mUserLru.remove(userIdInt); 16462 mUserLru.add(userIdInt); 16463 16464 if (foreground) { 16465 mCurrentUserId = userId; 16466 updateCurrentProfileIdsLocked(); 16467 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16468 // Once the internal notion of the active user has switched, we lock the device 16469 // with the option to show the user switcher on the keyguard. 16470 mWindowManager.lockNow(null); 16471 } else { 16472 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16473 updateCurrentProfileIdsLocked(); 16474 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16475 mUserLru.remove(currentUserIdInt); 16476 mUserLru.add(currentUserIdInt); 16477 } 16478 16479 final UserStartedState uss = mStartedUsers.get(userId); 16480 16481 // Make sure user is in the started state. If it is currently 16482 // stopping, we need to knock that off. 16483 if (uss.mState == UserStartedState.STATE_STOPPING) { 16484 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16485 // so we can just fairly silently bring the user back from 16486 // the almost-dead. 16487 uss.mState = UserStartedState.STATE_RUNNING; 16488 updateStartedUserArrayLocked(); 16489 needStart = true; 16490 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16491 // This means ACTION_SHUTDOWN has been sent, so we will 16492 // need to treat this as a new boot of the user. 16493 uss.mState = UserStartedState.STATE_BOOTING; 16494 updateStartedUserArrayLocked(); 16495 needStart = true; 16496 } 16497 16498 if (uss.mState == UserStartedState.STATE_BOOTING) { 16499 // Booting up a new user, need to tell system services about it. 16500 // Note that this is on the same handler as scheduling of broadcasts, 16501 // which is important because it needs to go first. 16502 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16503 } 16504 16505 if (foreground) { 16506 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16507 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16508 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16509 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16510 oldUserId, userId, uss)); 16511 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16512 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16513 } 16514 16515 if (needStart) { 16516 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16517 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16518 | Intent.FLAG_RECEIVER_FOREGROUND); 16519 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16520 broadcastIntentLocked(null, null, intent, 16521 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16522 false, false, MY_PID, Process.SYSTEM_UID, userId); 16523 } 16524 16525 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16526 if (userId != 0) { 16527 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16528 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16529 broadcastIntentLocked(null, null, intent, null, 16530 new IIntentReceiver.Stub() { 16531 public void performReceive(Intent intent, int resultCode, 16532 String data, Bundle extras, boolean ordered, 16533 boolean sticky, int sendingUser) { 16534 userInitialized(uss, userId); 16535 } 16536 }, 0, null, null, null, AppOpsManager.OP_NONE, 16537 true, false, MY_PID, Process.SYSTEM_UID, 16538 userId); 16539 uss.initializing = true; 16540 } else { 16541 getUserManagerLocked().makeInitialized(userInfo.id); 16542 } 16543 } 16544 16545 if (foreground) { 16546 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16547 if (homeInFront) { 16548 startHomeActivityLocked(userId); 16549 } else { 16550 mStackSupervisor.resumeTopActivitiesLocked(); 16551 } 16552 EventLogTags.writeAmSwitchUser(userId); 16553 getUserManagerLocked().userForeground(userId); 16554 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16555 } 16556 16557 if (needStart) { 16558 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16559 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16560 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16561 broadcastIntentLocked(null, null, intent, 16562 null, new IIntentReceiver.Stub() { 16563 @Override 16564 public void performReceive(Intent intent, int resultCode, String data, 16565 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16566 throws RemoteException { 16567 } 16568 }, 0, null, null, 16569 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16570 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16571 } 16572 } 16573 } finally { 16574 Binder.restoreCallingIdentity(ident); 16575 } 16576 16577 return true; 16578 } 16579 16580 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16581 long ident = Binder.clearCallingIdentity(); 16582 try { 16583 Intent intent; 16584 if (oldUserId >= 0) { 16585 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16586 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16587 | Intent.FLAG_RECEIVER_FOREGROUND); 16588 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16589 broadcastIntentLocked(null, null, intent, 16590 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16591 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16592 } 16593 if (newUserId >= 0) { 16594 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16595 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16596 | Intent.FLAG_RECEIVER_FOREGROUND); 16597 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16598 broadcastIntentLocked(null, null, intent, 16599 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16600 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16601 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16602 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16603 | Intent.FLAG_RECEIVER_FOREGROUND); 16604 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16605 broadcastIntentLocked(null, null, intent, 16606 null, null, 0, null, null, 16607 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16608 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16609 } 16610 } finally { 16611 Binder.restoreCallingIdentity(ident); 16612 } 16613 } 16614 16615 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16616 final int newUserId) { 16617 final int N = mUserSwitchObservers.beginBroadcast(); 16618 if (N > 0) { 16619 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16620 int mCount = 0; 16621 @Override 16622 public void sendResult(Bundle data) throws RemoteException { 16623 synchronized (ActivityManagerService.this) { 16624 if (mCurUserSwitchCallback == this) { 16625 mCount++; 16626 if (mCount == N) { 16627 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16628 } 16629 } 16630 } 16631 } 16632 }; 16633 synchronized (this) { 16634 uss.switching = true; 16635 mCurUserSwitchCallback = callback; 16636 } 16637 for (int i=0; i<N; i++) { 16638 try { 16639 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16640 newUserId, callback); 16641 } catch (RemoteException e) { 16642 } 16643 } 16644 } else { 16645 synchronized (this) { 16646 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16647 } 16648 } 16649 mUserSwitchObservers.finishBroadcast(); 16650 } 16651 16652 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16653 synchronized (this) { 16654 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16655 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16656 } 16657 } 16658 16659 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16660 mCurUserSwitchCallback = null; 16661 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16662 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16663 oldUserId, newUserId, uss)); 16664 } 16665 16666 void userInitialized(UserStartedState uss, int newUserId) { 16667 completeSwitchAndInitalize(uss, newUserId, true, false); 16668 } 16669 16670 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16671 completeSwitchAndInitalize(uss, newUserId, false, true); 16672 } 16673 16674 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16675 boolean clearInitializing, boolean clearSwitching) { 16676 boolean unfrozen = false; 16677 synchronized (this) { 16678 if (clearInitializing) { 16679 uss.initializing = false; 16680 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16681 } 16682 if (clearSwitching) { 16683 uss.switching = false; 16684 } 16685 if (!uss.switching && !uss.initializing) { 16686 mWindowManager.stopFreezingScreen(); 16687 unfrozen = true; 16688 } 16689 } 16690 if (unfrozen) { 16691 final int N = mUserSwitchObservers.beginBroadcast(); 16692 for (int i=0; i<N; i++) { 16693 try { 16694 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16695 } catch (RemoteException e) { 16696 } 16697 } 16698 mUserSwitchObservers.finishBroadcast(); 16699 } 16700 } 16701 16702 void scheduleStartProfilesLocked() { 16703 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16704 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16705 DateUtils.SECOND_IN_MILLIS); 16706 } 16707 } 16708 16709 void startProfilesLocked() { 16710 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16711 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16712 mCurrentUserId, false /* enabledOnly */); 16713 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16714 for (UserInfo user : profiles) { 16715 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16716 && user.id != mCurrentUserId) { 16717 toStart.add(user); 16718 } 16719 } 16720 final int n = toStart.size(); 16721 int i = 0; 16722 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16723 startUserInBackground(toStart.get(i).id); 16724 } 16725 if (i < n) { 16726 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16727 } 16728 } 16729 16730 void finishUserSwitch(UserStartedState uss) { 16731 synchronized (this) { 16732 if (uss.mState == UserStartedState.STATE_BOOTING 16733 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16734 uss.mState = UserStartedState.STATE_RUNNING; 16735 final int userId = uss.mHandle.getIdentifier(); 16736 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16737 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16738 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16739 broadcastIntentLocked(null, null, intent, 16740 null, null, 0, null, null, 16741 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16742 true, false, MY_PID, Process.SYSTEM_UID, userId); 16743 } 16744 16745 startProfilesLocked(); 16746 16747 int num = mUserLru.size(); 16748 int i = 0; 16749 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16750 Integer oldUserId = mUserLru.get(i); 16751 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16752 if (oldUss == null) { 16753 // Shouldn't happen, but be sane if it does. 16754 mUserLru.remove(i); 16755 num--; 16756 continue; 16757 } 16758 if (oldUss.mState == UserStartedState.STATE_STOPPING 16759 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16760 // This user is already stopping, doesn't count. 16761 num--; 16762 i++; 16763 continue; 16764 } 16765 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16766 // Owner and current can't be stopped, but count as running. 16767 i++; 16768 continue; 16769 } 16770 // This is a user to be stopped. 16771 stopUserLocked(oldUserId, null); 16772 num--; 16773 i++; 16774 } 16775 } 16776 } 16777 16778 @Override 16779 public int stopUser(final int userId, final IStopUserCallback callback) { 16780 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16781 != PackageManager.PERMISSION_GRANTED) { 16782 String msg = "Permission Denial: switchUser() from pid=" 16783 + Binder.getCallingPid() 16784 + ", uid=" + Binder.getCallingUid() 16785 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16786 Slog.w(TAG, msg); 16787 throw new SecurityException(msg); 16788 } 16789 if (userId <= 0) { 16790 throw new IllegalArgumentException("Can't stop primary user " + userId); 16791 } 16792 synchronized (this) { 16793 return stopUserLocked(userId, callback); 16794 } 16795 } 16796 16797 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16798 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16799 if (mCurrentUserId == userId) { 16800 return ActivityManager.USER_OP_IS_CURRENT; 16801 } 16802 16803 final UserStartedState uss = mStartedUsers.get(userId); 16804 if (uss == null) { 16805 // User is not started, nothing to do... but we do need to 16806 // callback if requested. 16807 if (callback != null) { 16808 mHandler.post(new Runnable() { 16809 @Override 16810 public void run() { 16811 try { 16812 callback.userStopped(userId); 16813 } catch (RemoteException e) { 16814 } 16815 } 16816 }); 16817 } 16818 return ActivityManager.USER_OP_SUCCESS; 16819 } 16820 16821 if (callback != null) { 16822 uss.mStopCallbacks.add(callback); 16823 } 16824 16825 if (uss.mState != UserStartedState.STATE_STOPPING 16826 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16827 uss.mState = UserStartedState.STATE_STOPPING; 16828 updateStartedUserArrayLocked(); 16829 16830 long ident = Binder.clearCallingIdentity(); 16831 try { 16832 // We are going to broadcast ACTION_USER_STOPPING and then 16833 // once that is done send a final ACTION_SHUTDOWN and then 16834 // stop the user. 16835 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16836 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16837 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16838 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16839 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16840 // This is the result receiver for the final shutdown broadcast. 16841 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16842 @Override 16843 public void performReceive(Intent intent, int resultCode, String data, 16844 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16845 finishUserStop(uss); 16846 } 16847 }; 16848 // This is the result receiver for the initial stopping broadcast. 16849 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16850 @Override 16851 public void performReceive(Intent intent, int resultCode, String data, 16852 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16853 // On to the next. 16854 synchronized (ActivityManagerService.this) { 16855 if (uss.mState != UserStartedState.STATE_STOPPING) { 16856 // Whoops, we are being started back up. Abort, abort! 16857 return; 16858 } 16859 uss.mState = UserStartedState.STATE_SHUTDOWN; 16860 } 16861 mSystemServiceManager.stopUser(userId); 16862 broadcastIntentLocked(null, null, shutdownIntent, 16863 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16864 true, false, MY_PID, Process.SYSTEM_UID, userId); 16865 } 16866 }; 16867 // Kick things off. 16868 broadcastIntentLocked(null, null, stoppingIntent, 16869 null, stoppingReceiver, 0, null, null, 16870 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16871 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16872 } finally { 16873 Binder.restoreCallingIdentity(ident); 16874 } 16875 } 16876 16877 return ActivityManager.USER_OP_SUCCESS; 16878 } 16879 16880 void finishUserStop(UserStartedState uss) { 16881 final int userId = uss.mHandle.getIdentifier(); 16882 boolean stopped; 16883 ArrayList<IStopUserCallback> callbacks; 16884 synchronized (this) { 16885 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16886 if (mStartedUsers.get(userId) != uss) { 16887 stopped = false; 16888 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16889 stopped = false; 16890 } else { 16891 stopped = true; 16892 // User can no longer run. 16893 mStartedUsers.remove(userId); 16894 mUserLru.remove(Integer.valueOf(userId)); 16895 updateStartedUserArrayLocked(); 16896 16897 // Clean up all state and processes associated with the user. 16898 // Kill all the processes for the user. 16899 forceStopUserLocked(userId, "finish user"); 16900 } 16901 } 16902 16903 for (int i=0; i<callbacks.size(); i++) { 16904 try { 16905 if (stopped) callbacks.get(i).userStopped(userId); 16906 else callbacks.get(i).userStopAborted(userId); 16907 } catch (RemoteException e) { 16908 } 16909 } 16910 16911 if (stopped) { 16912 mSystemServiceManager.cleanupUser(userId); 16913 synchronized (this) { 16914 mStackSupervisor.removeUserLocked(userId); 16915 } 16916 } 16917 } 16918 16919 @Override 16920 public UserInfo getCurrentUser() { 16921 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16922 != PackageManager.PERMISSION_GRANTED) && ( 16923 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16924 != PackageManager.PERMISSION_GRANTED)) { 16925 String msg = "Permission Denial: getCurrentUser() from pid=" 16926 + Binder.getCallingPid() 16927 + ", uid=" + Binder.getCallingUid() 16928 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16929 Slog.w(TAG, msg); 16930 throw new SecurityException(msg); 16931 } 16932 synchronized (this) { 16933 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16934 } 16935 } 16936 16937 int getCurrentUserIdLocked() { 16938 return mCurrentUserId; 16939 } 16940 16941 @Override 16942 public boolean isUserRunning(int userId, boolean orStopped) { 16943 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16944 != PackageManager.PERMISSION_GRANTED) { 16945 String msg = "Permission Denial: isUserRunning() from pid=" 16946 + Binder.getCallingPid() 16947 + ", uid=" + Binder.getCallingUid() 16948 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16949 Slog.w(TAG, msg); 16950 throw new SecurityException(msg); 16951 } 16952 synchronized (this) { 16953 return isUserRunningLocked(userId, orStopped); 16954 } 16955 } 16956 16957 boolean isUserRunningLocked(int userId, boolean orStopped) { 16958 UserStartedState state = mStartedUsers.get(userId); 16959 if (state == null) { 16960 return false; 16961 } 16962 if (orStopped) { 16963 return true; 16964 } 16965 return state.mState != UserStartedState.STATE_STOPPING 16966 && state.mState != UserStartedState.STATE_SHUTDOWN; 16967 } 16968 16969 @Override 16970 public int[] getRunningUserIds() { 16971 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16972 != PackageManager.PERMISSION_GRANTED) { 16973 String msg = "Permission Denial: isUserRunning() from pid=" 16974 + Binder.getCallingPid() 16975 + ", uid=" + Binder.getCallingUid() 16976 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16977 Slog.w(TAG, msg); 16978 throw new SecurityException(msg); 16979 } 16980 synchronized (this) { 16981 return mStartedUserArray; 16982 } 16983 } 16984 16985 private void updateStartedUserArrayLocked() { 16986 int num = 0; 16987 for (int i=0; i<mStartedUsers.size(); i++) { 16988 UserStartedState uss = mStartedUsers.valueAt(i); 16989 // This list does not include stopping users. 16990 if (uss.mState != UserStartedState.STATE_STOPPING 16991 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16992 num++; 16993 } 16994 } 16995 mStartedUserArray = new int[num]; 16996 num = 0; 16997 for (int i=0; i<mStartedUsers.size(); i++) { 16998 UserStartedState uss = mStartedUsers.valueAt(i); 16999 if (uss.mState != UserStartedState.STATE_STOPPING 17000 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17001 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17002 num++; 17003 } 17004 } 17005 } 17006 17007 @Override 17008 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17009 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17010 != PackageManager.PERMISSION_GRANTED) { 17011 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17012 + Binder.getCallingPid() 17013 + ", uid=" + Binder.getCallingUid() 17014 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 17015 Slog.w(TAG, msg); 17016 throw new SecurityException(msg); 17017 } 17018 17019 mUserSwitchObservers.register(observer); 17020 } 17021 17022 @Override 17023 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17024 mUserSwitchObservers.unregister(observer); 17025 } 17026 17027 private boolean userExists(int userId) { 17028 if (userId == 0) { 17029 return true; 17030 } 17031 UserManagerService ums = getUserManagerLocked(); 17032 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17033 } 17034 17035 int[] getUsersLocked() { 17036 UserManagerService ums = getUserManagerLocked(); 17037 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17038 } 17039 17040 UserManagerService getUserManagerLocked() { 17041 if (mUserManager == null) { 17042 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17043 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17044 } 17045 return mUserManager; 17046 } 17047 17048 private int applyUserId(int uid, int userId) { 17049 return UserHandle.getUid(userId, uid); 17050 } 17051 17052 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17053 if (info == null) return null; 17054 ApplicationInfo newInfo = new ApplicationInfo(info); 17055 newInfo.uid = applyUserId(info.uid, userId); 17056 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17057 + info.packageName; 17058 return newInfo; 17059 } 17060 17061 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17062 if (aInfo == null 17063 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17064 return aInfo; 17065 } 17066 17067 ActivityInfo info = new ActivityInfo(aInfo); 17068 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17069 return info; 17070 } 17071 17072 private final class LocalService extends ActivityManagerInternal { 17073 @Override 17074 public void goingToSleep() { 17075 ActivityManagerService.this.goingToSleep(); 17076 } 17077 17078 @Override 17079 public void wakingUp() { 17080 ActivityManagerService.this.wakingUp(); 17081 } 17082 } 17083} 17084