ActivityManagerService.java revision 648c83b4ee5fe825aa4032e0bb32c1d6269b02ad
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.IThumbnailReceiver; 99import android.app.IUiAutomationConnection; 100import android.app.IUserSwitchObserver; 101import android.app.Instrumentation; 102import android.app.Notification; 103import android.app.NotificationManager; 104import android.app.PendingIntent; 105import android.app.backup.IBackupManager; 106import android.content.ActivityNotFoundException; 107import android.content.BroadcastReceiver; 108import android.content.ClipData; 109import android.content.ComponentCallbacks2; 110import android.content.ComponentName; 111import android.content.ContentProvider; 112import android.content.ContentResolver; 113import android.content.Context; 114import android.content.DialogInterface; 115import android.content.IContentProvider; 116import android.content.IIntentReceiver; 117import android.content.IIntentSender; 118import android.content.Intent; 119import android.content.IntentFilter; 120import android.content.IntentSender; 121import android.content.pm.ActivityInfo; 122import android.content.pm.ApplicationInfo; 123import android.content.pm.ConfigurationInfo; 124import android.content.pm.IPackageDataObserver; 125import android.content.pm.IPackageManager; 126import android.content.pm.InstrumentationInfo; 127import android.content.pm.PackageInfo; 128import android.content.pm.PackageManager; 129import android.content.pm.ParceledListSlice; 130import android.content.pm.UserInfo; 131import android.content.pm.PackageManager.NameNotFoundException; 132import android.content.pm.PathPermission; 133import android.content.pm.ProviderInfo; 134import android.content.pm.ResolveInfo; 135import android.content.pm.ServiceInfo; 136import android.content.res.CompatibilityInfo; 137import android.content.res.Configuration; 138import android.graphics.Bitmap; 139import android.net.Proxy; 140import android.net.ProxyProperties; 141import android.net.Uri; 142import android.os.Binder; 143import android.os.Build; 144import android.os.Bundle; 145import android.os.Debug; 146import android.os.DropBoxManager; 147import android.os.Environment; 148import android.os.FactoryTest; 149import android.os.FileObserver; 150import android.os.FileUtils; 151import android.os.Handler; 152import android.os.IBinder; 153import android.os.IPermissionController; 154import android.os.IRemoteCallback; 155import android.os.IUserManager; 156import android.os.Looper; 157import android.os.Message; 158import android.os.Parcel; 159import android.os.ParcelFileDescriptor; 160import android.os.Process; 161import android.os.RemoteCallbackList; 162import android.os.RemoteException; 163import android.os.SELinux; 164import android.os.ServiceManager; 165import android.os.StrictMode; 166import android.os.SystemClock; 167import android.os.SystemProperties; 168import android.os.UpdateLock; 169import android.os.UserHandle; 170import android.provider.Settings; 171import android.text.format.DateUtils; 172import android.text.format.Time; 173import android.util.AtomicFile; 174import android.util.EventLog; 175import android.util.Log; 176import android.util.Pair; 177import android.util.PrintWriterPrinter; 178import android.util.Slog; 179import android.util.SparseArray; 180import android.util.TimeUtils; 181import android.util.Xml; 182import android.view.Gravity; 183import android.view.LayoutInflater; 184import android.view.View; 185import android.view.WindowManager; 186 187import java.io.BufferedInputStream; 188import java.io.BufferedOutputStream; 189import java.io.DataInputStream; 190import java.io.DataOutputStream; 191import java.io.File; 192import java.io.FileDescriptor; 193import java.io.FileInputStream; 194import java.io.FileNotFoundException; 195import java.io.FileOutputStream; 196import java.io.IOException; 197import java.io.InputStreamReader; 198import java.io.PrintWriter; 199import java.io.StringWriter; 200import java.lang.ref.WeakReference; 201import java.util.ArrayList; 202import java.util.Arrays; 203import java.util.Collections; 204import java.util.Comparator; 205import java.util.HashMap; 206import java.util.HashSet; 207import java.util.Iterator; 208import java.util.List; 209import java.util.Locale; 210import java.util.Map; 211import java.util.Set; 212import java.util.concurrent.atomic.AtomicBoolean; 213import java.util.concurrent.atomic.AtomicLong; 214 215public final class ActivityManagerService extends ActivityManagerNative 216 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 217 private static final String USER_DATA_DIR = "/data/user/"; 218 static final String TAG = "ActivityManager"; 219 static final String TAG_MU = "ActivityManagerServiceMU"; 220 static final boolean DEBUG = false; 221 static final boolean localLOGV = DEBUG; 222 static final boolean DEBUG_BACKUP = localLOGV || false; 223 static final boolean DEBUG_BROADCAST = localLOGV || false; 224 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 225 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 226 static final boolean DEBUG_CLEANUP = localLOGV || false; 227 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 228 static final boolean DEBUG_FOCUS = false; 229 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 230 static final boolean DEBUG_MU = localLOGV || false; 231 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 232 static final boolean DEBUG_LRU = localLOGV || false; 233 static final boolean DEBUG_PAUSE = localLOGV || false; 234 static final boolean DEBUG_POWER = localLOGV || false; 235 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 236 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 237 static final boolean DEBUG_PROCESSES = localLOGV || false; 238 static final boolean DEBUG_PROVIDER = localLOGV || false; 239 static final boolean DEBUG_RESULTS = localLOGV || false; 240 static final boolean DEBUG_SERVICE = localLOGV || false; 241 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 242 static final boolean DEBUG_STACK = localLOGV || false; 243 static final boolean DEBUG_SWITCH = localLOGV || false; 244 static final boolean DEBUG_TASKS = localLOGV || false; 245 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 246 static final boolean DEBUG_TRANSITION = localLOGV || false; 247 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 248 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 249 static final boolean DEBUG_VISBILITY = localLOGV || false; 250 static final boolean DEBUG_PSS = localLOGV || false; 251 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 252 static final boolean VALIDATE_TOKENS = false; 253 static final boolean SHOW_ACTIVITY_START_TIME = true; 254 255 // Control over CPU and battery monitoring. 256 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 257 static final boolean MONITOR_CPU_USAGE = true; 258 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 259 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 260 static final boolean MONITOR_THREAD_CPU_USAGE = false; 261 262 // The flags that are set for all calls we make to the package manager. 263 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 264 265 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 266 267 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 268 269 // Maximum number of recent tasks that we can remember. 270 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 271 272 // Amount of time after a call to stopAppSwitches() during which we will 273 // prevent further untrusted switches from happening. 274 static final long APP_SWITCH_DELAY_TIME = 5*1000; 275 276 // How long we wait for a launched process to attach to the activity manager 277 // before we decide it's never going to come up for real. 278 static final int PROC_START_TIMEOUT = 10*1000; 279 280 // How long we wait for a launched process to attach to the activity manager 281 // before we decide it's never going to come up for real, when the process was 282 // started with a wrapper for instrumentation (such as Valgrind) because it 283 // could take much longer than usual. 284 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 285 286 // How long to wait after going idle before forcing apps to GC. 287 static final int GC_TIMEOUT = 5*1000; 288 289 // The minimum amount of time between successive GC requests for a process. 290 static final int GC_MIN_INTERVAL = 60*1000; 291 292 // The minimum amount of time between successive PSS requests for a process. 293 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 294 295 // The minimum amount of time between successive PSS requests for a process 296 // when the request is due to the memory state being lowered. 297 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 298 299 // The rate at which we check for apps using excessive power -- 15 mins. 300 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 301 302 // The minimum sample duration we will allow before deciding we have 303 // enough data on wake locks to start killing things. 304 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 305 306 // The minimum sample duration we will allow before deciding we have 307 // enough data on CPU usage to start killing things. 308 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 309 310 // How long we allow a receiver to run before giving up on it. 311 static final int BROADCAST_FG_TIMEOUT = 10*1000; 312 static final int BROADCAST_BG_TIMEOUT = 60*1000; 313 314 // How long we wait until we timeout on key dispatching. 315 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 316 317 // How long we wait until we timeout on key dispatching during instrumentation. 318 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 319 320 // Amount of time we wait for observers to handle a user switch before 321 // giving up on them and unfreezing the screen. 322 static final int USER_SWITCH_TIMEOUT = 2*1000; 323 324 // Maximum number of users we allow to be running at a time. 325 static final int MAX_RUNNING_USERS = 3; 326 327 // How long to wait in getAssistContextExtras for the activity and foreground services 328 // to respond with the result. 329 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 330 331 // Maximum number of persisted Uri grants a package is allowed 332 static final int MAX_PERSISTED_URI_GRANTS = 128; 333 334 static final int MY_PID = Process.myPid(); 335 336 static final String[] EMPTY_STRING_ARRAY = new String[0]; 337 338 // How many bytes to write into the dropbox log before truncating 339 static final int DROPBOX_MAX_SIZE = 256 * 1024; 340 341 /** All system services */ 342 SystemServiceManager mSystemServiceManager; 343 344 /** Run all ActivityStacks through this */ 345 ActivityStackSupervisor mStackSupervisor; 346 347 public IntentFirewall mIntentFirewall; 348 349 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 350 // default actuion automatically. Important for devices without direct input 351 // devices. 352 private boolean mShowDialogs = true; 353 354 /** 355 * Description of a request to start a new activity, which has been held 356 * due to app switches being disabled. 357 */ 358 static class PendingActivityLaunch { 359 final ActivityRecord r; 360 final ActivityRecord sourceRecord; 361 final int startFlags; 362 final ActivityStack stack; 363 364 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 365 int _startFlags, ActivityStack _stack) { 366 r = _r; 367 sourceRecord = _sourceRecord; 368 startFlags = _startFlags; 369 stack = _stack; 370 } 371 } 372 373 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 374 = new ArrayList<PendingActivityLaunch>(); 375 376 BroadcastQueue mFgBroadcastQueue; 377 BroadcastQueue mBgBroadcastQueue; 378 // Convenient for easy iteration over the queues. Foreground is first 379 // so that dispatch of foreground broadcasts gets precedence. 380 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 381 382 BroadcastQueue broadcastQueueForIntent(Intent intent) { 383 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 384 if (DEBUG_BACKGROUND_BROADCAST) { 385 Slog.i(TAG, "Broadcast intent " + intent + " on " 386 + (isFg ? "foreground" : "background") 387 + " queue"); 388 } 389 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 390 } 391 392 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 393 for (BroadcastQueue queue : mBroadcastQueues) { 394 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 395 if (r != null) { 396 return r; 397 } 398 } 399 return null; 400 } 401 402 /** 403 * Activity we have told the window manager to have key focus. 404 */ 405 ActivityRecord mFocusedActivity = null; 406 407 /** 408 * List of intents that were used to start the most recent tasks. 409 */ 410 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 411 412 public class PendingAssistExtras extends Binder implements Runnable { 413 public final ActivityRecord activity; 414 public boolean haveResult = false; 415 public Bundle result = null; 416 public PendingAssistExtras(ActivityRecord _activity) { 417 activity = _activity; 418 } 419 @Override 420 public void run() { 421 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 422 synchronized (this) { 423 haveResult = true; 424 notifyAll(); 425 } 426 } 427 } 428 429 final ArrayList<PendingAssistExtras> mPendingAssistExtras 430 = new ArrayList<PendingAssistExtras>(); 431 432 /** 433 * Process management. 434 */ 435 final ProcessList mProcessList = new ProcessList(); 436 437 /** 438 * All of the applications we currently have running organized by name. 439 * The keys are strings of the application package name (as 440 * returned by the package manager), and the keys are ApplicationRecord 441 * objects. 442 */ 443 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 444 445 /** 446 * Tracking long-term execution of processes to look for abuse and other 447 * bad app behavior. 448 */ 449 final ProcessStatsService mProcessStats; 450 451 /** 452 * The currently running isolated processes. 453 */ 454 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 455 456 /** 457 * Counter for assigning isolated process uids, to avoid frequently reusing the 458 * same ones. 459 */ 460 int mNextIsolatedProcessUid = 0; 461 462 /** 463 * The currently running heavy-weight process, if any. 464 */ 465 ProcessRecord mHeavyWeightProcess = null; 466 467 /** 468 * The last time that various processes have crashed. 469 */ 470 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 471 472 /** 473 * Information about a process that is currently marked as bad. 474 */ 475 static final class BadProcessInfo { 476 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 477 this.time = time; 478 this.shortMsg = shortMsg; 479 this.longMsg = longMsg; 480 this.stack = stack; 481 } 482 483 final long time; 484 final String shortMsg; 485 final String longMsg; 486 final String stack; 487 } 488 489 /** 490 * Set of applications that we consider to be bad, and will reject 491 * incoming broadcasts from (which the user has no control over). 492 * Processes are added to this set when they have crashed twice within 493 * a minimum amount of time; they are removed from it when they are 494 * later restarted (hopefully due to some user action). The value is the 495 * time it was added to the list. 496 */ 497 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 498 499 /** 500 * All of the processes we currently have running organized by pid. 501 * The keys are the pid running the application. 502 * 503 * <p>NOTE: This object is protected by its own lock, NOT the global 504 * activity manager lock! 505 */ 506 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 507 508 /** 509 * All of the processes that have been forced to be foreground. The key 510 * is the pid of the caller who requested it (we hold a death 511 * link on it). 512 */ 513 abstract class ForegroundToken implements IBinder.DeathRecipient { 514 int pid; 515 IBinder token; 516 } 517 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 518 519 /** 520 * List of records for processes that someone had tried to start before the 521 * system was ready. We don't start them at that point, but ensure they 522 * are started by the time booting is complete. 523 */ 524 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 525 526 /** 527 * List of persistent applications that are in the process 528 * of being started. 529 */ 530 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 531 532 /** 533 * Processes that are being forcibly torn down. 534 */ 535 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 536 537 /** 538 * List of running applications, sorted by recent usage. 539 * The first entry in the list is the least recently used. 540 */ 541 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 542 543 /** 544 * Where in mLruProcesses that the processes hosting activities start. 545 */ 546 int mLruProcessActivityStart = 0; 547 548 /** 549 * Where in mLruProcesses that the processes hosting services start. 550 * This is after (lower index) than mLruProcessesActivityStart. 551 */ 552 int mLruProcessServiceStart = 0; 553 554 /** 555 * List of processes that should gc as soon as things are idle. 556 */ 557 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 558 559 /** 560 * Processes we want to collect PSS data from. 561 */ 562 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 563 564 /** 565 * Last time we requested PSS data of all processes. 566 */ 567 long mLastFullPssTime = SystemClock.uptimeMillis(); 568 569 /** 570 * This is the process holding what we currently consider to be 571 * the "home" activity. 572 */ 573 ProcessRecord mHomeProcess; 574 575 /** 576 * This is the process holding the activity the user last visited that 577 * is in a different process from the one they are currently in. 578 */ 579 ProcessRecord mPreviousProcess; 580 581 /** 582 * The time at which the previous process was last visible. 583 */ 584 long mPreviousProcessVisibleTime; 585 586 /** 587 * Which uses have been started, so are allowed to run code. 588 */ 589 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 590 591 /** 592 * LRU list of history of current users. Most recently current is at the end. 593 */ 594 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 595 596 /** 597 * Constant array of the users that are currently started. 598 */ 599 int[] mStartedUserArray = new int[] { 0 }; 600 601 /** 602 * Registered observers of the user switching mechanics. 603 */ 604 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 605 = new RemoteCallbackList<IUserSwitchObserver>(); 606 607 /** 608 * Currently active user switch. 609 */ 610 Object mCurUserSwitchCallback; 611 612 /** 613 * Packages that the user has asked to have run in screen size 614 * compatibility mode instead of filling the screen. 615 */ 616 final CompatModePackages mCompatModePackages; 617 618 /** 619 * Set of IntentSenderRecord objects that are currently active. 620 */ 621 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 622 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 623 624 /** 625 * Fingerprints (hashCode()) of stack traces that we've 626 * already logged DropBox entries for. Guarded by itself. If 627 * something (rogue user app) forces this over 628 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 629 */ 630 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 631 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 632 633 /** 634 * Strict Mode background batched logging state. 635 * 636 * The string buffer is guarded by itself, and its lock is also 637 * used to determine if another batched write is already 638 * in-flight. 639 */ 640 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 641 642 /** 643 * Keeps track of all IIntentReceivers that have been registered for 644 * broadcasts. Hash keys are the receiver IBinder, hash value is 645 * a ReceiverList. 646 */ 647 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 648 new HashMap<IBinder, ReceiverList>(); 649 650 /** 651 * Resolver for broadcast intents to registered receivers. 652 * Holds BroadcastFilter (subclass of IntentFilter). 653 */ 654 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 655 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 656 @Override 657 protected boolean allowFilterResult( 658 BroadcastFilter filter, List<BroadcastFilter> dest) { 659 IBinder target = filter.receiverList.receiver.asBinder(); 660 for (int i=dest.size()-1; i>=0; i--) { 661 if (dest.get(i).receiverList.receiver.asBinder() == target) { 662 return false; 663 } 664 } 665 return true; 666 } 667 668 @Override 669 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 670 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 671 || userId == filter.owningUserId) { 672 return super.newResult(filter, match, userId); 673 } 674 return null; 675 } 676 677 @Override 678 protected BroadcastFilter[] newArray(int size) { 679 return new BroadcastFilter[size]; 680 } 681 682 @Override 683 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 684 return packageName.equals(filter.packageName); 685 } 686 }; 687 688 /** 689 * State of all active sticky broadcasts per user. Keys are the action of the 690 * sticky Intent, values are an ArrayList of all broadcasted intents with 691 * that action (which should usually be one). The SparseArray is keyed 692 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 693 * for stickies that are sent to all users. 694 */ 695 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 696 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 697 698 final ActiveServices mServices; 699 700 /** 701 * Backup/restore process management 702 */ 703 String mBackupAppName = null; 704 BackupRecord mBackupTarget = null; 705 706 /** 707 * List of PendingThumbnailsRecord objects of clients who are still 708 * waiting to receive all of the thumbnails for a task. 709 */ 710 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 711 new ArrayList<PendingThumbnailsRecord>(); 712 713 final ProviderMap mProviderMap; 714 715 /** 716 * List of content providers who have clients waiting for them. The 717 * application is currently being launched and the provider will be 718 * removed from this list once it is published. 719 */ 720 final ArrayList<ContentProviderRecord> mLaunchingProviders 721 = new ArrayList<ContentProviderRecord>(); 722 723 /** 724 * File storing persisted {@link #mGrantedUriPermissions}. 725 */ 726 private final AtomicFile mGrantFile; 727 728 /** XML constants used in {@link #mGrantFile} */ 729 private static final String TAG_URI_GRANTS = "uri-grants"; 730 private static final String TAG_URI_GRANT = "uri-grant"; 731 private static final String ATTR_USER_HANDLE = "userHandle"; 732 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 733 private static final String ATTR_TARGET_PKG = "targetPkg"; 734 private static final String ATTR_URI = "uri"; 735 private static final String ATTR_MODE_FLAGS = "modeFlags"; 736 private static final String ATTR_CREATED_TIME = "createdTime"; 737 private static final String ATTR_PREFIX = "prefix"; 738 739 /** 740 * Global set of specific {@link Uri} permissions that have been granted. 741 * This optimized lookup structure maps from {@link UriPermission#targetUid} 742 * to {@link UriPermission#uri} to {@link UriPermission}. 743 */ 744 @GuardedBy("this") 745 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 746 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 747 748 public static class GrantUri { 749 public final Uri uri; 750 public final boolean prefix; 751 752 public GrantUri(Uri uri, boolean prefix) { 753 this.uri = uri; 754 this.prefix = prefix; 755 } 756 757 @Override 758 public int hashCode() { 759 return toString().hashCode(); 760 } 761 762 @Override 763 public boolean equals(Object o) { 764 if (o instanceof GrantUri) { 765 GrantUri other = (GrantUri) o; 766 return uri.equals(other.uri) && prefix == other.prefix; 767 } 768 return false; 769 } 770 771 @Override 772 public String toString() { 773 if (prefix) { 774 return uri.toString() + " [prefix]"; 775 } else { 776 return uri.toString(); 777 } 778 } 779 } 780 781 CoreSettingsObserver mCoreSettingsObserver; 782 783 /** 784 * Thread-local storage used to carry caller permissions over through 785 * indirect content-provider access. 786 */ 787 private class Identity { 788 public int pid; 789 public int uid; 790 791 Identity(int _pid, int _uid) { 792 pid = _pid; 793 uid = _uid; 794 } 795 } 796 797 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 798 799 /** 800 * All information we have collected about the runtime performance of 801 * any user id that can impact battery performance. 802 */ 803 final BatteryStatsService mBatteryStatsService; 804 805 /** 806 * Information about component usage 807 */ 808 final UsageStatsService mUsageStatsService; 809 810 /** 811 * Information about and control over application operations 812 */ 813 final AppOpsService mAppOpsService; 814 815 /** 816 * Current configuration information. HistoryRecord objects are given 817 * a reference to this object to indicate which configuration they are 818 * currently running in, so this object must be kept immutable. 819 */ 820 Configuration mConfiguration = new Configuration(); 821 822 /** 823 * Current sequencing integer of the configuration, for skipping old 824 * configurations. 825 */ 826 int mConfigurationSeq = 0; 827 828 /** 829 * Hardware-reported OpenGLES version. 830 */ 831 final int GL_ES_VERSION; 832 833 /** 834 * List of initialization arguments to pass to all processes when binding applications to them. 835 * For example, references to the commonly used services. 836 */ 837 HashMap<String, IBinder> mAppBindArgs; 838 839 /** 840 * Temporary to avoid allocations. Protected by main lock. 841 */ 842 final StringBuilder mStringBuilder = new StringBuilder(256); 843 844 /** 845 * Used to control how we initialize the service. 846 */ 847 ComponentName mTopComponent; 848 String mTopAction = Intent.ACTION_MAIN; 849 String mTopData; 850 boolean mProcessesReady = false; 851 boolean mSystemReady = false; 852 boolean mBooting = false; 853 boolean mWaitingUpdate = false; 854 boolean mDidUpdate = false; 855 boolean mOnBattery = false; 856 boolean mLaunchWarningShown = false; 857 858 Context mContext; 859 860 int mFactoryTest; 861 862 boolean mCheckedForSetup; 863 864 /** 865 * The time at which we will allow normal application switches again, 866 * after a call to {@link #stopAppSwitches()}. 867 */ 868 long mAppSwitchesAllowedTime; 869 870 /** 871 * This is set to true after the first switch after mAppSwitchesAllowedTime 872 * is set; any switches after that will clear the time. 873 */ 874 boolean mDidAppSwitch; 875 876 /** 877 * Last time (in realtime) at which we checked for power usage. 878 */ 879 long mLastPowerCheckRealtime; 880 881 /** 882 * Last time (in uptime) at which we checked for power usage. 883 */ 884 long mLastPowerCheckUptime; 885 886 /** 887 * Set while we are wanting to sleep, to prevent any 888 * activities from being started/resumed. 889 */ 890 private boolean mSleeping = false; 891 892 /** 893 * Set while we are running a voice interaction. This overrides 894 * sleeping while it is active. 895 */ 896 private boolean mRunningVoice = false; 897 898 /** 899 * State of external calls telling us if the device is asleep. 900 */ 901 private boolean mWentToSleep = false; 902 903 /** 904 * State of external call telling us if the lock screen is shown. 905 */ 906 private boolean mLockScreenShown = false; 907 908 /** 909 * Set if we are shutting down the system, similar to sleeping. 910 */ 911 boolean mShuttingDown = false; 912 913 /** 914 * Current sequence id for oom_adj computation traversal. 915 */ 916 int mAdjSeq = 0; 917 918 /** 919 * Current sequence id for process LRU updating. 920 */ 921 int mLruSeq = 0; 922 923 /** 924 * Keep track of the non-cached/empty process we last found, to help 925 * determine how to distribute cached/empty processes next time. 926 */ 927 int mNumNonCachedProcs = 0; 928 929 /** 930 * Keep track of the number of cached hidden procs, to balance oom adj 931 * distribution between those and empty procs. 932 */ 933 int mNumCachedHiddenProcs = 0; 934 935 /** 936 * Keep track of the number of service processes we last found, to 937 * determine on the next iteration which should be B services. 938 */ 939 int mNumServiceProcs = 0; 940 int mNewNumAServiceProcs = 0; 941 int mNewNumServiceProcs = 0; 942 943 /** 944 * Allow the current computed overall memory level of the system to go down? 945 * This is set to false when we are killing processes for reasons other than 946 * memory management, so that the now smaller process list will not be taken as 947 * an indication that memory is tighter. 948 */ 949 boolean mAllowLowerMemLevel = false; 950 951 /** 952 * The last computed memory level, for holding when we are in a state that 953 * processes are going away for other reasons. 954 */ 955 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 956 957 /** 958 * The last total number of process we have, to determine if changes actually look 959 * like a shrinking number of process due to lower RAM. 960 */ 961 int mLastNumProcesses; 962 963 /** 964 * The uptime of the last time we performed idle maintenance. 965 */ 966 long mLastIdleTime = SystemClock.uptimeMillis(); 967 968 /** 969 * Total time spent with RAM that has been added in the past since the last idle time. 970 */ 971 long mLowRamTimeSinceLastIdle = 0; 972 973 /** 974 * If RAM is currently low, when that horrible situation started. 975 */ 976 long mLowRamStartTime = 0; 977 978 /** 979 * For reporting to battery stats the current top application. 980 */ 981 private String mCurResumedPackage = null; 982 private int mCurResumedUid = -1; 983 984 /** 985 * For reporting to battery stats the apps currently running foreground 986 * service. The ProcessMap is package/uid tuples; each of these contain 987 * an array of the currently foreground processes. 988 */ 989 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 990 = new ProcessMap<ArrayList<ProcessRecord>>(); 991 992 /** 993 * This is set if we had to do a delayed dexopt of an app before launching 994 * it, to increasing the ANR timeouts in that case. 995 */ 996 boolean mDidDexOpt; 997 998 /** 999 * Set if the systemServer made a call to enterSafeMode. 1000 */ 1001 boolean mSafeMode; 1002 1003 String mDebugApp = null; 1004 boolean mWaitForDebugger = false; 1005 boolean mDebugTransient = false; 1006 String mOrigDebugApp = null; 1007 boolean mOrigWaitForDebugger = false; 1008 boolean mAlwaysFinishActivities = false; 1009 IActivityController mController = null; 1010 String mProfileApp = null; 1011 ProcessRecord mProfileProc = null; 1012 String mProfileFile; 1013 ParcelFileDescriptor mProfileFd; 1014 int mProfileType = 0; 1015 boolean mAutoStopProfiler = false; 1016 String mOpenGlTraceApp = null; 1017 1018 static class ProcessChangeItem { 1019 static final int CHANGE_ACTIVITIES = 1<<0; 1020 static final int CHANGE_IMPORTANCE= 1<<1; 1021 int changes; 1022 int uid; 1023 int pid; 1024 int importance; 1025 boolean foregroundActivities; 1026 } 1027 1028 final RemoteCallbackList<IProcessObserver> mProcessObservers 1029 = new RemoteCallbackList<IProcessObserver>(); 1030 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1031 1032 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1033 = new ArrayList<ProcessChangeItem>(); 1034 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1035 = new ArrayList<ProcessChangeItem>(); 1036 1037 /** 1038 * Runtime CPU use collection thread. This object's lock is used to 1039 * protect all related state. 1040 */ 1041 final Thread mProcessCpuThread; 1042 1043 /** 1044 * Used to collect process stats when showing not responding dialog. 1045 * Protected by mProcessCpuThread. 1046 */ 1047 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1048 MONITOR_THREAD_CPU_USAGE); 1049 final AtomicLong mLastCpuTime = new AtomicLong(0); 1050 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1051 1052 long mLastWriteTime = 0; 1053 1054 /** 1055 * Used to retain an update lock when the foreground activity is in 1056 * immersive mode. 1057 */ 1058 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1059 1060 /** 1061 * Set to true after the system has finished booting. 1062 */ 1063 boolean mBooted = false; 1064 1065 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1066 int mProcessLimitOverride = -1; 1067 1068 WindowManagerService mWindowManager; 1069 1070 final ActivityThread mSystemThread; 1071 1072 int mCurrentUserId = 0; 1073 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1074 private UserManagerService mUserManager; 1075 1076 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1077 final ProcessRecord mApp; 1078 final int mPid; 1079 final IApplicationThread mAppThread; 1080 1081 AppDeathRecipient(ProcessRecord app, int pid, 1082 IApplicationThread thread) { 1083 if (localLOGV) Slog.v( 1084 TAG, "New death recipient " + this 1085 + " for thread " + thread.asBinder()); 1086 mApp = app; 1087 mPid = pid; 1088 mAppThread = thread; 1089 } 1090 1091 @Override 1092 public void binderDied() { 1093 if (localLOGV) Slog.v( 1094 TAG, "Death received in " + this 1095 + " for thread " + mAppThread.asBinder()); 1096 synchronized(ActivityManagerService.this) { 1097 appDiedLocked(mApp, mPid, mAppThread); 1098 } 1099 } 1100 } 1101 1102 static final int SHOW_ERROR_MSG = 1; 1103 static final int SHOW_NOT_RESPONDING_MSG = 2; 1104 static final int SHOW_FACTORY_ERROR_MSG = 3; 1105 static final int UPDATE_CONFIGURATION_MSG = 4; 1106 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1107 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1108 static final int SERVICE_TIMEOUT_MSG = 12; 1109 static final int UPDATE_TIME_ZONE = 13; 1110 static final int SHOW_UID_ERROR_MSG = 14; 1111 static final int IM_FEELING_LUCKY_MSG = 15; 1112 static final int PROC_START_TIMEOUT_MSG = 20; 1113 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1114 static final int KILL_APPLICATION_MSG = 22; 1115 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1116 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1117 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1118 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1119 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1120 static final int CLEAR_DNS_CACHE_MSG = 28; 1121 static final int UPDATE_HTTP_PROXY_MSG = 29; 1122 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1123 static final int DISPATCH_PROCESSES_CHANGED = 31; 1124 static final int DISPATCH_PROCESS_DIED = 32; 1125 static final int REPORT_MEM_USAGE_MSG = 33; 1126 static final int REPORT_USER_SWITCH_MSG = 34; 1127 static final int CONTINUE_USER_SWITCH_MSG = 35; 1128 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1129 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1130 static final int PERSIST_URI_GRANTS_MSG = 38; 1131 static final int REQUEST_ALL_PSS_MSG = 39; 1132 static final int START_PROFILES_MSG = 40; 1133 static final int UPDATE_TIME = 41; 1134 static final int SYSTEM_USER_START_MSG = 42; 1135 static final int SYSTEM_USER_CURRENT_MSG = 43; 1136 1137 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1138 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1139 static final int FIRST_COMPAT_MODE_MSG = 300; 1140 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1141 1142 AlertDialog mUidAlert; 1143 CompatModeDialog mCompatModeDialog; 1144 long mLastMemUsageReportTime = 0; 1145 1146 /** 1147 * Flag whether the current user is a "monkey", i.e. whether 1148 * the UI is driven by a UI automation tool. 1149 */ 1150 private boolean mUserIsMonkey; 1151 1152 final ServiceThread mHandlerThread; 1153 final MainHandler mHandler; 1154 1155 final class MainHandler extends Handler { 1156 public MainHandler(Looper looper) { 1157 super(looper, null, true); 1158 } 1159 1160 @Override 1161 public void handleMessage(Message msg) { 1162 switch (msg.what) { 1163 case SHOW_ERROR_MSG: { 1164 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1165 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1166 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1167 synchronized (ActivityManagerService.this) { 1168 ProcessRecord proc = (ProcessRecord)data.get("app"); 1169 AppErrorResult res = (AppErrorResult) data.get("result"); 1170 if (proc != null && proc.crashDialog != null) { 1171 Slog.e(TAG, "App already has crash dialog: " + proc); 1172 if (res != null) { 1173 res.set(0); 1174 } 1175 return; 1176 } 1177 if (!showBackground && UserHandle.getAppId(proc.uid) 1178 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1179 && proc.pid != MY_PID) { 1180 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1181 if (res != null) { 1182 res.set(0); 1183 } 1184 return; 1185 } 1186 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1187 Dialog d = new AppErrorDialog(mContext, 1188 ActivityManagerService.this, res, proc); 1189 d.show(); 1190 proc.crashDialog = d; 1191 } else { 1192 // The device is asleep, so just pretend that the user 1193 // saw a crash dialog and hit "force quit". 1194 if (res != null) { 1195 res.set(0); 1196 } 1197 } 1198 } 1199 1200 ensureBootCompleted(); 1201 } break; 1202 case SHOW_NOT_RESPONDING_MSG: { 1203 synchronized (ActivityManagerService.this) { 1204 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1205 ProcessRecord proc = (ProcessRecord)data.get("app"); 1206 if (proc != null && proc.anrDialog != null) { 1207 Slog.e(TAG, "App already has anr dialog: " + proc); 1208 return; 1209 } 1210 1211 Intent intent = new Intent("android.intent.action.ANR"); 1212 if (!mProcessesReady) { 1213 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1214 | Intent.FLAG_RECEIVER_FOREGROUND); 1215 } 1216 broadcastIntentLocked(null, null, intent, 1217 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1218 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1219 1220 if (mShowDialogs) { 1221 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1222 mContext, proc, (ActivityRecord)data.get("activity"), 1223 msg.arg1 != 0); 1224 d.show(); 1225 proc.anrDialog = d; 1226 } else { 1227 // Just kill the app if there is no dialog to be shown. 1228 killAppAtUsersRequest(proc, null); 1229 } 1230 } 1231 1232 ensureBootCompleted(); 1233 } break; 1234 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1235 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1236 synchronized (ActivityManagerService.this) { 1237 ProcessRecord proc = (ProcessRecord) data.get("app"); 1238 if (proc == null) { 1239 Slog.e(TAG, "App not found when showing strict mode dialog."); 1240 break; 1241 } 1242 if (proc.crashDialog != null) { 1243 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1244 return; 1245 } 1246 AppErrorResult res = (AppErrorResult) data.get("result"); 1247 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1248 Dialog d = new StrictModeViolationDialog(mContext, 1249 ActivityManagerService.this, res, proc); 1250 d.show(); 1251 proc.crashDialog = d; 1252 } else { 1253 // The device is asleep, so just pretend that the user 1254 // saw a crash dialog and hit "force quit". 1255 res.set(0); 1256 } 1257 } 1258 ensureBootCompleted(); 1259 } break; 1260 case SHOW_FACTORY_ERROR_MSG: { 1261 Dialog d = new FactoryErrorDialog( 1262 mContext, msg.getData().getCharSequence("msg")); 1263 d.show(); 1264 ensureBootCompleted(); 1265 } break; 1266 case UPDATE_CONFIGURATION_MSG: { 1267 final ContentResolver resolver = mContext.getContentResolver(); 1268 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1269 } break; 1270 case GC_BACKGROUND_PROCESSES_MSG: { 1271 synchronized (ActivityManagerService.this) { 1272 performAppGcsIfAppropriateLocked(); 1273 } 1274 } break; 1275 case WAIT_FOR_DEBUGGER_MSG: { 1276 synchronized (ActivityManagerService.this) { 1277 ProcessRecord app = (ProcessRecord)msg.obj; 1278 if (msg.arg1 != 0) { 1279 if (!app.waitedForDebugger) { 1280 Dialog d = new AppWaitingForDebuggerDialog( 1281 ActivityManagerService.this, 1282 mContext, app); 1283 app.waitDialog = d; 1284 app.waitedForDebugger = true; 1285 d.show(); 1286 } 1287 } else { 1288 if (app.waitDialog != null) { 1289 app.waitDialog.dismiss(); 1290 app.waitDialog = null; 1291 } 1292 } 1293 } 1294 } break; 1295 case SERVICE_TIMEOUT_MSG: { 1296 if (mDidDexOpt) { 1297 mDidDexOpt = false; 1298 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1299 nmsg.obj = msg.obj; 1300 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1301 return; 1302 } 1303 mServices.serviceTimeout((ProcessRecord)msg.obj); 1304 } break; 1305 case UPDATE_TIME_ZONE: { 1306 synchronized (ActivityManagerService.this) { 1307 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1308 ProcessRecord r = mLruProcesses.get(i); 1309 if (r.thread != null) { 1310 try { 1311 r.thread.updateTimeZone(); 1312 } catch (RemoteException ex) { 1313 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1314 } 1315 } 1316 } 1317 } 1318 } break; 1319 case CLEAR_DNS_CACHE_MSG: { 1320 synchronized (ActivityManagerService.this) { 1321 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1322 ProcessRecord r = mLruProcesses.get(i); 1323 if (r.thread != null) { 1324 try { 1325 r.thread.clearDnsCache(); 1326 } catch (RemoteException ex) { 1327 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1328 } 1329 } 1330 } 1331 } 1332 } break; 1333 case UPDATE_HTTP_PROXY_MSG: { 1334 ProxyProperties proxy = (ProxyProperties)msg.obj; 1335 String host = ""; 1336 String port = ""; 1337 String exclList = ""; 1338 String pacFileUrl = null; 1339 if (proxy != null) { 1340 host = proxy.getHost(); 1341 port = Integer.toString(proxy.getPort()); 1342 exclList = proxy.getExclusionList(); 1343 pacFileUrl = proxy.getPacFileUrl(); 1344 } 1345 synchronized (ActivityManagerService.this) { 1346 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1347 ProcessRecord r = mLruProcesses.get(i); 1348 if (r.thread != null) { 1349 try { 1350 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1351 } catch (RemoteException ex) { 1352 Slog.w(TAG, "Failed to update http proxy for: " + 1353 r.info.processName); 1354 } 1355 } 1356 } 1357 } 1358 } break; 1359 case SHOW_UID_ERROR_MSG: { 1360 String title = "System UIDs Inconsistent"; 1361 String text = "UIDs on the system are inconsistent, you need to wipe your" 1362 + " data partition or your device will be unstable."; 1363 Log.e(TAG, title + ": " + text); 1364 if (mShowDialogs) { 1365 // XXX This is a temporary dialog, no need to localize. 1366 AlertDialog d = new BaseErrorDialog(mContext); 1367 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1368 d.setCancelable(false); 1369 d.setTitle(title); 1370 d.setMessage(text); 1371 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1372 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1373 mUidAlert = d; 1374 d.show(); 1375 } 1376 } break; 1377 case IM_FEELING_LUCKY_MSG: { 1378 if (mUidAlert != null) { 1379 mUidAlert.dismiss(); 1380 mUidAlert = null; 1381 } 1382 } break; 1383 case PROC_START_TIMEOUT_MSG: { 1384 if (mDidDexOpt) { 1385 mDidDexOpt = false; 1386 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1387 nmsg.obj = msg.obj; 1388 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1389 return; 1390 } 1391 ProcessRecord app = (ProcessRecord)msg.obj; 1392 synchronized (ActivityManagerService.this) { 1393 processStartTimedOutLocked(app); 1394 } 1395 } break; 1396 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1397 synchronized (ActivityManagerService.this) { 1398 doPendingActivityLaunchesLocked(true); 1399 } 1400 } break; 1401 case KILL_APPLICATION_MSG: { 1402 synchronized (ActivityManagerService.this) { 1403 int appid = msg.arg1; 1404 boolean restart = (msg.arg2 == 1); 1405 Bundle bundle = (Bundle)msg.obj; 1406 String pkg = bundle.getString("pkg"); 1407 String reason = bundle.getString("reason"); 1408 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1409 false, UserHandle.USER_ALL, reason); 1410 } 1411 } break; 1412 case FINALIZE_PENDING_INTENT_MSG: { 1413 ((PendingIntentRecord)msg.obj).completeFinalize(); 1414 } break; 1415 case POST_HEAVY_NOTIFICATION_MSG: { 1416 INotificationManager inm = NotificationManager.getService(); 1417 if (inm == null) { 1418 return; 1419 } 1420 1421 ActivityRecord root = (ActivityRecord)msg.obj; 1422 ProcessRecord process = root.app; 1423 if (process == null) { 1424 return; 1425 } 1426 1427 try { 1428 Context context = mContext.createPackageContext(process.info.packageName, 0); 1429 String text = mContext.getString(R.string.heavy_weight_notification, 1430 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1431 Notification notification = new Notification(); 1432 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1433 notification.when = 0; 1434 notification.flags = Notification.FLAG_ONGOING_EVENT; 1435 notification.tickerText = text; 1436 notification.defaults = 0; // please be quiet 1437 notification.sound = null; 1438 notification.vibrate = null; 1439 notification.setLatestEventInfo(context, text, 1440 mContext.getText(R.string.heavy_weight_notification_detail), 1441 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1442 PendingIntent.FLAG_CANCEL_CURRENT, null, 1443 new UserHandle(root.userId))); 1444 1445 try { 1446 int[] outId = new int[1]; 1447 inm.enqueueNotificationWithTag("android", "android", null, 1448 R.string.heavy_weight_notification, 1449 notification, outId, root.userId); 1450 } catch (RuntimeException e) { 1451 Slog.w(ActivityManagerService.TAG, 1452 "Error showing notification for heavy-weight app", e); 1453 } catch (RemoteException e) { 1454 } 1455 } catch (NameNotFoundException e) { 1456 Slog.w(TAG, "Unable to create context for heavy notification", e); 1457 } 1458 } break; 1459 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1460 INotificationManager inm = NotificationManager.getService(); 1461 if (inm == null) { 1462 return; 1463 } 1464 try { 1465 inm.cancelNotificationWithTag("android", null, 1466 R.string.heavy_weight_notification, msg.arg1); 1467 } catch (RuntimeException e) { 1468 Slog.w(ActivityManagerService.TAG, 1469 "Error canceling notification for service", e); 1470 } catch (RemoteException e) { 1471 } 1472 } break; 1473 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1474 synchronized (ActivityManagerService.this) { 1475 checkExcessivePowerUsageLocked(true); 1476 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1477 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1478 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1479 } 1480 } break; 1481 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1482 synchronized (ActivityManagerService.this) { 1483 ActivityRecord ar = (ActivityRecord)msg.obj; 1484 if (mCompatModeDialog != null) { 1485 if (mCompatModeDialog.mAppInfo.packageName.equals( 1486 ar.info.applicationInfo.packageName)) { 1487 return; 1488 } 1489 mCompatModeDialog.dismiss(); 1490 mCompatModeDialog = null; 1491 } 1492 if (ar != null && false) { 1493 if (mCompatModePackages.getPackageAskCompatModeLocked( 1494 ar.packageName)) { 1495 int mode = mCompatModePackages.computeCompatModeLocked( 1496 ar.info.applicationInfo); 1497 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1498 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1499 mCompatModeDialog = new CompatModeDialog( 1500 ActivityManagerService.this, mContext, 1501 ar.info.applicationInfo); 1502 mCompatModeDialog.show(); 1503 } 1504 } 1505 } 1506 } 1507 break; 1508 } 1509 case DISPATCH_PROCESSES_CHANGED: { 1510 dispatchProcessesChanged(); 1511 break; 1512 } 1513 case DISPATCH_PROCESS_DIED: { 1514 final int pid = msg.arg1; 1515 final int uid = msg.arg2; 1516 dispatchProcessDied(pid, uid); 1517 break; 1518 } 1519 case REPORT_MEM_USAGE_MSG: { 1520 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1521 Thread thread = new Thread() { 1522 @Override public void run() { 1523 final SparseArray<ProcessMemInfo> infoMap 1524 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1525 for (int i=0, N=memInfos.size(); i<N; i++) { 1526 ProcessMemInfo mi = memInfos.get(i); 1527 infoMap.put(mi.pid, mi); 1528 } 1529 updateCpuStatsNow(); 1530 synchronized (mProcessCpuThread) { 1531 final int N = mProcessCpuTracker.countStats(); 1532 for (int i=0; i<N; i++) { 1533 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1534 if (st.vsize > 0) { 1535 long pss = Debug.getPss(st.pid, null); 1536 if (pss > 0) { 1537 if (infoMap.indexOfKey(st.pid) < 0) { 1538 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1539 ProcessList.NATIVE_ADJ, -1, "native", null); 1540 mi.pss = pss; 1541 memInfos.add(mi); 1542 } 1543 } 1544 } 1545 } 1546 } 1547 1548 long totalPss = 0; 1549 for (int i=0, N=memInfos.size(); i<N; i++) { 1550 ProcessMemInfo mi = memInfos.get(i); 1551 if (mi.pss == 0) { 1552 mi.pss = Debug.getPss(mi.pid, null); 1553 } 1554 totalPss += mi.pss; 1555 } 1556 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1557 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1558 if (lhs.oomAdj != rhs.oomAdj) { 1559 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1560 } 1561 if (lhs.pss != rhs.pss) { 1562 return lhs.pss < rhs.pss ? 1 : -1; 1563 } 1564 return 0; 1565 } 1566 }); 1567 1568 StringBuilder tag = new StringBuilder(128); 1569 StringBuilder stack = new StringBuilder(128); 1570 tag.append("Low on memory -- "); 1571 appendMemBucket(tag, totalPss, "total", false); 1572 appendMemBucket(stack, totalPss, "total", true); 1573 1574 StringBuilder logBuilder = new StringBuilder(1024); 1575 logBuilder.append("Low on memory:\n"); 1576 1577 boolean firstLine = true; 1578 int lastOomAdj = Integer.MIN_VALUE; 1579 for (int i=0, N=memInfos.size(); i<N; i++) { 1580 ProcessMemInfo mi = memInfos.get(i); 1581 1582 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1583 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1584 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1585 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1586 if (lastOomAdj != mi.oomAdj) { 1587 lastOomAdj = mi.oomAdj; 1588 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1589 tag.append(" / "); 1590 } 1591 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1592 if (firstLine) { 1593 stack.append(":"); 1594 firstLine = false; 1595 } 1596 stack.append("\n\t at "); 1597 } else { 1598 stack.append("$"); 1599 } 1600 } else { 1601 tag.append(" "); 1602 stack.append("$"); 1603 } 1604 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1605 appendMemBucket(tag, mi.pss, mi.name, false); 1606 } 1607 appendMemBucket(stack, mi.pss, mi.name, true); 1608 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1609 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1610 stack.append("("); 1611 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1612 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1613 stack.append(DUMP_MEM_OOM_LABEL[k]); 1614 stack.append(":"); 1615 stack.append(DUMP_MEM_OOM_ADJ[k]); 1616 } 1617 } 1618 stack.append(")"); 1619 } 1620 } 1621 1622 logBuilder.append(" "); 1623 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1624 logBuilder.append(' '); 1625 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1626 logBuilder.append(' '); 1627 ProcessList.appendRamKb(logBuilder, mi.pss); 1628 logBuilder.append(" kB: "); 1629 logBuilder.append(mi.name); 1630 logBuilder.append(" ("); 1631 logBuilder.append(mi.pid); 1632 logBuilder.append(") "); 1633 logBuilder.append(mi.adjType); 1634 logBuilder.append('\n'); 1635 if (mi.adjReason != null) { 1636 logBuilder.append(" "); 1637 logBuilder.append(mi.adjReason); 1638 logBuilder.append('\n'); 1639 } 1640 } 1641 1642 logBuilder.append(" "); 1643 ProcessList.appendRamKb(logBuilder, totalPss); 1644 logBuilder.append(" kB: TOTAL\n"); 1645 1646 long[] infos = new long[Debug.MEMINFO_COUNT]; 1647 Debug.getMemInfo(infos); 1648 logBuilder.append(" MemInfo: "); 1649 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1650 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1651 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1652 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1653 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1654 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1655 logBuilder.append(" ZRAM: "); 1656 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1657 logBuilder.append(" kB RAM, "); 1658 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1659 logBuilder.append(" kB swap total, "); 1660 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1661 logBuilder.append(" kB swap free\n"); 1662 } 1663 Slog.i(TAG, logBuilder.toString()); 1664 1665 StringBuilder dropBuilder = new StringBuilder(1024); 1666 /* 1667 StringWriter oomSw = new StringWriter(); 1668 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1669 StringWriter catSw = new StringWriter(); 1670 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1671 String[] emptyArgs = new String[] { }; 1672 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1673 oomPw.flush(); 1674 String oomString = oomSw.toString(); 1675 */ 1676 dropBuilder.append(stack); 1677 dropBuilder.append('\n'); 1678 dropBuilder.append('\n'); 1679 dropBuilder.append(logBuilder); 1680 dropBuilder.append('\n'); 1681 /* 1682 dropBuilder.append(oomString); 1683 dropBuilder.append('\n'); 1684 */ 1685 StringWriter catSw = new StringWriter(); 1686 synchronized (ActivityManagerService.this) { 1687 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1688 String[] emptyArgs = new String[] { }; 1689 catPw.println(); 1690 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1691 catPw.println(); 1692 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1693 false, false, null); 1694 catPw.println(); 1695 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1696 catPw.flush(); 1697 } 1698 dropBuilder.append(catSw.toString()); 1699 addErrorToDropBox("lowmem", null, "system_server", null, 1700 null, tag.toString(), dropBuilder.toString(), null, null); 1701 //Slog.i(TAG, "Sent to dropbox:"); 1702 //Slog.i(TAG, dropBuilder.toString()); 1703 synchronized (ActivityManagerService.this) { 1704 long now = SystemClock.uptimeMillis(); 1705 if (mLastMemUsageReportTime < now) { 1706 mLastMemUsageReportTime = now; 1707 } 1708 } 1709 } 1710 }; 1711 thread.start(); 1712 break; 1713 } 1714 case REPORT_USER_SWITCH_MSG: { 1715 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1716 break; 1717 } 1718 case CONTINUE_USER_SWITCH_MSG: { 1719 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1720 break; 1721 } 1722 case USER_SWITCH_TIMEOUT_MSG: { 1723 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1724 break; 1725 } 1726 case IMMERSIVE_MODE_LOCK_MSG: { 1727 final boolean nextState = (msg.arg1 != 0); 1728 if (mUpdateLock.isHeld() != nextState) { 1729 if (DEBUG_IMMERSIVE) { 1730 final ActivityRecord r = (ActivityRecord) msg.obj; 1731 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1732 } 1733 if (nextState) { 1734 mUpdateLock.acquire(); 1735 } else { 1736 mUpdateLock.release(); 1737 } 1738 } 1739 break; 1740 } 1741 case PERSIST_URI_GRANTS_MSG: { 1742 writeGrantedUriPermissions(); 1743 break; 1744 } 1745 case REQUEST_ALL_PSS_MSG: { 1746 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1747 break; 1748 } 1749 case START_PROFILES_MSG: { 1750 synchronized (ActivityManagerService.this) { 1751 startProfilesLocked(); 1752 } 1753 break; 1754 } 1755 case UPDATE_TIME: { 1756 synchronized (ActivityManagerService.this) { 1757 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1758 ProcessRecord r = mLruProcesses.get(i); 1759 if (r.thread != null) { 1760 try { 1761 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1762 } catch (RemoteException ex) { 1763 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1764 } 1765 } 1766 } 1767 } 1768 break; 1769 } 1770 case SYSTEM_USER_START_MSG: { 1771 mSystemServiceManager.startUser(msg.arg1); 1772 break; 1773 } 1774 case SYSTEM_USER_CURRENT_MSG: { 1775 mSystemServiceManager.switchUser(msg.arg1); 1776 break; 1777 } 1778 } 1779 } 1780 }; 1781 1782 static final int COLLECT_PSS_BG_MSG = 1; 1783 1784 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1785 @Override 1786 public void handleMessage(Message msg) { 1787 switch (msg.what) { 1788 case COLLECT_PSS_BG_MSG: { 1789 int i=0, num=0; 1790 long start = SystemClock.uptimeMillis(); 1791 long[] tmp = new long[1]; 1792 do { 1793 ProcessRecord proc; 1794 int procState; 1795 int pid; 1796 synchronized (ActivityManagerService.this) { 1797 if (i >= mPendingPssProcesses.size()) { 1798 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1799 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1800 mPendingPssProcesses.clear(); 1801 return; 1802 } 1803 proc = mPendingPssProcesses.get(i); 1804 procState = proc.pssProcState; 1805 if (proc.thread != null && procState == proc.setProcState) { 1806 pid = proc.pid; 1807 } else { 1808 proc = null; 1809 pid = 0; 1810 } 1811 i++; 1812 } 1813 if (proc != null) { 1814 long pss = Debug.getPss(pid, tmp); 1815 synchronized (ActivityManagerService.this) { 1816 if (proc.thread != null && proc.setProcState == procState 1817 && proc.pid == pid) { 1818 num++; 1819 proc.lastPssTime = SystemClock.uptimeMillis(); 1820 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1821 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1822 + ": " + pss + " lastPss=" + proc.lastPss 1823 + " state=" + ProcessList.makeProcStateString(procState)); 1824 if (proc.initialIdlePss == 0) { 1825 proc.initialIdlePss = pss; 1826 } 1827 proc.lastPss = pss; 1828 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1829 proc.lastCachedPss = pss; 1830 } 1831 } 1832 } 1833 } 1834 } while (true); 1835 } 1836 } 1837 } 1838 }; 1839 1840 /** 1841 * Monitor for package changes and update our internal state. 1842 */ 1843 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1844 @Override 1845 public void onPackageRemoved(String packageName, int uid) { 1846 // Remove all tasks with activities in the specified package from the list of recent tasks 1847 synchronized (ActivityManagerService.this) { 1848 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1849 TaskRecord tr = mRecentTasks.get(i); 1850 ComponentName cn = tr.intent.getComponent(); 1851 if (cn != null && cn.getPackageName().equals(packageName)) { 1852 // If the package name matches, remove the task and kill the process 1853 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1854 } 1855 } 1856 } 1857 } 1858 1859 @Override 1860 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1861 final PackageManager pm = mContext.getPackageManager(); 1862 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1863 new ArrayList<Pair<Intent, Integer>>(); 1864 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1865 // Copy the list of recent tasks so that we don't hold onto the lock on 1866 // ActivityManagerService for long periods while checking if components exist. 1867 synchronized (ActivityManagerService.this) { 1868 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1869 TaskRecord tr = mRecentTasks.get(i); 1870 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1871 } 1872 } 1873 // Check the recent tasks and filter out all tasks with components that no longer exist. 1874 Intent tmpI = new Intent(); 1875 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1876 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1877 ComponentName cn = p.first.getComponent(); 1878 if (cn != null && cn.getPackageName().equals(packageName)) { 1879 try { 1880 // Add the task to the list to remove if the component no longer exists 1881 tmpI.setComponent(cn); 1882 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1883 tasksToRemove.add(p.second); 1884 } 1885 } catch (Exception e) {} 1886 } 1887 } 1888 // Prune all the tasks with removed components from the list of recent tasks 1889 synchronized (ActivityManagerService.this) { 1890 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1891 // Remove the task but don't kill the process (since other components in that 1892 // package may still be running and in the background) 1893 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1894 } 1895 } 1896 return true; 1897 } 1898 1899 @Override 1900 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1901 // Force stop the specified packages 1902 if (packages != null) { 1903 for (String pkg : packages) { 1904 synchronized (ActivityManagerService.this) { 1905 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1906 "finished booting")) { 1907 return true; 1908 } 1909 } 1910 } 1911 } 1912 return false; 1913 } 1914 }; 1915 1916 public void setSystemProcess() { 1917 try { 1918 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1919 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1920 ServiceManager.addService("meminfo", new MemBinder(this)); 1921 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1922 ServiceManager.addService("dbinfo", new DbBinder(this)); 1923 if (MONITOR_CPU_USAGE) { 1924 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1925 } 1926 ServiceManager.addService("permission", new PermissionController(this)); 1927 1928 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1929 "android", STOCK_PM_FLAGS); 1930 mSystemThread.installSystemApplicationInfo(info); 1931 1932 synchronized (this) { 1933 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1934 app.persistent = true; 1935 app.pid = MY_PID; 1936 app.maxAdj = ProcessList.SYSTEM_ADJ; 1937 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1938 mProcessNames.put(app.processName, app.uid, app); 1939 synchronized (mPidsSelfLocked) { 1940 mPidsSelfLocked.put(app.pid, app); 1941 } 1942 updateLruProcessLocked(app, false, null); 1943 updateOomAdjLocked(); 1944 } 1945 } catch (PackageManager.NameNotFoundException e) { 1946 throw new RuntimeException( 1947 "Unable to find android system package", e); 1948 } 1949 } 1950 1951 public void setWindowManager(WindowManagerService wm) { 1952 mWindowManager = wm; 1953 mStackSupervisor.setWindowManager(wm); 1954 } 1955 1956 public void startObservingNativeCrashes() { 1957 final NativeCrashListener ncl = new NativeCrashListener(this); 1958 ncl.start(); 1959 } 1960 1961 public IAppOpsService getAppOpsService() { 1962 return mAppOpsService; 1963 } 1964 1965 static class MemBinder extends Binder { 1966 ActivityManagerService mActivityManagerService; 1967 MemBinder(ActivityManagerService activityManagerService) { 1968 mActivityManagerService = activityManagerService; 1969 } 1970 1971 @Override 1972 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1973 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1974 != PackageManager.PERMISSION_GRANTED) { 1975 pw.println("Permission Denial: can't dump meminfo from from pid=" 1976 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1977 + " without permission " + android.Manifest.permission.DUMP); 1978 return; 1979 } 1980 1981 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1982 } 1983 } 1984 1985 static class GraphicsBinder extends Binder { 1986 ActivityManagerService mActivityManagerService; 1987 GraphicsBinder(ActivityManagerService activityManagerService) { 1988 mActivityManagerService = activityManagerService; 1989 } 1990 1991 @Override 1992 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1993 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1994 != PackageManager.PERMISSION_GRANTED) { 1995 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1996 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1997 + " without permission " + android.Manifest.permission.DUMP); 1998 return; 1999 } 2000 2001 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2002 } 2003 } 2004 2005 static class DbBinder extends Binder { 2006 ActivityManagerService mActivityManagerService; 2007 DbBinder(ActivityManagerService activityManagerService) { 2008 mActivityManagerService = activityManagerService; 2009 } 2010 2011 @Override 2012 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2013 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2014 != PackageManager.PERMISSION_GRANTED) { 2015 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2016 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2017 + " without permission " + android.Manifest.permission.DUMP); 2018 return; 2019 } 2020 2021 mActivityManagerService.dumpDbInfo(fd, pw, args); 2022 } 2023 } 2024 2025 static class CpuBinder extends Binder { 2026 ActivityManagerService mActivityManagerService; 2027 CpuBinder(ActivityManagerService activityManagerService) { 2028 mActivityManagerService = activityManagerService; 2029 } 2030 2031 @Override 2032 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2033 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2034 != PackageManager.PERMISSION_GRANTED) { 2035 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2036 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2037 + " without permission " + android.Manifest.permission.DUMP); 2038 return; 2039 } 2040 2041 synchronized (mActivityManagerService.mProcessCpuThread) { 2042 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2043 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2044 SystemClock.uptimeMillis())); 2045 } 2046 } 2047 } 2048 2049 public static final class Lifecycle extends SystemService { 2050 private final ActivityManagerService mService; 2051 2052 public Lifecycle(Context context) { 2053 super(context); 2054 mService = new ActivityManagerService(context); 2055 } 2056 2057 @Override 2058 public void onStart() { 2059 mService.start(); 2060 } 2061 2062 public ActivityManagerService getService() { 2063 return mService; 2064 } 2065 } 2066 2067 // Note: This method is invoked on the main thread but may need to attach various 2068 // handlers to other threads. So take care to be explicit about the looper. 2069 public ActivityManagerService(Context systemContext) { 2070 mContext = systemContext; 2071 mFactoryTest = FactoryTest.getMode(); 2072 mSystemThread = ActivityThread.currentActivityThread(); 2073 2074 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2075 2076 mHandlerThread = new ServiceThread(TAG, 2077 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2078 mHandlerThread.start(); 2079 mHandler = new MainHandler(mHandlerThread.getLooper()); 2080 2081 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2082 "foreground", BROADCAST_FG_TIMEOUT, false); 2083 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2084 "background", BROADCAST_BG_TIMEOUT, true); 2085 mBroadcastQueues[0] = mFgBroadcastQueue; 2086 mBroadcastQueues[1] = mBgBroadcastQueue; 2087 2088 mServices = new ActiveServices(this); 2089 mProviderMap = new ProviderMap(this); 2090 2091 // TODO: Move creation of battery stats service outside of activity manager service. 2092 File dataDir = Environment.getDataDirectory(); 2093 File systemDir = new File(dataDir, "system"); 2094 systemDir.mkdirs(); 2095 mBatteryStatsService = new BatteryStatsService(new File( 2096 systemDir, "batterystats.bin").toString(), mHandler); 2097 mBatteryStatsService.getActiveStatistics().readLocked(); 2098 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2099 mOnBattery = DEBUG_POWER ? true 2100 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2101 mBatteryStatsService.getActiveStatistics().setCallback(this); 2102 2103 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2104 2105 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2106 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2107 2108 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2109 2110 // User 0 is the first and only user that runs at boot. 2111 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2112 mUserLru.add(Integer.valueOf(0)); 2113 updateStartedUserArrayLocked(); 2114 2115 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2116 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2117 2118 mConfiguration.setToDefaults(); 2119 mConfiguration.setLocale(Locale.getDefault()); 2120 2121 mConfigurationSeq = mConfiguration.seq = 1; 2122 mProcessCpuTracker.init(); 2123 2124 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2125 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2126 mStackSupervisor = new ActivityStackSupervisor(this); 2127 2128 mProcessCpuThread = new Thread("CpuTracker") { 2129 @Override 2130 public void run() { 2131 while (true) { 2132 try { 2133 try { 2134 synchronized(this) { 2135 final long now = SystemClock.uptimeMillis(); 2136 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2137 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2138 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2139 // + ", write delay=" + nextWriteDelay); 2140 if (nextWriteDelay < nextCpuDelay) { 2141 nextCpuDelay = nextWriteDelay; 2142 } 2143 if (nextCpuDelay > 0) { 2144 mProcessCpuMutexFree.set(true); 2145 this.wait(nextCpuDelay); 2146 } 2147 } 2148 } catch (InterruptedException e) { 2149 } 2150 updateCpuStatsNow(); 2151 } catch (Exception e) { 2152 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2153 } 2154 } 2155 } 2156 }; 2157 2158 Watchdog.getInstance().addMonitor(this); 2159 Watchdog.getInstance().addThread(mHandler); 2160 } 2161 2162 public void setSystemServiceManager(SystemServiceManager mgr) { 2163 mSystemServiceManager = mgr; 2164 } 2165 2166 private void start() { 2167 mProcessCpuThread.start(); 2168 2169 mBatteryStatsService.publish(mContext); 2170 mUsageStatsService.publish(mContext); 2171 mAppOpsService.publish(mContext); 2172 2173 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2174 } 2175 2176 @Override 2177 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2178 throws RemoteException { 2179 if (code == SYSPROPS_TRANSACTION) { 2180 // We need to tell all apps about the system property change. 2181 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2182 synchronized(this) { 2183 final int NP = mProcessNames.getMap().size(); 2184 for (int ip=0; ip<NP; ip++) { 2185 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2186 final int NA = apps.size(); 2187 for (int ia=0; ia<NA; ia++) { 2188 ProcessRecord app = apps.valueAt(ia); 2189 if (app.thread != null) { 2190 procs.add(app.thread.asBinder()); 2191 } 2192 } 2193 } 2194 } 2195 2196 int N = procs.size(); 2197 for (int i=0; i<N; i++) { 2198 Parcel data2 = Parcel.obtain(); 2199 try { 2200 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2201 } catch (RemoteException e) { 2202 } 2203 data2.recycle(); 2204 } 2205 } 2206 try { 2207 return super.onTransact(code, data, reply, flags); 2208 } catch (RuntimeException e) { 2209 // The activity manager only throws security exceptions, so let's 2210 // log all others. 2211 if (!(e instanceof SecurityException)) { 2212 Slog.wtf(TAG, "Activity Manager Crash", e); 2213 } 2214 throw e; 2215 } 2216 } 2217 2218 void updateCpuStats() { 2219 final long now = SystemClock.uptimeMillis(); 2220 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2221 return; 2222 } 2223 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2224 synchronized (mProcessCpuThread) { 2225 mProcessCpuThread.notify(); 2226 } 2227 } 2228 } 2229 2230 void updateCpuStatsNow() { 2231 synchronized (mProcessCpuThread) { 2232 mProcessCpuMutexFree.set(false); 2233 final long now = SystemClock.uptimeMillis(); 2234 boolean haveNewCpuStats = false; 2235 2236 if (MONITOR_CPU_USAGE && 2237 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2238 mLastCpuTime.set(now); 2239 haveNewCpuStats = true; 2240 mProcessCpuTracker.update(); 2241 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2242 //Slog.i(TAG, "Total CPU usage: " 2243 // + mProcessCpu.getTotalCpuPercent() + "%"); 2244 2245 // Slog the cpu usage if the property is set. 2246 if ("true".equals(SystemProperties.get("events.cpu"))) { 2247 int user = mProcessCpuTracker.getLastUserTime(); 2248 int system = mProcessCpuTracker.getLastSystemTime(); 2249 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2250 int irq = mProcessCpuTracker.getLastIrqTime(); 2251 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2252 int idle = mProcessCpuTracker.getLastIdleTime(); 2253 2254 int total = user + system + iowait + irq + softIrq + idle; 2255 if (total == 0) total = 1; 2256 2257 EventLog.writeEvent(EventLogTags.CPU, 2258 ((user+system+iowait+irq+softIrq) * 100) / total, 2259 (user * 100) / total, 2260 (system * 100) / total, 2261 (iowait * 100) / total, 2262 (irq * 100) / total, 2263 (softIrq * 100) / total); 2264 } 2265 } 2266 2267 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2268 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2269 synchronized(bstats) { 2270 synchronized(mPidsSelfLocked) { 2271 if (haveNewCpuStats) { 2272 if (mOnBattery) { 2273 int perc = bstats.startAddingCpuLocked(); 2274 int totalUTime = 0; 2275 int totalSTime = 0; 2276 final int N = mProcessCpuTracker.countStats(); 2277 for (int i=0; i<N; i++) { 2278 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2279 if (!st.working) { 2280 continue; 2281 } 2282 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2283 int otherUTime = (st.rel_utime*perc)/100; 2284 int otherSTime = (st.rel_stime*perc)/100; 2285 totalUTime += otherUTime; 2286 totalSTime += otherSTime; 2287 if (pr != null) { 2288 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2289 if (ps == null || !ps.isActive()) { 2290 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2291 pr.info.uid, pr.processName); 2292 } 2293 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2294 st.rel_stime-otherSTime); 2295 ps.addSpeedStepTimes(cpuSpeedTimes); 2296 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2297 } else { 2298 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2299 if (ps == null || !ps.isActive()) { 2300 st.batteryStats = ps = bstats.getProcessStatsLocked( 2301 bstats.mapUid(st.uid), st.name); 2302 } 2303 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2304 st.rel_stime-otherSTime); 2305 ps.addSpeedStepTimes(cpuSpeedTimes); 2306 } 2307 } 2308 bstats.finishAddingCpuLocked(perc, totalUTime, 2309 totalSTime, cpuSpeedTimes); 2310 } 2311 } 2312 } 2313 2314 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2315 mLastWriteTime = now; 2316 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2317 } 2318 } 2319 } 2320 } 2321 2322 @Override 2323 public void batteryNeedsCpuUpdate() { 2324 updateCpuStatsNow(); 2325 } 2326 2327 @Override 2328 public void batteryPowerChanged(boolean onBattery) { 2329 // When plugging in, update the CPU stats first before changing 2330 // the plug state. 2331 updateCpuStatsNow(); 2332 synchronized (this) { 2333 synchronized(mPidsSelfLocked) { 2334 mOnBattery = DEBUG_POWER ? true : onBattery; 2335 } 2336 } 2337 } 2338 2339 /** 2340 * Initialize the application bind args. These are passed to each 2341 * process when the bindApplication() IPC is sent to the process. They're 2342 * lazily setup to make sure the services are running when they're asked for. 2343 */ 2344 private HashMap<String, IBinder> getCommonServicesLocked() { 2345 if (mAppBindArgs == null) { 2346 mAppBindArgs = new HashMap<String, IBinder>(); 2347 2348 // Setup the application init args 2349 mAppBindArgs.put("package", ServiceManager.getService("package")); 2350 mAppBindArgs.put("window", ServiceManager.getService("window")); 2351 mAppBindArgs.put(Context.ALARM_SERVICE, 2352 ServiceManager.getService(Context.ALARM_SERVICE)); 2353 } 2354 return mAppBindArgs; 2355 } 2356 2357 final void setFocusedActivityLocked(ActivityRecord r) { 2358 if (mFocusedActivity != r) { 2359 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2360 mFocusedActivity = r; 2361 if (r.task != null && r.task.voiceInteractor != null) { 2362 startRunningVoiceLocked(); 2363 } else { 2364 finishRunningVoiceLocked(); 2365 } 2366 mStackSupervisor.setFocusedStack(r); 2367 if (r != null) { 2368 mWindowManager.setFocusedApp(r.appToken, true); 2369 } 2370 applyUpdateLockStateLocked(r); 2371 } 2372 } 2373 2374 final void clearFocusedActivity(ActivityRecord r) { 2375 if (mFocusedActivity == r) { 2376 mFocusedActivity = null; 2377 } 2378 } 2379 2380 @Override 2381 public void setFocusedStack(int stackId) { 2382 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2383 synchronized (ActivityManagerService.this) { 2384 ActivityStack stack = mStackSupervisor.getStack(stackId); 2385 if (stack != null) { 2386 ActivityRecord r = stack.topRunningActivityLocked(null); 2387 if (r != null) { 2388 setFocusedActivityLocked(r); 2389 } 2390 } 2391 } 2392 } 2393 2394 @Override 2395 public void notifyActivityDrawn(IBinder token) { 2396 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2397 synchronized (this) { 2398 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2399 if (r != null) { 2400 r.task.stack.notifyActivityDrawnLocked(r); 2401 } 2402 } 2403 } 2404 2405 final void applyUpdateLockStateLocked(ActivityRecord r) { 2406 // Modifications to the UpdateLock state are done on our handler, outside 2407 // the activity manager's locks. The new state is determined based on the 2408 // state *now* of the relevant activity record. The object is passed to 2409 // the handler solely for logging detail, not to be consulted/modified. 2410 final boolean nextState = r != null && r.immersive; 2411 mHandler.sendMessage( 2412 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2413 } 2414 2415 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2416 Message msg = Message.obtain(); 2417 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2418 msg.obj = r.task.askedCompatMode ? null : r; 2419 mHandler.sendMessage(msg); 2420 } 2421 2422 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2423 String what, Object obj, ProcessRecord srcApp) { 2424 app.lastActivityTime = now; 2425 2426 if (app.activities.size() > 0) { 2427 // Don't want to touch dependent processes that are hosting activities. 2428 return index; 2429 } 2430 2431 int lrui = mLruProcesses.lastIndexOf(app); 2432 if (lrui < 0) { 2433 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2434 + what + " " + obj + " from " + srcApp); 2435 return index; 2436 } 2437 2438 if (lrui >= index) { 2439 // Don't want to cause this to move dependent processes *back* in the 2440 // list as if they were less frequently used. 2441 return index; 2442 } 2443 2444 if (lrui >= mLruProcessActivityStart) { 2445 // Don't want to touch dependent processes that are hosting activities. 2446 return index; 2447 } 2448 2449 mLruProcesses.remove(lrui); 2450 if (index > 0) { 2451 index--; 2452 } 2453 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2454 + " in LRU list: " + app); 2455 mLruProcesses.add(index, app); 2456 return index; 2457 } 2458 2459 final void removeLruProcessLocked(ProcessRecord app) { 2460 int lrui = mLruProcesses.lastIndexOf(app); 2461 if (lrui >= 0) { 2462 if (lrui <= mLruProcessActivityStart) { 2463 mLruProcessActivityStart--; 2464 } 2465 if (lrui <= mLruProcessServiceStart) { 2466 mLruProcessServiceStart--; 2467 } 2468 mLruProcesses.remove(lrui); 2469 } 2470 } 2471 2472 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2473 ProcessRecord client) { 2474 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2475 || app.treatLikeActivity; 2476 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2477 if (!activityChange && hasActivity) { 2478 // The process has activities, so we are only allowing activity-based adjustments 2479 // to move it. It should be kept in the front of the list with other 2480 // processes that have activities, and we don't want those to change their 2481 // order except due to activity operations. 2482 return; 2483 } 2484 2485 mLruSeq++; 2486 final long now = SystemClock.uptimeMillis(); 2487 app.lastActivityTime = now; 2488 2489 // First a quick reject: if the app is already at the position we will 2490 // put it, then there is nothing to do. 2491 if (hasActivity) { 2492 final int N = mLruProcesses.size(); 2493 if (N > 0 && mLruProcesses.get(N-1) == app) { 2494 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2495 return; 2496 } 2497 } else { 2498 if (mLruProcessServiceStart > 0 2499 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2500 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2501 return; 2502 } 2503 } 2504 2505 int lrui = mLruProcesses.lastIndexOf(app); 2506 2507 if (app.persistent && lrui >= 0) { 2508 // We don't care about the position of persistent processes, as long as 2509 // they are in the list. 2510 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2511 return; 2512 } 2513 2514 /* In progress: compute new position first, so we can avoid doing work 2515 if the process is not actually going to move. Not yet working. 2516 int addIndex; 2517 int nextIndex; 2518 boolean inActivity = false, inService = false; 2519 if (hasActivity) { 2520 // Process has activities, put it at the very tipsy-top. 2521 addIndex = mLruProcesses.size(); 2522 nextIndex = mLruProcessServiceStart; 2523 inActivity = true; 2524 } else if (hasService) { 2525 // Process has services, put it at the top of the service list. 2526 addIndex = mLruProcessActivityStart; 2527 nextIndex = mLruProcessServiceStart; 2528 inActivity = true; 2529 inService = true; 2530 } else { 2531 // Process not otherwise of interest, it goes to the top of the non-service area. 2532 addIndex = mLruProcessServiceStart; 2533 if (client != null) { 2534 int clientIndex = mLruProcesses.lastIndexOf(client); 2535 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2536 + app); 2537 if (clientIndex >= 0 && addIndex > clientIndex) { 2538 addIndex = clientIndex; 2539 } 2540 } 2541 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2542 } 2543 2544 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2545 + mLruProcessActivityStart + "): " + app); 2546 */ 2547 2548 if (lrui >= 0) { 2549 if (lrui < mLruProcessActivityStart) { 2550 mLruProcessActivityStart--; 2551 } 2552 if (lrui < mLruProcessServiceStart) { 2553 mLruProcessServiceStart--; 2554 } 2555 /* 2556 if (addIndex > lrui) { 2557 addIndex--; 2558 } 2559 if (nextIndex > lrui) { 2560 nextIndex--; 2561 } 2562 */ 2563 mLruProcesses.remove(lrui); 2564 } 2565 2566 /* 2567 mLruProcesses.add(addIndex, app); 2568 if (inActivity) { 2569 mLruProcessActivityStart++; 2570 } 2571 if (inService) { 2572 mLruProcessActivityStart++; 2573 } 2574 */ 2575 2576 int nextIndex; 2577 if (hasActivity) { 2578 final int N = mLruProcesses.size(); 2579 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2580 // Process doesn't have activities, but has clients with 2581 // activities... move it up, but one below the top (the top 2582 // should always have a real activity). 2583 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2584 mLruProcesses.add(N-1, app); 2585 // To keep it from spamming the LRU list (by making a bunch of clients), 2586 // we will push down any other entries owned by the app. 2587 final int uid = app.info.uid; 2588 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2589 ProcessRecord subProc = mLruProcesses.get(i); 2590 if (subProc.info.uid == uid) { 2591 // We want to push this one down the list. If the process after 2592 // it is for the same uid, however, don't do so, because we don't 2593 // want them internally to be re-ordered. 2594 if (mLruProcesses.get(i-1).info.uid != uid) { 2595 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2596 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2597 ProcessRecord tmp = mLruProcesses.get(i); 2598 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2599 mLruProcesses.set(i-1, tmp); 2600 i--; 2601 } 2602 } else { 2603 // A gap, we can stop here. 2604 break; 2605 } 2606 } 2607 } else { 2608 // Process has activities, put it at the very tipsy-top. 2609 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2610 mLruProcesses.add(app); 2611 } 2612 nextIndex = mLruProcessServiceStart; 2613 } else if (hasService) { 2614 // Process has services, put it at the top of the service list. 2615 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2616 mLruProcesses.add(mLruProcessActivityStart, app); 2617 nextIndex = mLruProcessServiceStart; 2618 mLruProcessActivityStart++; 2619 } else { 2620 // Process not otherwise of interest, it goes to the top of the non-service area. 2621 int index = mLruProcessServiceStart; 2622 if (client != null) { 2623 // If there is a client, don't allow the process to be moved up higher 2624 // in the list than that client. 2625 int clientIndex = mLruProcesses.lastIndexOf(client); 2626 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2627 + " when updating " + app); 2628 if (clientIndex <= lrui) { 2629 // Don't allow the client index restriction to push it down farther in the 2630 // list than it already is. 2631 clientIndex = lrui; 2632 } 2633 if (clientIndex >= 0 && index > clientIndex) { 2634 index = clientIndex; 2635 } 2636 } 2637 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2638 mLruProcesses.add(index, app); 2639 nextIndex = index-1; 2640 mLruProcessActivityStart++; 2641 mLruProcessServiceStart++; 2642 } 2643 2644 // If the app is currently using a content provider or service, 2645 // bump those processes as well. 2646 for (int j=app.connections.size()-1; j>=0; j--) { 2647 ConnectionRecord cr = app.connections.valueAt(j); 2648 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2649 && cr.binding.service.app != null 2650 && cr.binding.service.app.lruSeq != mLruSeq 2651 && !cr.binding.service.app.persistent) { 2652 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2653 "service connection", cr, app); 2654 } 2655 } 2656 for (int j=app.conProviders.size()-1; j>=0; j--) { 2657 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2658 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2659 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2660 "provider reference", cpr, app); 2661 } 2662 } 2663 } 2664 2665 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2666 if (uid == Process.SYSTEM_UID) { 2667 // The system gets to run in any process. If there are multiple 2668 // processes with the same uid, just pick the first (this 2669 // should never happen). 2670 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2671 if (procs == null) return null; 2672 final int N = procs.size(); 2673 for (int i = 0; i < N; i++) { 2674 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2675 } 2676 } 2677 ProcessRecord proc = mProcessNames.get(processName, uid); 2678 if (false && proc != null && !keepIfLarge 2679 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2680 && proc.lastCachedPss >= 4000) { 2681 // Turn this condition on to cause killing to happen regularly, for testing. 2682 if (proc.baseProcessTracker != null) { 2683 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2684 } 2685 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2686 + "k from cached"); 2687 } else if (proc != null && !keepIfLarge 2688 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2689 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2690 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2691 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2692 if (proc.baseProcessTracker != null) { 2693 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2694 } 2695 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2696 + "k from cached"); 2697 } 2698 } 2699 return proc; 2700 } 2701 2702 void ensurePackageDexOpt(String packageName) { 2703 IPackageManager pm = AppGlobals.getPackageManager(); 2704 try { 2705 if (pm.performDexOpt(packageName)) { 2706 mDidDexOpt = true; 2707 } 2708 } catch (RemoteException e) { 2709 } 2710 } 2711 2712 boolean isNextTransitionForward() { 2713 int transit = mWindowManager.getPendingAppTransition(); 2714 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2715 || transit == AppTransition.TRANSIT_TASK_OPEN 2716 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2717 } 2718 2719 final ProcessRecord startProcessLocked(String processName, 2720 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2721 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2722 boolean isolated, boolean keepIfLarge) { 2723 ProcessRecord app; 2724 if (!isolated) { 2725 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2726 } else { 2727 // If this is an isolated process, it can't re-use an existing process. 2728 app = null; 2729 } 2730 // We don't have to do anything more if: 2731 // (1) There is an existing application record; and 2732 // (2) The caller doesn't think it is dead, OR there is no thread 2733 // object attached to it so we know it couldn't have crashed; and 2734 // (3) There is a pid assigned to it, so it is either starting or 2735 // already running. 2736 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2737 + " app=" + app + " knownToBeDead=" + knownToBeDead 2738 + " thread=" + (app != null ? app.thread : null) 2739 + " pid=" + (app != null ? app.pid : -1)); 2740 if (app != null && app.pid > 0) { 2741 if (!knownToBeDead || app.thread == null) { 2742 // We already have the app running, or are waiting for it to 2743 // come up (we have a pid but not yet its thread), so keep it. 2744 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2745 // If this is a new package in the process, add the package to the list 2746 app.addPackage(info.packageName, mProcessStats); 2747 return app; 2748 } 2749 2750 // An application record is attached to a previous process, 2751 // clean it up now. 2752 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2753 handleAppDiedLocked(app, true, true); 2754 } 2755 2756 String hostingNameStr = hostingName != null 2757 ? hostingName.flattenToShortString() : null; 2758 2759 if (!isolated) { 2760 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2761 // If we are in the background, then check to see if this process 2762 // is bad. If so, we will just silently fail. 2763 if (mBadProcesses.get(info.processName, info.uid) != null) { 2764 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2765 + "/" + info.processName); 2766 return null; 2767 } 2768 } else { 2769 // When the user is explicitly starting a process, then clear its 2770 // crash count so that we won't make it bad until they see at 2771 // least one crash dialog again, and make the process good again 2772 // if it had been bad. 2773 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2774 + "/" + info.processName); 2775 mProcessCrashTimes.remove(info.processName, info.uid); 2776 if (mBadProcesses.get(info.processName, info.uid) != null) { 2777 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2778 UserHandle.getUserId(info.uid), info.uid, 2779 info.processName); 2780 mBadProcesses.remove(info.processName, info.uid); 2781 if (app != null) { 2782 app.bad = false; 2783 } 2784 } 2785 } 2786 } 2787 2788 if (app == null) { 2789 app = newProcessRecordLocked(info, processName, isolated); 2790 if (app == null) { 2791 Slog.w(TAG, "Failed making new process record for " 2792 + processName + "/" + info.uid + " isolated=" + isolated); 2793 return null; 2794 } 2795 mProcessNames.put(processName, app.uid, app); 2796 if (isolated) { 2797 mIsolatedProcesses.put(app.uid, app); 2798 } 2799 } else { 2800 // If this is a new package in the process, add the package to the list 2801 app.addPackage(info.packageName, mProcessStats); 2802 } 2803 2804 // If the system is not ready yet, then hold off on starting this 2805 // process until it is. 2806 if (!mProcessesReady 2807 && !isAllowedWhileBooting(info) 2808 && !allowWhileBooting) { 2809 if (!mProcessesOnHold.contains(app)) { 2810 mProcessesOnHold.add(app); 2811 } 2812 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2813 return app; 2814 } 2815 2816 startProcessLocked(app, hostingType, hostingNameStr); 2817 return (app.pid != 0) ? app : null; 2818 } 2819 2820 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2821 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2822 } 2823 2824 private final void startProcessLocked(ProcessRecord app, 2825 String hostingType, String hostingNameStr) { 2826 if (app.pid > 0 && app.pid != MY_PID) { 2827 synchronized (mPidsSelfLocked) { 2828 mPidsSelfLocked.remove(app.pid); 2829 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2830 } 2831 app.setPid(0); 2832 } 2833 2834 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2835 "startProcessLocked removing on hold: " + app); 2836 mProcessesOnHold.remove(app); 2837 2838 updateCpuStats(); 2839 2840 try { 2841 int uid = app.uid; 2842 2843 int[] gids = null; 2844 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2845 if (!app.isolated) { 2846 int[] permGids = null; 2847 try { 2848 final PackageManager pm = mContext.getPackageManager(); 2849 permGids = pm.getPackageGids(app.info.packageName); 2850 2851 if (Environment.isExternalStorageEmulated()) { 2852 if (pm.checkPermission( 2853 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2854 app.info.packageName) == PERMISSION_GRANTED) { 2855 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2856 } else { 2857 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2858 } 2859 } 2860 } catch (PackageManager.NameNotFoundException e) { 2861 Slog.w(TAG, "Unable to retrieve gids", e); 2862 } 2863 2864 /* 2865 * Add shared application GID so applications can share some 2866 * resources like shared libraries 2867 */ 2868 if (permGids == null) { 2869 gids = new int[1]; 2870 } else { 2871 gids = new int[permGids.length + 1]; 2872 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2873 } 2874 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2875 } 2876 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2877 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2878 && mTopComponent != null 2879 && app.processName.equals(mTopComponent.getPackageName())) { 2880 uid = 0; 2881 } 2882 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2883 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2884 uid = 0; 2885 } 2886 } 2887 int debugFlags = 0; 2888 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2889 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2890 // Also turn on CheckJNI for debuggable apps. It's quite 2891 // awkward to turn on otherwise. 2892 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2893 } 2894 // Run the app in safe mode if its manifest requests so or the 2895 // system is booted in safe mode. 2896 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2897 mSafeMode == true) { 2898 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2899 } 2900 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2901 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2902 } 2903 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2904 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2905 } 2906 if ("1".equals(SystemProperties.get("debug.assert"))) { 2907 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2908 } 2909 2910 String requiredAbi = app.info.requiredCpuAbi; 2911 if (requiredAbi == null) { 2912 requiredAbi = Build.SUPPORTED_ABIS[0]; 2913 } 2914 2915 // Start the process. It will either succeed and return a result containing 2916 // the PID of the new process, or else throw a RuntimeException. 2917 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2918 app.processName, uid, uid, gids, debugFlags, mountExternal, 2919 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2920 2921 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2922 synchronized (bs) { 2923 if (bs.isOnBattery()) { 2924 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2925 } 2926 } 2927 2928 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2929 UserHandle.getUserId(uid), startResult.pid, uid, 2930 app.processName, hostingType, 2931 hostingNameStr != null ? hostingNameStr : ""); 2932 2933 if (app.persistent) { 2934 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2935 } 2936 2937 StringBuilder buf = mStringBuilder; 2938 buf.setLength(0); 2939 buf.append("Start proc "); 2940 buf.append(app.processName); 2941 buf.append(" for "); 2942 buf.append(hostingType); 2943 if (hostingNameStr != null) { 2944 buf.append(" "); 2945 buf.append(hostingNameStr); 2946 } 2947 buf.append(": pid="); 2948 buf.append(startResult.pid); 2949 buf.append(" uid="); 2950 buf.append(uid); 2951 buf.append(" gids={"); 2952 if (gids != null) { 2953 for (int gi=0; gi<gids.length; gi++) { 2954 if (gi != 0) buf.append(", "); 2955 buf.append(gids[gi]); 2956 2957 } 2958 } 2959 buf.append("}"); 2960 Slog.i(TAG, buf.toString()); 2961 app.setPid(startResult.pid); 2962 app.usingWrapper = startResult.usingWrapper; 2963 app.removed = false; 2964 synchronized (mPidsSelfLocked) { 2965 this.mPidsSelfLocked.put(startResult.pid, app); 2966 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2967 msg.obj = app; 2968 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2969 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2970 } 2971 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2972 app.processName, app.info.uid); 2973 if (app.isolated) { 2974 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2975 } 2976 } catch (RuntimeException e) { 2977 // XXX do better error recovery. 2978 app.setPid(0); 2979 Slog.e(TAG, "Failure starting process " + app.processName, e); 2980 } 2981 } 2982 2983 void updateUsageStats(ActivityRecord component, boolean resumed) { 2984 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2985 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2986 if (resumed) { 2987 mUsageStatsService.noteResumeComponent(component.realActivity); 2988 synchronized (stats) { 2989 stats.noteActivityResumedLocked(component.app.uid); 2990 } 2991 } else { 2992 mUsageStatsService.notePauseComponent(component.realActivity); 2993 synchronized (stats) { 2994 stats.noteActivityPausedLocked(component.app.uid); 2995 } 2996 } 2997 } 2998 2999 Intent getHomeIntent() { 3000 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3001 intent.setComponent(mTopComponent); 3002 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3003 intent.addCategory(Intent.CATEGORY_HOME); 3004 } 3005 return intent; 3006 } 3007 3008 boolean startHomeActivityLocked(int userId) { 3009 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3010 && mTopAction == null) { 3011 // We are running in factory test mode, but unable to find 3012 // the factory test app, so just sit around displaying the 3013 // error message and don't try to start anything. 3014 return false; 3015 } 3016 Intent intent = getHomeIntent(); 3017 ActivityInfo aInfo = 3018 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3019 if (aInfo != null) { 3020 intent.setComponent(new ComponentName( 3021 aInfo.applicationInfo.packageName, aInfo.name)); 3022 // Don't do this if the home app is currently being 3023 // instrumented. 3024 aInfo = new ActivityInfo(aInfo); 3025 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3026 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3027 aInfo.applicationInfo.uid, true); 3028 if (app == null || app.instrumentationClass == null) { 3029 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3030 mStackSupervisor.startHomeActivity(intent, aInfo); 3031 } 3032 } 3033 3034 return true; 3035 } 3036 3037 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3038 ActivityInfo ai = null; 3039 ComponentName comp = intent.getComponent(); 3040 try { 3041 if (comp != null) { 3042 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3043 } else { 3044 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3045 intent, 3046 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3047 flags, userId); 3048 3049 if (info != null) { 3050 ai = info.activityInfo; 3051 } 3052 } 3053 } catch (RemoteException e) { 3054 // ignore 3055 } 3056 3057 return ai; 3058 } 3059 3060 /** 3061 * Starts the "new version setup screen" if appropriate. 3062 */ 3063 void startSetupActivityLocked() { 3064 // Only do this once per boot. 3065 if (mCheckedForSetup) { 3066 return; 3067 } 3068 3069 // We will show this screen if the current one is a different 3070 // version than the last one shown, and we are not running in 3071 // low-level factory test mode. 3072 final ContentResolver resolver = mContext.getContentResolver(); 3073 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3074 Settings.Global.getInt(resolver, 3075 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3076 mCheckedForSetup = true; 3077 3078 // See if we should be showing the platform update setup UI. 3079 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3080 List<ResolveInfo> ris = mContext.getPackageManager() 3081 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3082 3083 // We don't allow third party apps to replace this. 3084 ResolveInfo ri = null; 3085 for (int i=0; ris != null && i<ris.size(); i++) { 3086 if ((ris.get(i).activityInfo.applicationInfo.flags 3087 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3088 ri = ris.get(i); 3089 break; 3090 } 3091 } 3092 3093 if (ri != null) { 3094 String vers = ri.activityInfo.metaData != null 3095 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3096 : null; 3097 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3098 vers = ri.activityInfo.applicationInfo.metaData.getString( 3099 Intent.METADATA_SETUP_VERSION); 3100 } 3101 String lastVers = Settings.Secure.getString( 3102 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3103 if (vers != null && !vers.equals(lastVers)) { 3104 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3105 intent.setComponent(new ComponentName( 3106 ri.activityInfo.packageName, ri.activityInfo.name)); 3107 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3108 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3109 } 3110 } 3111 } 3112 } 3113 3114 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3115 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3116 } 3117 3118 void enforceNotIsolatedCaller(String caller) { 3119 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3120 throw new SecurityException("Isolated process not allowed to call " + caller); 3121 } 3122 } 3123 3124 @Override 3125 public int getFrontActivityScreenCompatMode() { 3126 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3127 synchronized (this) { 3128 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3129 } 3130 } 3131 3132 @Override 3133 public void setFrontActivityScreenCompatMode(int mode) { 3134 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3135 "setFrontActivityScreenCompatMode"); 3136 synchronized (this) { 3137 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3138 } 3139 } 3140 3141 @Override 3142 public int getPackageScreenCompatMode(String packageName) { 3143 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3144 synchronized (this) { 3145 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3146 } 3147 } 3148 3149 @Override 3150 public void setPackageScreenCompatMode(String packageName, int mode) { 3151 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3152 "setPackageScreenCompatMode"); 3153 synchronized (this) { 3154 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3155 } 3156 } 3157 3158 @Override 3159 public boolean getPackageAskScreenCompat(String packageName) { 3160 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3161 synchronized (this) { 3162 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3163 } 3164 } 3165 3166 @Override 3167 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3168 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3169 "setPackageAskScreenCompat"); 3170 synchronized (this) { 3171 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3172 } 3173 } 3174 3175 private void dispatchProcessesChanged() { 3176 int N; 3177 synchronized (this) { 3178 N = mPendingProcessChanges.size(); 3179 if (mActiveProcessChanges.length < N) { 3180 mActiveProcessChanges = new ProcessChangeItem[N]; 3181 } 3182 mPendingProcessChanges.toArray(mActiveProcessChanges); 3183 mAvailProcessChanges.addAll(mPendingProcessChanges); 3184 mPendingProcessChanges.clear(); 3185 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3186 } 3187 3188 int i = mProcessObservers.beginBroadcast(); 3189 while (i > 0) { 3190 i--; 3191 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3192 if (observer != null) { 3193 try { 3194 for (int j=0; j<N; j++) { 3195 ProcessChangeItem item = mActiveProcessChanges[j]; 3196 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3197 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3198 + item.pid + " uid=" + item.uid + ": " 3199 + item.foregroundActivities); 3200 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3201 item.foregroundActivities); 3202 } 3203 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3204 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3205 + item.pid + " uid=" + item.uid + ": " + item.importance); 3206 observer.onImportanceChanged(item.pid, item.uid, 3207 item.importance); 3208 } 3209 } 3210 } catch (RemoteException e) { 3211 } 3212 } 3213 } 3214 mProcessObservers.finishBroadcast(); 3215 } 3216 3217 private void dispatchProcessDied(int pid, int uid) { 3218 int i = mProcessObservers.beginBroadcast(); 3219 while (i > 0) { 3220 i--; 3221 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3222 if (observer != null) { 3223 try { 3224 observer.onProcessDied(pid, uid); 3225 } catch (RemoteException e) { 3226 } 3227 } 3228 } 3229 mProcessObservers.finishBroadcast(); 3230 } 3231 3232 final void doPendingActivityLaunchesLocked(boolean doResume) { 3233 final int N = mPendingActivityLaunches.size(); 3234 if (N <= 0) { 3235 return; 3236 } 3237 for (int i=0; i<N; i++) { 3238 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3239 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3240 doResume && i == (N-1), null); 3241 } 3242 mPendingActivityLaunches.clear(); 3243 } 3244 3245 @Override 3246 public final int startActivity(IApplicationThread caller, String callingPackage, 3247 Intent intent, String resolvedType, IBinder resultTo, 3248 String resultWho, int requestCode, int startFlags, 3249 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3250 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3251 resultWho, requestCode, 3252 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3253 } 3254 3255 @Override 3256 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3257 Intent intent, String resolvedType, IBinder resultTo, 3258 String resultWho, int requestCode, int startFlags, 3259 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3260 enforceNotIsolatedCaller("startActivity"); 3261 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3262 false, true, "startActivity", null); 3263 // TODO: Switch to user app stacks here. 3264 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3265 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3266 null, null, options, userId, null); 3267 } 3268 3269 @Override 3270 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3271 Intent intent, String resolvedType, IBinder resultTo, 3272 String resultWho, int requestCode, int startFlags, String profileFile, 3273 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3274 enforceNotIsolatedCaller("startActivityAndWait"); 3275 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3276 false, true, "startActivityAndWait", null); 3277 WaitResult res = new WaitResult(); 3278 // TODO: Switch to user app stacks here. 3279 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3280 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3281 res, null, options, UserHandle.getCallingUserId(), null); 3282 return res; 3283 } 3284 3285 @Override 3286 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3287 Intent intent, String resolvedType, IBinder resultTo, 3288 String resultWho, int requestCode, int startFlags, Configuration config, 3289 Bundle options, int userId) { 3290 enforceNotIsolatedCaller("startActivityWithConfig"); 3291 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3292 false, true, "startActivityWithConfig", null); 3293 // TODO: Switch to user app stacks here. 3294 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3295 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3296 null, null, null, config, options, userId, null); 3297 return ret; 3298 } 3299 3300 @Override 3301 public int startActivityIntentSender(IApplicationThread caller, 3302 IntentSender intent, Intent fillInIntent, String resolvedType, 3303 IBinder resultTo, String resultWho, int requestCode, 3304 int flagsMask, int flagsValues, Bundle options) { 3305 enforceNotIsolatedCaller("startActivityIntentSender"); 3306 // Refuse possible leaked file descriptors 3307 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3308 throw new IllegalArgumentException("File descriptors passed in Intent"); 3309 } 3310 3311 IIntentSender sender = intent.getTarget(); 3312 if (!(sender instanceof PendingIntentRecord)) { 3313 throw new IllegalArgumentException("Bad PendingIntent object"); 3314 } 3315 3316 PendingIntentRecord pir = (PendingIntentRecord)sender; 3317 3318 synchronized (this) { 3319 // If this is coming from the currently resumed activity, it is 3320 // effectively saying that app switches are allowed at this point. 3321 final ActivityStack stack = getFocusedStack(); 3322 if (stack.mResumedActivity != null && 3323 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3324 mAppSwitchesAllowedTime = 0; 3325 } 3326 } 3327 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3328 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3329 return ret; 3330 } 3331 3332 @Override 3333 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3334 Intent intent, String resolvedType, IVoiceInteractionSession session, 3335 IVoiceInteractor interactor, int startFlags, String profileFile, 3336 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3337 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3338 != PackageManager.PERMISSION_GRANTED) { 3339 String msg = "Permission Denial: startVoiceActivity() from pid=" 3340 + Binder.getCallingPid() 3341 + ", uid=" + Binder.getCallingUid() 3342 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3343 Slog.w(TAG, msg); 3344 throw new SecurityException(msg); 3345 } 3346 if (session == null || interactor == null) { 3347 throw new NullPointerException("null session or interactor"); 3348 } 3349 userId = handleIncomingUser(callingPid, callingUid, userId, 3350 false, true, "startVoiceActivity", null); 3351 // TODO: Switch to user app stacks here. 3352 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3353 resolvedType, session, interactor, null, null, 0, startFlags, 3354 profileFile, profileFd, null, null, options, userId, null); 3355 } 3356 3357 @Override 3358 public boolean startNextMatchingActivity(IBinder callingActivity, 3359 Intent intent, Bundle options) { 3360 // Refuse possible leaked file descriptors 3361 if (intent != null && intent.hasFileDescriptors() == true) { 3362 throw new IllegalArgumentException("File descriptors passed in Intent"); 3363 } 3364 3365 synchronized (this) { 3366 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3367 if (r == null) { 3368 ActivityOptions.abort(options); 3369 return false; 3370 } 3371 if (r.app == null || r.app.thread == null) { 3372 // The caller is not running... d'oh! 3373 ActivityOptions.abort(options); 3374 return false; 3375 } 3376 intent = new Intent(intent); 3377 // The caller is not allowed to change the data. 3378 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3379 // And we are resetting to find the next component... 3380 intent.setComponent(null); 3381 3382 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3383 3384 ActivityInfo aInfo = null; 3385 try { 3386 List<ResolveInfo> resolves = 3387 AppGlobals.getPackageManager().queryIntentActivities( 3388 intent, r.resolvedType, 3389 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3390 UserHandle.getCallingUserId()); 3391 3392 // Look for the original activity in the list... 3393 final int N = resolves != null ? resolves.size() : 0; 3394 for (int i=0; i<N; i++) { 3395 ResolveInfo rInfo = resolves.get(i); 3396 if (rInfo.activityInfo.packageName.equals(r.packageName) 3397 && rInfo.activityInfo.name.equals(r.info.name)) { 3398 // We found the current one... the next matching is 3399 // after it. 3400 i++; 3401 if (i<N) { 3402 aInfo = resolves.get(i).activityInfo; 3403 } 3404 if (debug) { 3405 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3406 + "/" + r.info.name); 3407 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3408 + "/" + aInfo.name); 3409 } 3410 break; 3411 } 3412 } 3413 } catch (RemoteException e) { 3414 } 3415 3416 if (aInfo == null) { 3417 // Nobody who is next! 3418 ActivityOptions.abort(options); 3419 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3420 return false; 3421 } 3422 3423 intent.setComponent(new ComponentName( 3424 aInfo.applicationInfo.packageName, aInfo.name)); 3425 intent.setFlags(intent.getFlags()&~( 3426 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3427 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3428 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3429 Intent.FLAG_ACTIVITY_NEW_TASK)); 3430 3431 // Okay now we need to start the new activity, replacing the 3432 // currently running activity. This is a little tricky because 3433 // we want to start the new one as if the current one is finished, 3434 // but not finish the current one first so that there is no flicker. 3435 // And thus... 3436 final boolean wasFinishing = r.finishing; 3437 r.finishing = true; 3438 3439 // Propagate reply information over to the new activity. 3440 final ActivityRecord resultTo = r.resultTo; 3441 final String resultWho = r.resultWho; 3442 final int requestCode = r.requestCode; 3443 r.resultTo = null; 3444 if (resultTo != null) { 3445 resultTo.removeResultsLocked(r, resultWho, requestCode); 3446 } 3447 3448 final long origId = Binder.clearCallingIdentity(); 3449 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3450 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3451 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3452 options, false, null, null); 3453 Binder.restoreCallingIdentity(origId); 3454 3455 r.finishing = wasFinishing; 3456 if (res != ActivityManager.START_SUCCESS) { 3457 return false; 3458 } 3459 return true; 3460 } 3461 } 3462 3463 final int startActivityInPackage(int uid, String callingPackage, 3464 Intent intent, String resolvedType, IBinder resultTo, 3465 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3466 IActivityContainer container) { 3467 3468 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3469 false, true, "startActivityInPackage", null); 3470 3471 // TODO: Switch to user app stacks here. 3472 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3473 null, null, resultTo, resultWho, requestCode, startFlags, 3474 null, null, null, null, options, userId, container); 3475 return ret; 3476 } 3477 3478 @Override 3479 public final int startActivities(IApplicationThread caller, String callingPackage, 3480 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3481 int userId) { 3482 enforceNotIsolatedCaller("startActivities"); 3483 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3484 false, true, "startActivity", null); 3485 // TODO: Switch to user app stacks here. 3486 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3487 resolvedTypes, resultTo, options, userId); 3488 return ret; 3489 } 3490 3491 final int startActivitiesInPackage(int uid, String callingPackage, 3492 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3493 Bundle options, int userId) { 3494 3495 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3496 false, true, "startActivityInPackage", null); 3497 // TODO: Switch to user app stacks here. 3498 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3499 resultTo, options, userId); 3500 return ret; 3501 } 3502 3503 final void addRecentTaskLocked(TaskRecord task) { 3504 int N = mRecentTasks.size(); 3505 // Quick case: check if the top-most recent task is the same. 3506 if (N > 0 && mRecentTasks.get(0) == task) { 3507 return; 3508 } 3509 // Another quick case: never add voice sessions. 3510 if (task.voiceSession != null) { 3511 return; 3512 } 3513 // Remove any existing entries that are the same kind of task. 3514 final Intent intent = task.intent; 3515 final boolean document = intent != null && intent.isDocument(); 3516 for (int i=0; i<N; i++) { 3517 TaskRecord tr = mRecentTasks.get(i); 3518 if (task != tr) { 3519 if (task.userId != tr.userId) { 3520 continue; 3521 } 3522 final Intent trIntent = tr.intent; 3523 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3524 (intent == null || !intent.filterEquals(trIntent))) { 3525 continue; 3526 } 3527 if (document || trIntent != null && trIntent.isDocument()) { 3528 // Document tasks do not match other tasks. 3529 continue; 3530 } 3531 } 3532 3533 // Either task and tr are the same or, their affinities match or their intents match 3534 // and neither of them is a document. 3535 tr.disposeThumbnail(); 3536 mRecentTasks.remove(i); 3537 i--; 3538 N--; 3539 if (task.intent == null) { 3540 // If the new recent task we are adding is not fully 3541 // specified, then replace it with the existing recent task. 3542 task = tr; 3543 } 3544 } 3545 if (N >= MAX_RECENT_TASKS) { 3546 mRecentTasks.remove(N-1).disposeThumbnail(); 3547 } 3548 mRecentTasks.add(0, task); 3549 } 3550 3551 @Override 3552 public void reportActivityFullyDrawn(IBinder token) { 3553 synchronized (this) { 3554 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3555 if (r == null) { 3556 return; 3557 } 3558 r.reportFullyDrawnLocked(); 3559 } 3560 } 3561 3562 @Override 3563 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3564 synchronized (this) { 3565 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3566 if (r == null) { 3567 return; 3568 } 3569 final long origId = Binder.clearCallingIdentity(); 3570 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3571 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3572 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3573 if (config != null) { 3574 r.frozenBeforeDestroy = true; 3575 if (!updateConfigurationLocked(config, r, false, false)) { 3576 mStackSupervisor.resumeTopActivitiesLocked(); 3577 } 3578 } 3579 Binder.restoreCallingIdentity(origId); 3580 } 3581 } 3582 3583 @Override 3584 public int getRequestedOrientation(IBinder token) { 3585 synchronized (this) { 3586 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3587 if (r == null) { 3588 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3589 } 3590 return mWindowManager.getAppOrientation(r.appToken); 3591 } 3592 } 3593 3594 /** 3595 * This is the internal entry point for handling Activity.finish(). 3596 * 3597 * @param token The Binder token referencing the Activity we want to finish. 3598 * @param resultCode Result code, if any, from this Activity. 3599 * @param resultData Result data (Intent), if any, from this Activity. 3600 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3601 * the root Activity in the task. 3602 * 3603 * @return Returns true if the activity successfully finished, or false if it is still running. 3604 */ 3605 @Override 3606 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3607 boolean finishTask) { 3608 // Refuse possible leaked file descriptors 3609 if (resultData != null && resultData.hasFileDescriptors() == true) { 3610 throw new IllegalArgumentException("File descriptors passed in Intent"); 3611 } 3612 3613 synchronized(this) { 3614 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3615 if (r == null) { 3616 return true; 3617 } 3618 // Keep track of the root activity of the task before we finish it 3619 TaskRecord tr = r.task; 3620 ActivityRecord rootR = tr.getRootActivity(); 3621 if (mController != null) { 3622 // Find the first activity that is not finishing. 3623 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3624 if (next != null) { 3625 // ask watcher if this is allowed 3626 boolean resumeOK = true; 3627 try { 3628 resumeOK = mController.activityResuming(next.packageName); 3629 } catch (RemoteException e) { 3630 mController = null; 3631 Watchdog.getInstance().setActivityController(null); 3632 } 3633 3634 if (!resumeOK) { 3635 return false; 3636 } 3637 } 3638 } 3639 final long origId = Binder.clearCallingIdentity(); 3640 try { 3641 boolean res; 3642 if (finishTask && r == rootR) { 3643 // If requested, remove the task that is associated to this activity only if it 3644 // was the root activity in the task. The result code and data is ignored because 3645 // we don't support returning them across task boundaries. 3646 res = removeTaskByIdLocked(tr.taskId, 0); 3647 } else { 3648 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3649 resultData, "app-request", true); 3650 } 3651 return res; 3652 } finally { 3653 Binder.restoreCallingIdentity(origId); 3654 } 3655 } 3656 } 3657 3658 @Override 3659 public final void finishHeavyWeightApp() { 3660 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3661 != PackageManager.PERMISSION_GRANTED) { 3662 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3663 + Binder.getCallingPid() 3664 + ", uid=" + Binder.getCallingUid() 3665 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3666 Slog.w(TAG, msg); 3667 throw new SecurityException(msg); 3668 } 3669 3670 synchronized(this) { 3671 if (mHeavyWeightProcess == null) { 3672 return; 3673 } 3674 3675 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3676 mHeavyWeightProcess.activities); 3677 for (int i=0; i<activities.size(); i++) { 3678 ActivityRecord r = activities.get(i); 3679 if (!r.finishing) { 3680 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3681 null, "finish-heavy", true); 3682 } 3683 } 3684 3685 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3686 mHeavyWeightProcess.userId, 0)); 3687 mHeavyWeightProcess = null; 3688 } 3689 } 3690 3691 @Override 3692 public void crashApplication(int uid, int initialPid, String packageName, 3693 String message) { 3694 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3695 != PackageManager.PERMISSION_GRANTED) { 3696 String msg = "Permission Denial: crashApplication() from pid=" 3697 + Binder.getCallingPid() 3698 + ", uid=" + Binder.getCallingUid() 3699 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3700 Slog.w(TAG, msg); 3701 throw new SecurityException(msg); 3702 } 3703 3704 synchronized(this) { 3705 ProcessRecord proc = null; 3706 3707 // Figure out which process to kill. We don't trust that initialPid 3708 // still has any relation to current pids, so must scan through the 3709 // list. 3710 synchronized (mPidsSelfLocked) { 3711 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3712 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3713 if (p.uid != uid) { 3714 continue; 3715 } 3716 if (p.pid == initialPid) { 3717 proc = p; 3718 break; 3719 } 3720 if (p.pkgList.containsKey(packageName)) { 3721 proc = p; 3722 } 3723 } 3724 } 3725 3726 if (proc == null) { 3727 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3728 + " initialPid=" + initialPid 3729 + " packageName=" + packageName); 3730 return; 3731 } 3732 3733 if (proc.thread != null) { 3734 if (proc.pid == Process.myPid()) { 3735 Log.w(TAG, "crashApplication: trying to crash self!"); 3736 return; 3737 } 3738 long ident = Binder.clearCallingIdentity(); 3739 try { 3740 proc.thread.scheduleCrash(message); 3741 } catch (RemoteException e) { 3742 } 3743 Binder.restoreCallingIdentity(ident); 3744 } 3745 } 3746 } 3747 3748 @Override 3749 public final void finishSubActivity(IBinder token, String resultWho, 3750 int requestCode) { 3751 synchronized(this) { 3752 final long origId = Binder.clearCallingIdentity(); 3753 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3754 if (r != null) { 3755 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3756 } 3757 Binder.restoreCallingIdentity(origId); 3758 } 3759 } 3760 3761 @Override 3762 public boolean finishActivityAffinity(IBinder token) { 3763 synchronized(this) { 3764 final long origId = Binder.clearCallingIdentity(); 3765 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3766 boolean res = false; 3767 if (r != null) { 3768 res = r.task.stack.finishActivityAffinityLocked(r); 3769 } 3770 Binder.restoreCallingIdentity(origId); 3771 return res; 3772 } 3773 } 3774 3775 @Override 3776 public boolean willActivityBeVisible(IBinder token) { 3777 synchronized(this) { 3778 ActivityStack stack = ActivityRecord.getStackLocked(token); 3779 if (stack != null) { 3780 return stack.willActivityBeVisibleLocked(token); 3781 } 3782 return false; 3783 } 3784 } 3785 3786 @Override 3787 public void overridePendingTransition(IBinder token, String packageName, 3788 int enterAnim, int exitAnim) { 3789 synchronized(this) { 3790 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3791 if (self == null) { 3792 return; 3793 } 3794 3795 final long origId = Binder.clearCallingIdentity(); 3796 3797 if (self.state == ActivityState.RESUMED 3798 || self.state == ActivityState.PAUSING) { 3799 mWindowManager.overridePendingAppTransition(packageName, 3800 enterAnim, exitAnim, null); 3801 } 3802 3803 Binder.restoreCallingIdentity(origId); 3804 } 3805 } 3806 3807 /** 3808 * Main function for removing an existing process from the activity manager 3809 * as a result of that process going away. Clears out all connections 3810 * to the process. 3811 */ 3812 private final void handleAppDiedLocked(ProcessRecord app, 3813 boolean restarting, boolean allowRestart) { 3814 int pid = app.pid; 3815 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3816 if (!restarting) { 3817 removeLruProcessLocked(app); 3818 if (pid > 0) { 3819 ProcessList.remove(pid); 3820 } 3821 } 3822 3823 if (mProfileProc == app) { 3824 clearProfilerLocked(); 3825 } 3826 3827 // Remove this application's activities from active lists. 3828 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3829 3830 app.activities.clear(); 3831 3832 if (app.instrumentationClass != null) { 3833 Slog.w(TAG, "Crash of app " + app.processName 3834 + " running instrumentation " + app.instrumentationClass); 3835 Bundle info = new Bundle(); 3836 info.putString("shortMsg", "Process crashed."); 3837 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3838 } 3839 3840 if (!restarting) { 3841 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3842 // If there was nothing to resume, and we are not already 3843 // restarting this process, but there is a visible activity that 3844 // is hosted by the process... then make sure all visible 3845 // activities are running, taking care of restarting this 3846 // process. 3847 if (hasVisibleActivities) { 3848 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3849 } 3850 } 3851 } 3852 } 3853 3854 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3855 IBinder threadBinder = thread.asBinder(); 3856 // Find the application record. 3857 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3858 ProcessRecord rec = mLruProcesses.get(i); 3859 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3860 return i; 3861 } 3862 } 3863 return -1; 3864 } 3865 3866 final ProcessRecord getRecordForAppLocked( 3867 IApplicationThread thread) { 3868 if (thread == null) { 3869 return null; 3870 } 3871 3872 int appIndex = getLRURecordIndexForAppLocked(thread); 3873 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3874 } 3875 3876 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3877 // If there are no longer any background processes running, 3878 // and the app that died was not running instrumentation, 3879 // then tell everyone we are now low on memory. 3880 boolean haveBg = false; 3881 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3882 ProcessRecord rec = mLruProcesses.get(i); 3883 if (rec.thread != null 3884 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3885 haveBg = true; 3886 break; 3887 } 3888 } 3889 3890 if (!haveBg) { 3891 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3892 if (doReport) { 3893 long now = SystemClock.uptimeMillis(); 3894 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3895 doReport = false; 3896 } else { 3897 mLastMemUsageReportTime = now; 3898 } 3899 } 3900 final ArrayList<ProcessMemInfo> memInfos 3901 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3902 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3903 long now = SystemClock.uptimeMillis(); 3904 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3905 ProcessRecord rec = mLruProcesses.get(i); 3906 if (rec == dyingProc || rec.thread == null) { 3907 continue; 3908 } 3909 if (doReport) { 3910 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3911 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3912 } 3913 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3914 // The low memory report is overriding any current 3915 // state for a GC request. Make sure to do 3916 // heavy/important/visible/foreground processes first. 3917 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3918 rec.lastRequestedGc = 0; 3919 } else { 3920 rec.lastRequestedGc = rec.lastLowMemory; 3921 } 3922 rec.reportLowMemory = true; 3923 rec.lastLowMemory = now; 3924 mProcessesToGc.remove(rec); 3925 addProcessToGcListLocked(rec); 3926 } 3927 } 3928 if (doReport) { 3929 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3930 mHandler.sendMessage(msg); 3931 } 3932 scheduleAppGcsLocked(); 3933 } 3934 } 3935 3936 final void appDiedLocked(ProcessRecord app, int pid, 3937 IApplicationThread thread) { 3938 3939 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3940 synchronized (stats) { 3941 stats.noteProcessDiedLocked(app.info.uid, pid); 3942 } 3943 3944 // Clean up already done if the process has been re-started. 3945 if (app.pid == pid && app.thread != null && 3946 app.thread.asBinder() == thread.asBinder()) { 3947 boolean doLowMem = app.instrumentationClass == null; 3948 boolean doOomAdj = doLowMem; 3949 if (!app.killedByAm) { 3950 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3951 + ") has died."); 3952 mAllowLowerMemLevel = true; 3953 } else { 3954 // Note that we always want to do oom adj to update our state with the 3955 // new number of procs. 3956 mAllowLowerMemLevel = false; 3957 doLowMem = false; 3958 } 3959 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3960 if (DEBUG_CLEANUP) Slog.v( 3961 TAG, "Dying app: " + app + ", pid: " + pid 3962 + ", thread: " + thread.asBinder()); 3963 handleAppDiedLocked(app, false, true); 3964 3965 if (doOomAdj) { 3966 updateOomAdjLocked(); 3967 } 3968 if (doLowMem) { 3969 doLowMemReportIfNeededLocked(app); 3970 } 3971 } else if (app.pid != pid) { 3972 // A new process has already been started. 3973 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3974 + ") has died and restarted (pid " + app.pid + ")."); 3975 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3976 } else if (DEBUG_PROCESSES) { 3977 Slog.d(TAG, "Received spurious death notification for thread " 3978 + thread.asBinder()); 3979 } 3980 } 3981 3982 /** 3983 * If a stack trace dump file is configured, dump process stack traces. 3984 * @param clearTraces causes the dump file to be erased prior to the new 3985 * traces being written, if true; when false, the new traces will be 3986 * appended to any existing file content. 3987 * @param firstPids of dalvik VM processes to dump stack traces for first 3988 * @param lastPids of dalvik VM processes to dump stack traces for last 3989 * @param nativeProcs optional list of native process names to dump stack crawls 3990 * @return file containing stack traces, or null if no dump file is configured 3991 */ 3992 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3993 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3994 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3995 if (tracesPath == null || tracesPath.length() == 0) { 3996 return null; 3997 } 3998 3999 File tracesFile = new File(tracesPath); 4000 try { 4001 File tracesDir = tracesFile.getParentFile(); 4002 if (!tracesDir.exists()) { 4003 tracesFile.mkdirs(); 4004 if (!SELinux.restorecon(tracesDir)) { 4005 return null; 4006 } 4007 } 4008 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4009 4010 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4011 tracesFile.createNewFile(); 4012 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4013 } catch (IOException e) { 4014 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4015 return null; 4016 } 4017 4018 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4019 return tracesFile; 4020 } 4021 4022 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4023 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4024 // Use a FileObserver to detect when traces finish writing. 4025 // The order of traces is considered important to maintain for legibility. 4026 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4027 @Override 4028 public synchronized void onEvent(int event, String path) { notify(); } 4029 }; 4030 4031 try { 4032 observer.startWatching(); 4033 4034 // First collect all of the stacks of the most important pids. 4035 if (firstPids != null) { 4036 try { 4037 int num = firstPids.size(); 4038 for (int i = 0; i < num; i++) { 4039 synchronized (observer) { 4040 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4041 observer.wait(200); // Wait for write-close, give up after 200msec 4042 } 4043 } 4044 } catch (InterruptedException e) { 4045 Log.wtf(TAG, e); 4046 } 4047 } 4048 4049 // Next collect the stacks of the native pids 4050 if (nativeProcs != null) { 4051 int[] pids = Process.getPidsForCommands(nativeProcs); 4052 if (pids != null) { 4053 for (int pid : pids) { 4054 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4055 } 4056 } 4057 } 4058 4059 // Lastly, measure CPU usage. 4060 if (processCpuTracker != null) { 4061 processCpuTracker.init(); 4062 System.gc(); 4063 processCpuTracker.update(); 4064 try { 4065 synchronized (processCpuTracker) { 4066 processCpuTracker.wait(500); // measure over 1/2 second. 4067 } 4068 } catch (InterruptedException e) { 4069 } 4070 processCpuTracker.update(); 4071 4072 // We'll take the stack crawls of just the top apps using CPU. 4073 final int N = processCpuTracker.countWorkingStats(); 4074 int numProcs = 0; 4075 for (int i=0; i<N && numProcs<5; i++) { 4076 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4077 if (lastPids.indexOfKey(stats.pid) >= 0) { 4078 numProcs++; 4079 try { 4080 synchronized (observer) { 4081 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4082 observer.wait(200); // Wait for write-close, give up after 200msec 4083 } 4084 } catch (InterruptedException e) { 4085 Log.wtf(TAG, e); 4086 } 4087 4088 } 4089 } 4090 } 4091 } finally { 4092 observer.stopWatching(); 4093 } 4094 } 4095 4096 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4097 if (true || IS_USER_BUILD) { 4098 return; 4099 } 4100 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4101 if (tracesPath == null || tracesPath.length() == 0) { 4102 return; 4103 } 4104 4105 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4106 StrictMode.allowThreadDiskWrites(); 4107 try { 4108 final File tracesFile = new File(tracesPath); 4109 final File tracesDir = tracesFile.getParentFile(); 4110 final File tracesTmp = new File(tracesDir, "__tmp__"); 4111 try { 4112 if (!tracesDir.exists()) { 4113 tracesFile.mkdirs(); 4114 if (!SELinux.restorecon(tracesDir.getPath())) { 4115 return; 4116 } 4117 } 4118 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4119 4120 if (tracesFile.exists()) { 4121 tracesTmp.delete(); 4122 tracesFile.renameTo(tracesTmp); 4123 } 4124 StringBuilder sb = new StringBuilder(); 4125 Time tobj = new Time(); 4126 tobj.set(System.currentTimeMillis()); 4127 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4128 sb.append(": "); 4129 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4130 sb.append(" since "); 4131 sb.append(msg); 4132 FileOutputStream fos = new FileOutputStream(tracesFile); 4133 fos.write(sb.toString().getBytes()); 4134 if (app == null) { 4135 fos.write("\n*** No application process!".getBytes()); 4136 } 4137 fos.close(); 4138 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4139 } catch (IOException e) { 4140 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4141 return; 4142 } 4143 4144 if (app != null) { 4145 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4146 firstPids.add(app.pid); 4147 dumpStackTraces(tracesPath, firstPids, null, null, null); 4148 } 4149 4150 File lastTracesFile = null; 4151 File curTracesFile = null; 4152 for (int i=9; i>=0; i--) { 4153 String name = String.format(Locale.US, "slow%02d.txt", i); 4154 curTracesFile = new File(tracesDir, name); 4155 if (curTracesFile.exists()) { 4156 if (lastTracesFile != null) { 4157 curTracesFile.renameTo(lastTracesFile); 4158 } else { 4159 curTracesFile.delete(); 4160 } 4161 } 4162 lastTracesFile = curTracesFile; 4163 } 4164 tracesFile.renameTo(curTracesFile); 4165 if (tracesTmp.exists()) { 4166 tracesTmp.renameTo(tracesFile); 4167 } 4168 } finally { 4169 StrictMode.setThreadPolicy(oldPolicy); 4170 } 4171 } 4172 4173 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4174 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4175 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4176 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4177 4178 if (mController != null) { 4179 try { 4180 // 0 == continue, -1 = kill process immediately 4181 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4182 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4183 } catch (RemoteException e) { 4184 mController = null; 4185 Watchdog.getInstance().setActivityController(null); 4186 } 4187 } 4188 4189 long anrTime = SystemClock.uptimeMillis(); 4190 if (MONITOR_CPU_USAGE) { 4191 updateCpuStatsNow(); 4192 } 4193 4194 synchronized (this) { 4195 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4196 if (mShuttingDown) { 4197 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4198 return; 4199 } else if (app.notResponding) { 4200 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4201 return; 4202 } else if (app.crashing) { 4203 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4204 return; 4205 } 4206 4207 // In case we come through here for the same app before completing 4208 // this one, mark as anring now so we will bail out. 4209 app.notResponding = true; 4210 4211 // Log the ANR to the event log. 4212 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4213 app.processName, app.info.flags, annotation); 4214 4215 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4216 firstPids.add(app.pid); 4217 4218 int parentPid = app.pid; 4219 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4220 if (parentPid != app.pid) firstPids.add(parentPid); 4221 4222 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4223 4224 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4225 ProcessRecord r = mLruProcesses.get(i); 4226 if (r != null && r.thread != null) { 4227 int pid = r.pid; 4228 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4229 if (r.persistent) { 4230 firstPids.add(pid); 4231 } else { 4232 lastPids.put(pid, Boolean.TRUE); 4233 } 4234 } 4235 } 4236 } 4237 } 4238 4239 // Log the ANR to the main log. 4240 StringBuilder info = new StringBuilder(); 4241 info.setLength(0); 4242 info.append("ANR in ").append(app.processName); 4243 if (activity != null && activity.shortComponentName != null) { 4244 info.append(" (").append(activity.shortComponentName).append(")"); 4245 } 4246 info.append("\n"); 4247 info.append("PID: ").append(app.pid).append("\n"); 4248 if (annotation != null) { 4249 info.append("Reason: ").append(annotation).append("\n"); 4250 } 4251 if (parent != null && parent != activity) { 4252 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4253 } 4254 4255 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4256 4257 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4258 NATIVE_STACKS_OF_INTEREST); 4259 4260 String cpuInfo = null; 4261 if (MONITOR_CPU_USAGE) { 4262 updateCpuStatsNow(); 4263 synchronized (mProcessCpuThread) { 4264 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4265 } 4266 info.append(processCpuTracker.printCurrentLoad()); 4267 info.append(cpuInfo); 4268 } 4269 4270 info.append(processCpuTracker.printCurrentState(anrTime)); 4271 4272 Slog.e(TAG, info.toString()); 4273 if (tracesFile == null) { 4274 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4275 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4276 } 4277 4278 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4279 cpuInfo, tracesFile, null); 4280 4281 if (mController != null) { 4282 try { 4283 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4284 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4285 if (res != 0) { 4286 if (res < 0 && app.pid != MY_PID) { 4287 Process.killProcess(app.pid); 4288 } else { 4289 synchronized (this) { 4290 mServices.scheduleServiceTimeoutLocked(app); 4291 } 4292 } 4293 return; 4294 } 4295 } catch (RemoteException e) { 4296 mController = null; 4297 Watchdog.getInstance().setActivityController(null); 4298 } 4299 } 4300 4301 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4302 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4303 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4304 4305 synchronized (this) { 4306 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4307 killUnneededProcessLocked(app, "background ANR"); 4308 return; 4309 } 4310 4311 // Set the app's notResponding state, and look up the errorReportReceiver 4312 makeAppNotRespondingLocked(app, 4313 activity != null ? activity.shortComponentName : null, 4314 annotation != null ? "ANR " + annotation : "ANR", 4315 info.toString()); 4316 4317 // Bring up the infamous App Not Responding dialog 4318 Message msg = Message.obtain(); 4319 HashMap<String, Object> map = new HashMap<String, Object>(); 4320 msg.what = SHOW_NOT_RESPONDING_MSG; 4321 msg.obj = map; 4322 msg.arg1 = aboveSystem ? 1 : 0; 4323 map.put("app", app); 4324 if (activity != null) { 4325 map.put("activity", activity); 4326 } 4327 4328 mHandler.sendMessage(msg); 4329 } 4330 } 4331 4332 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4333 if (!mLaunchWarningShown) { 4334 mLaunchWarningShown = true; 4335 mHandler.post(new Runnable() { 4336 @Override 4337 public void run() { 4338 synchronized (ActivityManagerService.this) { 4339 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4340 d.show(); 4341 mHandler.postDelayed(new Runnable() { 4342 @Override 4343 public void run() { 4344 synchronized (ActivityManagerService.this) { 4345 d.dismiss(); 4346 mLaunchWarningShown = false; 4347 } 4348 } 4349 }, 4000); 4350 } 4351 } 4352 }); 4353 } 4354 } 4355 4356 @Override 4357 public boolean clearApplicationUserData(final String packageName, 4358 final IPackageDataObserver observer, int userId) { 4359 enforceNotIsolatedCaller("clearApplicationUserData"); 4360 int uid = Binder.getCallingUid(); 4361 int pid = Binder.getCallingPid(); 4362 userId = handleIncomingUser(pid, uid, 4363 userId, false, true, "clearApplicationUserData", null); 4364 long callingId = Binder.clearCallingIdentity(); 4365 try { 4366 IPackageManager pm = AppGlobals.getPackageManager(); 4367 int pkgUid = -1; 4368 synchronized(this) { 4369 try { 4370 pkgUid = pm.getPackageUid(packageName, userId); 4371 } catch (RemoteException e) { 4372 } 4373 if (pkgUid == -1) { 4374 Slog.w(TAG, "Invalid packageName: " + packageName); 4375 if (observer != null) { 4376 try { 4377 observer.onRemoveCompleted(packageName, false); 4378 } catch (RemoteException e) { 4379 Slog.i(TAG, "Observer no longer exists."); 4380 } 4381 } 4382 return false; 4383 } 4384 if (uid == pkgUid || checkComponentPermission( 4385 android.Manifest.permission.CLEAR_APP_USER_DATA, 4386 pid, uid, -1, true) 4387 == PackageManager.PERMISSION_GRANTED) { 4388 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4389 } else { 4390 throw new SecurityException("PID " + pid + " does not have permission " 4391 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4392 + " of package " + packageName); 4393 } 4394 } 4395 4396 try { 4397 // Clear application user data 4398 pm.clearApplicationUserData(packageName, observer, userId); 4399 4400 // Remove all permissions granted from/to this package 4401 removeUriPermissionsForPackageLocked(packageName, userId, true); 4402 4403 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4404 Uri.fromParts("package", packageName, null)); 4405 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4406 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4407 null, null, 0, null, null, null, false, false, userId); 4408 } catch (RemoteException e) { 4409 } 4410 } finally { 4411 Binder.restoreCallingIdentity(callingId); 4412 } 4413 return true; 4414 } 4415 4416 @Override 4417 public void killBackgroundProcesses(final String packageName, int userId) { 4418 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4419 != PackageManager.PERMISSION_GRANTED && 4420 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4421 != PackageManager.PERMISSION_GRANTED) { 4422 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4423 + Binder.getCallingPid() 4424 + ", uid=" + Binder.getCallingUid() 4425 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4426 Slog.w(TAG, msg); 4427 throw new SecurityException(msg); 4428 } 4429 4430 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4431 userId, true, true, "killBackgroundProcesses", null); 4432 long callingId = Binder.clearCallingIdentity(); 4433 try { 4434 IPackageManager pm = AppGlobals.getPackageManager(); 4435 synchronized(this) { 4436 int appId = -1; 4437 try { 4438 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4439 } catch (RemoteException e) { 4440 } 4441 if (appId == -1) { 4442 Slog.w(TAG, "Invalid packageName: " + packageName); 4443 return; 4444 } 4445 killPackageProcessesLocked(packageName, appId, userId, 4446 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4447 } 4448 } finally { 4449 Binder.restoreCallingIdentity(callingId); 4450 } 4451 } 4452 4453 @Override 4454 public void killAllBackgroundProcesses() { 4455 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4456 != PackageManager.PERMISSION_GRANTED) { 4457 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4458 + Binder.getCallingPid() 4459 + ", uid=" + Binder.getCallingUid() 4460 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4461 Slog.w(TAG, msg); 4462 throw new SecurityException(msg); 4463 } 4464 4465 long callingId = Binder.clearCallingIdentity(); 4466 try { 4467 synchronized(this) { 4468 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4469 final int NP = mProcessNames.getMap().size(); 4470 for (int ip=0; ip<NP; ip++) { 4471 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4472 final int NA = apps.size(); 4473 for (int ia=0; ia<NA; ia++) { 4474 ProcessRecord app = apps.valueAt(ia); 4475 if (app.persistent) { 4476 // we don't kill persistent processes 4477 continue; 4478 } 4479 if (app.removed) { 4480 procs.add(app); 4481 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4482 app.removed = true; 4483 procs.add(app); 4484 } 4485 } 4486 } 4487 4488 int N = procs.size(); 4489 for (int i=0; i<N; i++) { 4490 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4491 } 4492 mAllowLowerMemLevel = true; 4493 updateOomAdjLocked(); 4494 doLowMemReportIfNeededLocked(null); 4495 } 4496 } finally { 4497 Binder.restoreCallingIdentity(callingId); 4498 } 4499 } 4500 4501 @Override 4502 public void forceStopPackage(final String packageName, int userId) { 4503 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4504 != PackageManager.PERMISSION_GRANTED) { 4505 String msg = "Permission Denial: forceStopPackage() from pid=" 4506 + Binder.getCallingPid() 4507 + ", uid=" + Binder.getCallingUid() 4508 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4509 Slog.w(TAG, msg); 4510 throw new SecurityException(msg); 4511 } 4512 final int callingPid = Binder.getCallingPid(); 4513 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4514 userId, true, true, "forceStopPackage", null); 4515 long callingId = Binder.clearCallingIdentity(); 4516 try { 4517 IPackageManager pm = AppGlobals.getPackageManager(); 4518 synchronized(this) { 4519 int[] users = userId == UserHandle.USER_ALL 4520 ? getUsersLocked() : new int[] { userId }; 4521 for (int user : users) { 4522 int pkgUid = -1; 4523 try { 4524 pkgUid = pm.getPackageUid(packageName, user); 4525 } catch (RemoteException e) { 4526 } 4527 if (pkgUid == -1) { 4528 Slog.w(TAG, "Invalid packageName: " + packageName); 4529 continue; 4530 } 4531 try { 4532 pm.setPackageStoppedState(packageName, true, user); 4533 } catch (RemoteException e) { 4534 } catch (IllegalArgumentException e) { 4535 Slog.w(TAG, "Failed trying to unstop package " 4536 + packageName + ": " + e); 4537 } 4538 if (isUserRunningLocked(user, false)) { 4539 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4540 } 4541 } 4542 } 4543 } finally { 4544 Binder.restoreCallingIdentity(callingId); 4545 } 4546 } 4547 4548 /* 4549 * The pkg name and app id have to be specified. 4550 */ 4551 @Override 4552 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4553 if (pkg == null) { 4554 return; 4555 } 4556 // Make sure the uid is valid. 4557 if (appid < 0) { 4558 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4559 return; 4560 } 4561 int callerUid = Binder.getCallingUid(); 4562 // Only the system server can kill an application 4563 if (callerUid == Process.SYSTEM_UID) { 4564 // Post an aysnc message to kill the application 4565 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4566 msg.arg1 = appid; 4567 msg.arg2 = 0; 4568 Bundle bundle = new Bundle(); 4569 bundle.putString("pkg", pkg); 4570 bundle.putString("reason", reason); 4571 msg.obj = bundle; 4572 mHandler.sendMessage(msg); 4573 } else { 4574 throw new SecurityException(callerUid + " cannot kill pkg: " + 4575 pkg); 4576 } 4577 } 4578 4579 @Override 4580 public void closeSystemDialogs(String reason) { 4581 enforceNotIsolatedCaller("closeSystemDialogs"); 4582 4583 final int pid = Binder.getCallingPid(); 4584 final int uid = Binder.getCallingUid(); 4585 final long origId = Binder.clearCallingIdentity(); 4586 try { 4587 synchronized (this) { 4588 // Only allow this from foreground processes, so that background 4589 // applications can't abuse it to prevent system UI from being shown. 4590 if (uid >= Process.FIRST_APPLICATION_UID) { 4591 ProcessRecord proc; 4592 synchronized (mPidsSelfLocked) { 4593 proc = mPidsSelfLocked.get(pid); 4594 } 4595 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4596 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4597 + " from background process " + proc); 4598 return; 4599 } 4600 } 4601 closeSystemDialogsLocked(reason); 4602 } 4603 } finally { 4604 Binder.restoreCallingIdentity(origId); 4605 } 4606 } 4607 4608 void closeSystemDialogsLocked(String reason) { 4609 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4610 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4611 | Intent.FLAG_RECEIVER_FOREGROUND); 4612 if (reason != null) { 4613 intent.putExtra("reason", reason); 4614 } 4615 mWindowManager.closeSystemDialogs(reason); 4616 4617 mStackSupervisor.closeSystemDialogsLocked(); 4618 4619 broadcastIntentLocked(null, null, intent, null, 4620 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4621 Process.SYSTEM_UID, UserHandle.USER_ALL); 4622 } 4623 4624 @Override 4625 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4626 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4627 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4628 for (int i=pids.length-1; i>=0; i--) { 4629 ProcessRecord proc; 4630 int oomAdj; 4631 synchronized (this) { 4632 synchronized (mPidsSelfLocked) { 4633 proc = mPidsSelfLocked.get(pids[i]); 4634 oomAdj = proc != null ? proc.setAdj : 0; 4635 } 4636 } 4637 infos[i] = new Debug.MemoryInfo(); 4638 Debug.getMemoryInfo(pids[i], infos[i]); 4639 if (proc != null) { 4640 synchronized (this) { 4641 if (proc.thread != null && proc.setAdj == oomAdj) { 4642 // Record this for posterity if the process has been stable. 4643 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4644 infos[i].getTotalUss(), false, proc.pkgList); 4645 } 4646 } 4647 } 4648 } 4649 return infos; 4650 } 4651 4652 @Override 4653 public long[] getProcessPss(int[] pids) { 4654 enforceNotIsolatedCaller("getProcessPss"); 4655 long[] pss = new long[pids.length]; 4656 for (int i=pids.length-1; i>=0; i--) { 4657 ProcessRecord proc; 4658 int oomAdj; 4659 synchronized (this) { 4660 synchronized (mPidsSelfLocked) { 4661 proc = mPidsSelfLocked.get(pids[i]); 4662 oomAdj = proc != null ? proc.setAdj : 0; 4663 } 4664 } 4665 long[] tmpUss = new long[1]; 4666 pss[i] = Debug.getPss(pids[i], tmpUss); 4667 if (proc != null) { 4668 synchronized (this) { 4669 if (proc.thread != null && proc.setAdj == oomAdj) { 4670 // Record this for posterity if the process has been stable. 4671 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4672 } 4673 } 4674 } 4675 } 4676 return pss; 4677 } 4678 4679 @Override 4680 public void killApplicationProcess(String processName, int uid) { 4681 if (processName == null) { 4682 return; 4683 } 4684 4685 int callerUid = Binder.getCallingUid(); 4686 // Only the system server can kill an application 4687 if (callerUid == Process.SYSTEM_UID) { 4688 synchronized (this) { 4689 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4690 if (app != null && app.thread != null) { 4691 try { 4692 app.thread.scheduleSuicide(); 4693 } catch (RemoteException e) { 4694 // If the other end already died, then our work here is done. 4695 } 4696 } else { 4697 Slog.w(TAG, "Process/uid not found attempting kill of " 4698 + processName + " / " + uid); 4699 } 4700 } 4701 } else { 4702 throw new SecurityException(callerUid + " cannot kill app process: " + 4703 processName); 4704 } 4705 } 4706 4707 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4708 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4709 false, true, false, false, UserHandle.getUserId(uid), reason); 4710 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4711 Uri.fromParts("package", packageName, null)); 4712 if (!mProcessesReady) { 4713 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4714 | Intent.FLAG_RECEIVER_FOREGROUND); 4715 } 4716 intent.putExtra(Intent.EXTRA_UID, uid); 4717 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4718 broadcastIntentLocked(null, null, intent, 4719 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4720 false, false, 4721 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4722 } 4723 4724 private void forceStopUserLocked(int userId, String reason) { 4725 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4726 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4727 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4728 | Intent.FLAG_RECEIVER_FOREGROUND); 4729 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4730 broadcastIntentLocked(null, null, intent, 4731 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4732 false, false, 4733 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4734 } 4735 4736 private final boolean killPackageProcessesLocked(String packageName, int appId, 4737 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4738 boolean doit, boolean evenPersistent, String reason) { 4739 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4740 4741 // Remove all processes this package may have touched: all with the 4742 // same UID (except for the system or root user), and all whose name 4743 // matches the package name. 4744 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4745 final int NP = mProcessNames.getMap().size(); 4746 for (int ip=0; ip<NP; ip++) { 4747 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4748 final int NA = apps.size(); 4749 for (int ia=0; ia<NA; ia++) { 4750 ProcessRecord app = apps.valueAt(ia); 4751 if (app.persistent && !evenPersistent) { 4752 // we don't kill persistent processes 4753 continue; 4754 } 4755 if (app.removed) { 4756 if (doit) { 4757 procs.add(app); 4758 } 4759 continue; 4760 } 4761 4762 // Skip process if it doesn't meet our oom adj requirement. 4763 if (app.setAdj < minOomAdj) { 4764 continue; 4765 } 4766 4767 // If no package is specified, we call all processes under the 4768 // give user id. 4769 if (packageName == null) { 4770 if (app.userId != userId) { 4771 continue; 4772 } 4773 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4774 continue; 4775 } 4776 // Package has been specified, we want to hit all processes 4777 // that match it. We need to qualify this by the processes 4778 // that are running under the specified app and user ID. 4779 } else { 4780 if (UserHandle.getAppId(app.uid) != appId) { 4781 continue; 4782 } 4783 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4784 continue; 4785 } 4786 if (!app.pkgList.containsKey(packageName)) { 4787 continue; 4788 } 4789 } 4790 4791 // Process has passed all conditions, kill it! 4792 if (!doit) { 4793 return true; 4794 } 4795 app.removed = true; 4796 procs.add(app); 4797 } 4798 } 4799 4800 int N = procs.size(); 4801 for (int i=0; i<N; i++) { 4802 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4803 } 4804 updateOomAdjLocked(); 4805 return N > 0; 4806 } 4807 4808 private final boolean forceStopPackageLocked(String name, int appId, 4809 boolean callerWillRestart, boolean purgeCache, boolean doit, 4810 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4811 int i; 4812 int N; 4813 4814 if (userId == UserHandle.USER_ALL && name == null) { 4815 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4816 } 4817 4818 if (appId < 0 && name != null) { 4819 try { 4820 appId = UserHandle.getAppId( 4821 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4822 } catch (RemoteException e) { 4823 } 4824 } 4825 4826 if (doit) { 4827 if (name != null) { 4828 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4829 + " user=" + userId + ": " + reason); 4830 } else { 4831 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4832 } 4833 4834 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4835 for (int ip=pmap.size()-1; ip>=0; ip--) { 4836 SparseArray<Long> ba = pmap.valueAt(ip); 4837 for (i=ba.size()-1; i>=0; i--) { 4838 boolean remove = false; 4839 final int entUid = ba.keyAt(i); 4840 if (name != null) { 4841 if (userId == UserHandle.USER_ALL) { 4842 if (UserHandle.getAppId(entUid) == appId) { 4843 remove = true; 4844 } 4845 } else { 4846 if (entUid == UserHandle.getUid(userId, appId)) { 4847 remove = true; 4848 } 4849 } 4850 } else if (UserHandle.getUserId(entUid) == userId) { 4851 remove = true; 4852 } 4853 if (remove) { 4854 ba.removeAt(i); 4855 } 4856 } 4857 if (ba.size() == 0) { 4858 pmap.removeAt(ip); 4859 } 4860 } 4861 } 4862 4863 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4864 -100, callerWillRestart, true, doit, evenPersistent, 4865 name == null ? ("stop user " + userId) : ("stop " + name)); 4866 4867 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4868 if (!doit) { 4869 return true; 4870 } 4871 didSomething = true; 4872 } 4873 4874 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4875 if (!doit) { 4876 return true; 4877 } 4878 didSomething = true; 4879 } 4880 4881 if (name == null) { 4882 // Remove all sticky broadcasts from this user. 4883 mStickyBroadcasts.remove(userId); 4884 } 4885 4886 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4887 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4888 userId, providers)) { 4889 if (!doit) { 4890 return true; 4891 } 4892 didSomething = true; 4893 } 4894 N = providers.size(); 4895 for (i=0; i<N; i++) { 4896 removeDyingProviderLocked(null, providers.get(i), true); 4897 } 4898 4899 // Remove transient permissions granted from/to this package/user 4900 removeUriPermissionsForPackageLocked(name, userId, false); 4901 4902 if (name == null || uninstalling) { 4903 // Remove pending intents. For now we only do this when force 4904 // stopping users, because we have some problems when doing this 4905 // for packages -- app widgets are not currently cleaned up for 4906 // such packages, so they can be left with bad pending intents. 4907 if (mIntentSenderRecords.size() > 0) { 4908 Iterator<WeakReference<PendingIntentRecord>> it 4909 = mIntentSenderRecords.values().iterator(); 4910 while (it.hasNext()) { 4911 WeakReference<PendingIntentRecord> wpir = it.next(); 4912 if (wpir == null) { 4913 it.remove(); 4914 continue; 4915 } 4916 PendingIntentRecord pir = wpir.get(); 4917 if (pir == null) { 4918 it.remove(); 4919 continue; 4920 } 4921 if (name == null) { 4922 // Stopping user, remove all objects for the user. 4923 if (pir.key.userId != userId) { 4924 // Not the same user, skip it. 4925 continue; 4926 } 4927 } else { 4928 if (UserHandle.getAppId(pir.uid) != appId) { 4929 // Different app id, skip it. 4930 continue; 4931 } 4932 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4933 // Different user, skip it. 4934 continue; 4935 } 4936 if (!pir.key.packageName.equals(name)) { 4937 // Different package, skip it. 4938 continue; 4939 } 4940 } 4941 if (!doit) { 4942 return true; 4943 } 4944 didSomething = true; 4945 it.remove(); 4946 pir.canceled = true; 4947 if (pir.key.activity != null) { 4948 pir.key.activity.pendingResults.remove(pir.ref); 4949 } 4950 } 4951 } 4952 } 4953 4954 if (doit) { 4955 if (purgeCache && name != null) { 4956 AttributeCache ac = AttributeCache.instance(); 4957 if (ac != null) { 4958 ac.removePackage(name); 4959 } 4960 } 4961 if (mBooted) { 4962 mStackSupervisor.resumeTopActivitiesLocked(); 4963 mStackSupervisor.scheduleIdleLocked(); 4964 } 4965 } 4966 4967 return didSomething; 4968 } 4969 4970 private final boolean removeProcessLocked(ProcessRecord app, 4971 boolean callerWillRestart, boolean allowRestart, String reason) { 4972 final String name = app.processName; 4973 final int uid = app.uid; 4974 if (DEBUG_PROCESSES) Slog.d( 4975 TAG, "Force removing proc " + app.toShortString() + " (" + name 4976 + "/" + uid + ")"); 4977 4978 mProcessNames.remove(name, uid); 4979 mIsolatedProcesses.remove(app.uid); 4980 if (mHeavyWeightProcess == app) { 4981 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4982 mHeavyWeightProcess.userId, 0)); 4983 mHeavyWeightProcess = null; 4984 } 4985 boolean needRestart = false; 4986 if (app.pid > 0 && app.pid != MY_PID) { 4987 int pid = app.pid; 4988 synchronized (mPidsSelfLocked) { 4989 mPidsSelfLocked.remove(pid); 4990 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4991 } 4992 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4993 app.processName, app.info.uid); 4994 if (app.isolated) { 4995 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4996 } 4997 killUnneededProcessLocked(app, reason); 4998 handleAppDiedLocked(app, true, allowRestart); 4999 removeLruProcessLocked(app); 5000 5001 if (app.persistent && !app.isolated) { 5002 if (!callerWillRestart) { 5003 addAppLocked(app.info, false); 5004 } else { 5005 needRestart = true; 5006 } 5007 } 5008 } else { 5009 mRemovedProcesses.add(app); 5010 } 5011 5012 return needRestart; 5013 } 5014 5015 private final void processStartTimedOutLocked(ProcessRecord app) { 5016 final int pid = app.pid; 5017 boolean gone = false; 5018 synchronized (mPidsSelfLocked) { 5019 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5020 if (knownApp != null && knownApp.thread == null) { 5021 mPidsSelfLocked.remove(pid); 5022 gone = true; 5023 } 5024 } 5025 5026 if (gone) { 5027 Slog.w(TAG, "Process " + app + " failed to attach"); 5028 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5029 pid, app.uid, app.processName); 5030 mProcessNames.remove(app.processName, app.uid); 5031 mIsolatedProcesses.remove(app.uid); 5032 if (mHeavyWeightProcess == app) { 5033 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5034 mHeavyWeightProcess.userId, 0)); 5035 mHeavyWeightProcess = null; 5036 } 5037 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5038 app.processName, app.info.uid); 5039 if (app.isolated) { 5040 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5041 } 5042 // Take care of any launching providers waiting for this process. 5043 checkAppInLaunchingProvidersLocked(app, true); 5044 // Take care of any services that are waiting for the process. 5045 mServices.processStartTimedOutLocked(app); 5046 killUnneededProcessLocked(app, "start timeout"); 5047 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5048 Slog.w(TAG, "Unattached app died before backup, skipping"); 5049 try { 5050 IBackupManager bm = IBackupManager.Stub.asInterface( 5051 ServiceManager.getService(Context.BACKUP_SERVICE)); 5052 bm.agentDisconnected(app.info.packageName); 5053 } catch (RemoteException e) { 5054 // Can't happen; the backup manager is local 5055 } 5056 } 5057 if (isPendingBroadcastProcessLocked(pid)) { 5058 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5059 skipPendingBroadcastLocked(pid); 5060 } 5061 } else { 5062 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5063 } 5064 } 5065 5066 private final boolean attachApplicationLocked(IApplicationThread thread, 5067 int pid) { 5068 5069 // Find the application record that is being attached... either via 5070 // the pid if we are running in multiple processes, or just pull the 5071 // next app record if we are emulating process with anonymous threads. 5072 ProcessRecord app; 5073 if (pid != MY_PID && pid >= 0) { 5074 synchronized (mPidsSelfLocked) { 5075 app = mPidsSelfLocked.get(pid); 5076 } 5077 } else { 5078 app = null; 5079 } 5080 5081 if (app == null) { 5082 Slog.w(TAG, "No pending application record for pid " + pid 5083 + " (IApplicationThread " + thread + "); dropping process"); 5084 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5085 if (pid > 0 && pid != MY_PID) { 5086 Process.killProcessQuiet(pid); 5087 } else { 5088 try { 5089 thread.scheduleExit(); 5090 } catch (Exception e) { 5091 // Ignore exceptions. 5092 } 5093 } 5094 return false; 5095 } 5096 5097 // If this application record is still attached to a previous 5098 // process, clean it up now. 5099 if (app.thread != null) { 5100 handleAppDiedLocked(app, true, true); 5101 } 5102 5103 // Tell the process all about itself. 5104 5105 if (localLOGV) Slog.v( 5106 TAG, "Binding process pid " + pid + " to record " + app); 5107 5108 final String processName = app.processName; 5109 try { 5110 AppDeathRecipient adr = new AppDeathRecipient( 5111 app, pid, thread); 5112 thread.asBinder().linkToDeath(adr, 0); 5113 app.deathRecipient = adr; 5114 } catch (RemoteException e) { 5115 app.resetPackageList(mProcessStats); 5116 startProcessLocked(app, "link fail", processName); 5117 return false; 5118 } 5119 5120 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5121 5122 app.makeActive(thread, mProcessStats); 5123 app.curAdj = app.setAdj = -100; 5124 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5125 app.forcingToForeground = null; 5126 updateProcessForegroundLocked(app, false, false); 5127 app.hasShownUi = false; 5128 app.debugging = false; 5129 app.cached = false; 5130 5131 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5132 5133 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5134 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5135 5136 if (!normalMode) { 5137 Slog.i(TAG, "Launching preboot mode app: " + app); 5138 } 5139 5140 if (localLOGV) Slog.v( 5141 TAG, "New app record " + app 5142 + " thread=" + thread.asBinder() + " pid=" + pid); 5143 try { 5144 int testMode = IApplicationThread.DEBUG_OFF; 5145 if (mDebugApp != null && mDebugApp.equals(processName)) { 5146 testMode = mWaitForDebugger 5147 ? IApplicationThread.DEBUG_WAIT 5148 : IApplicationThread.DEBUG_ON; 5149 app.debugging = true; 5150 if (mDebugTransient) { 5151 mDebugApp = mOrigDebugApp; 5152 mWaitForDebugger = mOrigWaitForDebugger; 5153 } 5154 } 5155 String profileFile = app.instrumentationProfileFile; 5156 ParcelFileDescriptor profileFd = null; 5157 boolean profileAutoStop = false; 5158 if (mProfileApp != null && mProfileApp.equals(processName)) { 5159 mProfileProc = app; 5160 profileFile = mProfileFile; 5161 profileFd = mProfileFd; 5162 profileAutoStop = mAutoStopProfiler; 5163 } 5164 boolean enableOpenGlTrace = false; 5165 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5166 enableOpenGlTrace = true; 5167 mOpenGlTraceApp = null; 5168 } 5169 5170 // If the app is being launched for restore or full backup, set it up specially 5171 boolean isRestrictedBackupMode = false; 5172 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5173 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5174 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5175 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5176 } 5177 5178 ensurePackageDexOpt(app.instrumentationInfo != null 5179 ? app.instrumentationInfo.packageName 5180 : app.info.packageName); 5181 if (app.instrumentationClass != null) { 5182 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5183 } 5184 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5185 + processName + " with config " + mConfiguration); 5186 ApplicationInfo appInfo = app.instrumentationInfo != null 5187 ? app.instrumentationInfo : app.info; 5188 app.compat = compatibilityInfoForPackageLocked(appInfo); 5189 if (profileFd != null) { 5190 profileFd = profileFd.dup(); 5191 } 5192 thread.bindApplication(processName, appInfo, providers, 5193 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5194 app.instrumentationArguments, app.instrumentationWatcher, 5195 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5196 isRestrictedBackupMode || !normalMode, app.persistent, 5197 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5198 mCoreSettingsObserver.getCoreSettingsLocked()); 5199 updateLruProcessLocked(app, false, null); 5200 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5201 } catch (Exception e) { 5202 // todo: Yikes! What should we do? For now we will try to 5203 // start another process, but that could easily get us in 5204 // an infinite loop of restarting processes... 5205 Slog.w(TAG, "Exception thrown during bind!", e); 5206 5207 app.resetPackageList(mProcessStats); 5208 app.unlinkDeathRecipient(); 5209 startProcessLocked(app, "bind fail", processName); 5210 return false; 5211 } 5212 5213 // Remove this record from the list of starting applications. 5214 mPersistentStartingProcesses.remove(app); 5215 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5216 "Attach application locked removing on hold: " + app); 5217 mProcessesOnHold.remove(app); 5218 5219 boolean badApp = false; 5220 boolean didSomething = false; 5221 5222 // See if the top visible activity is waiting to run in this process... 5223 if (normalMode) { 5224 try { 5225 if (mStackSupervisor.attachApplicationLocked(app)) { 5226 didSomething = true; 5227 } 5228 } catch (Exception e) { 5229 badApp = true; 5230 } 5231 } 5232 5233 // Find any services that should be running in this process... 5234 if (!badApp) { 5235 try { 5236 didSomething |= mServices.attachApplicationLocked(app, processName); 5237 } catch (Exception e) { 5238 badApp = true; 5239 } 5240 } 5241 5242 // Check if a next-broadcast receiver is in this process... 5243 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5244 try { 5245 didSomething |= sendPendingBroadcastsLocked(app); 5246 } catch (Exception e) { 5247 // If the app died trying to launch the receiver we declare it 'bad' 5248 badApp = true; 5249 } 5250 } 5251 5252 // Check whether the next backup agent is in this process... 5253 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5254 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5255 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5256 try { 5257 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5258 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5259 mBackupTarget.backupMode); 5260 } catch (Exception e) { 5261 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5262 e.printStackTrace(); 5263 } 5264 } 5265 5266 if (badApp) { 5267 // todo: Also need to kill application to deal with all 5268 // kinds of exceptions. 5269 handleAppDiedLocked(app, false, true); 5270 return false; 5271 } 5272 5273 if (!didSomething) { 5274 updateOomAdjLocked(); 5275 } 5276 5277 return true; 5278 } 5279 5280 @Override 5281 public final void attachApplication(IApplicationThread thread) { 5282 synchronized (this) { 5283 int callingPid = Binder.getCallingPid(); 5284 final long origId = Binder.clearCallingIdentity(); 5285 attachApplicationLocked(thread, callingPid); 5286 Binder.restoreCallingIdentity(origId); 5287 } 5288 } 5289 5290 @Override 5291 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5292 final long origId = Binder.clearCallingIdentity(); 5293 synchronized (this) { 5294 ActivityStack stack = ActivityRecord.getStackLocked(token); 5295 if (stack != null) { 5296 ActivityRecord r = 5297 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5298 if (stopProfiling) { 5299 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5300 try { 5301 mProfileFd.close(); 5302 } catch (IOException e) { 5303 } 5304 clearProfilerLocked(); 5305 } 5306 } 5307 } 5308 } 5309 Binder.restoreCallingIdentity(origId); 5310 } 5311 5312 void enableScreenAfterBoot() { 5313 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5314 SystemClock.uptimeMillis()); 5315 mWindowManager.enableScreenAfterBoot(); 5316 5317 synchronized (this) { 5318 updateEventDispatchingLocked(); 5319 } 5320 } 5321 5322 @Override 5323 public void showBootMessage(final CharSequence msg, final boolean always) { 5324 enforceNotIsolatedCaller("showBootMessage"); 5325 mWindowManager.showBootMessage(msg, always); 5326 } 5327 5328 @Override 5329 public void dismissKeyguardOnNextActivity() { 5330 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5331 final long token = Binder.clearCallingIdentity(); 5332 try { 5333 synchronized (this) { 5334 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5335 if (mLockScreenShown) { 5336 mLockScreenShown = false; 5337 comeOutOfSleepIfNeededLocked(); 5338 } 5339 mStackSupervisor.setDismissKeyguard(true); 5340 } 5341 } finally { 5342 Binder.restoreCallingIdentity(token); 5343 } 5344 } 5345 5346 final void finishBooting() { 5347 // Register receivers to handle package update events 5348 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5349 5350 synchronized (this) { 5351 // Ensure that any processes we had put on hold are now started 5352 // up. 5353 final int NP = mProcessesOnHold.size(); 5354 if (NP > 0) { 5355 ArrayList<ProcessRecord> procs = 5356 new ArrayList<ProcessRecord>(mProcessesOnHold); 5357 for (int ip=0; ip<NP; ip++) { 5358 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5359 + procs.get(ip)); 5360 startProcessLocked(procs.get(ip), "on-hold", null); 5361 } 5362 } 5363 5364 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5365 // Start looking for apps that are abusing wake locks. 5366 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5367 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5368 // Tell anyone interested that we are done booting! 5369 SystemProperties.set("sys.boot_completed", "1"); 5370 SystemProperties.set("dev.bootcomplete", "1"); 5371 for (int i=0; i<mStartedUsers.size(); i++) { 5372 UserStartedState uss = mStartedUsers.valueAt(i); 5373 if (uss.mState == UserStartedState.STATE_BOOTING) { 5374 uss.mState = UserStartedState.STATE_RUNNING; 5375 final int userId = mStartedUsers.keyAt(i); 5376 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5377 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5378 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5379 broadcastIntentLocked(null, null, intent, null, 5380 new IIntentReceiver.Stub() { 5381 @Override 5382 public void performReceive(Intent intent, int resultCode, 5383 String data, Bundle extras, boolean ordered, 5384 boolean sticky, int sendingUser) { 5385 synchronized (ActivityManagerService.this) { 5386 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5387 true, false); 5388 } 5389 } 5390 }, 5391 0, null, null, 5392 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5393 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5394 userId); 5395 } 5396 } 5397 scheduleStartProfilesLocked(); 5398 } 5399 } 5400 } 5401 5402 final void ensureBootCompleted() { 5403 boolean booting; 5404 boolean enableScreen; 5405 synchronized (this) { 5406 booting = mBooting; 5407 mBooting = false; 5408 enableScreen = !mBooted; 5409 mBooted = true; 5410 } 5411 5412 if (booting) { 5413 finishBooting(); 5414 } 5415 5416 if (enableScreen) { 5417 enableScreenAfterBoot(); 5418 } 5419 } 5420 5421 @Override 5422 public final void activityResumed(IBinder token) { 5423 final long origId = Binder.clearCallingIdentity(); 5424 synchronized(this) { 5425 ActivityStack stack = ActivityRecord.getStackLocked(token); 5426 if (stack != null) { 5427 ActivityRecord.activityResumedLocked(token); 5428 } 5429 } 5430 Binder.restoreCallingIdentity(origId); 5431 } 5432 5433 @Override 5434 public final void activityPaused(IBinder token) { 5435 final long origId = Binder.clearCallingIdentity(); 5436 synchronized(this) { 5437 ActivityStack stack = ActivityRecord.getStackLocked(token); 5438 if (stack != null) { 5439 stack.activityPausedLocked(token, false); 5440 } 5441 } 5442 Binder.restoreCallingIdentity(origId); 5443 } 5444 5445 @Override 5446 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5447 CharSequence description) { 5448 if (localLOGV) Slog.v( 5449 TAG, "Activity stopped: token=" + token); 5450 5451 // Refuse possible leaked file descriptors 5452 if (icicle != null && icicle.hasFileDescriptors()) { 5453 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5454 } 5455 5456 ActivityRecord r = null; 5457 5458 final long origId = Binder.clearCallingIdentity(); 5459 5460 synchronized (this) { 5461 r = ActivityRecord.isInStackLocked(token); 5462 if (r != null) { 5463 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5464 } 5465 } 5466 5467 if (r != null) { 5468 sendPendingThumbnail(r, null, null, null, false); 5469 } 5470 5471 trimApplications(); 5472 5473 Binder.restoreCallingIdentity(origId); 5474 } 5475 5476 @Override 5477 public final void activityDestroyed(IBinder token) { 5478 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5479 synchronized (this) { 5480 ActivityStack stack = ActivityRecord.getStackLocked(token); 5481 if (stack != null) { 5482 stack.activityDestroyedLocked(token); 5483 } 5484 } 5485 } 5486 5487 @Override 5488 public String getCallingPackage(IBinder token) { 5489 synchronized (this) { 5490 ActivityRecord r = getCallingRecordLocked(token); 5491 return r != null ? r.info.packageName : null; 5492 } 5493 } 5494 5495 @Override 5496 public ComponentName getCallingActivity(IBinder token) { 5497 synchronized (this) { 5498 ActivityRecord r = getCallingRecordLocked(token); 5499 return r != null ? r.intent.getComponent() : null; 5500 } 5501 } 5502 5503 private ActivityRecord getCallingRecordLocked(IBinder token) { 5504 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5505 if (r == null) { 5506 return null; 5507 } 5508 return r.resultTo; 5509 } 5510 5511 @Override 5512 public ComponentName getActivityClassForToken(IBinder token) { 5513 synchronized(this) { 5514 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5515 if (r == null) { 5516 return null; 5517 } 5518 return r.intent.getComponent(); 5519 } 5520 } 5521 5522 @Override 5523 public String getPackageForToken(IBinder token) { 5524 synchronized(this) { 5525 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5526 if (r == null) { 5527 return null; 5528 } 5529 return r.packageName; 5530 } 5531 } 5532 5533 @Override 5534 public IIntentSender getIntentSender(int type, 5535 String packageName, IBinder token, String resultWho, 5536 int requestCode, Intent[] intents, String[] resolvedTypes, 5537 int flags, Bundle options, int userId) { 5538 enforceNotIsolatedCaller("getIntentSender"); 5539 // Refuse possible leaked file descriptors 5540 if (intents != null) { 5541 if (intents.length < 1) { 5542 throw new IllegalArgumentException("Intents array length must be >= 1"); 5543 } 5544 for (int i=0; i<intents.length; i++) { 5545 Intent intent = intents[i]; 5546 if (intent != null) { 5547 if (intent.hasFileDescriptors()) { 5548 throw new IllegalArgumentException("File descriptors passed in Intent"); 5549 } 5550 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5551 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5552 throw new IllegalArgumentException( 5553 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5554 } 5555 intents[i] = new Intent(intent); 5556 } 5557 } 5558 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5559 throw new IllegalArgumentException( 5560 "Intent array length does not match resolvedTypes length"); 5561 } 5562 } 5563 if (options != null) { 5564 if (options.hasFileDescriptors()) { 5565 throw new IllegalArgumentException("File descriptors passed in options"); 5566 } 5567 } 5568 5569 synchronized(this) { 5570 int callingUid = Binder.getCallingUid(); 5571 int origUserId = userId; 5572 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5573 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5574 "getIntentSender", null); 5575 if (origUserId == UserHandle.USER_CURRENT) { 5576 // We don't want to evaluate this until the pending intent is 5577 // actually executed. However, we do want to always do the 5578 // security checking for it above. 5579 userId = UserHandle.USER_CURRENT; 5580 } 5581 try { 5582 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5583 int uid = AppGlobals.getPackageManager() 5584 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5585 if (!UserHandle.isSameApp(callingUid, uid)) { 5586 String msg = "Permission Denial: getIntentSender() from pid=" 5587 + Binder.getCallingPid() 5588 + ", uid=" + Binder.getCallingUid() 5589 + ", (need uid=" + uid + ")" 5590 + " is not allowed to send as package " + packageName; 5591 Slog.w(TAG, msg); 5592 throw new SecurityException(msg); 5593 } 5594 } 5595 5596 return getIntentSenderLocked(type, packageName, callingUid, userId, 5597 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5598 5599 } catch (RemoteException e) { 5600 throw new SecurityException(e); 5601 } 5602 } 5603 } 5604 5605 IIntentSender getIntentSenderLocked(int type, String packageName, 5606 int callingUid, int userId, IBinder token, String resultWho, 5607 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5608 Bundle options) { 5609 if (DEBUG_MU) 5610 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5611 ActivityRecord activity = null; 5612 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5613 activity = ActivityRecord.isInStackLocked(token); 5614 if (activity == null) { 5615 return null; 5616 } 5617 if (activity.finishing) { 5618 return null; 5619 } 5620 } 5621 5622 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5623 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5624 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5625 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5626 |PendingIntent.FLAG_UPDATE_CURRENT); 5627 5628 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5629 type, packageName, activity, resultWho, 5630 requestCode, intents, resolvedTypes, flags, options, userId); 5631 WeakReference<PendingIntentRecord> ref; 5632 ref = mIntentSenderRecords.get(key); 5633 PendingIntentRecord rec = ref != null ? ref.get() : null; 5634 if (rec != null) { 5635 if (!cancelCurrent) { 5636 if (updateCurrent) { 5637 if (rec.key.requestIntent != null) { 5638 rec.key.requestIntent.replaceExtras(intents != null ? 5639 intents[intents.length - 1] : null); 5640 } 5641 if (intents != null) { 5642 intents[intents.length-1] = rec.key.requestIntent; 5643 rec.key.allIntents = intents; 5644 rec.key.allResolvedTypes = resolvedTypes; 5645 } else { 5646 rec.key.allIntents = null; 5647 rec.key.allResolvedTypes = null; 5648 } 5649 } 5650 return rec; 5651 } 5652 rec.canceled = true; 5653 mIntentSenderRecords.remove(key); 5654 } 5655 if (noCreate) { 5656 return rec; 5657 } 5658 rec = new PendingIntentRecord(this, key, callingUid); 5659 mIntentSenderRecords.put(key, rec.ref); 5660 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5661 if (activity.pendingResults == null) { 5662 activity.pendingResults 5663 = new HashSet<WeakReference<PendingIntentRecord>>(); 5664 } 5665 activity.pendingResults.add(rec.ref); 5666 } 5667 return rec; 5668 } 5669 5670 @Override 5671 public void cancelIntentSender(IIntentSender sender) { 5672 if (!(sender instanceof PendingIntentRecord)) { 5673 return; 5674 } 5675 synchronized(this) { 5676 PendingIntentRecord rec = (PendingIntentRecord)sender; 5677 try { 5678 int uid = AppGlobals.getPackageManager() 5679 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5680 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5681 String msg = "Permission Denial: cancelIntentSender() from pid=" 5682 + Binder.getCallingPid() 5683 + ", uid=" + Binder.getCallingUid() 5684 + " is not allowed to cancel packges " 5685 + rec.key.packageName; 5686 Slog.w(TAG, msg); 5687 throw new SecurityException(msg); 5688 } 5689 } catch (RemoteException e) { 5690 throw new SecurityException(e); 5691 } 5692 cancelIntentSenderLocked(rec, true); 5693 } 5694 } 5695 5696 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5697 rec.canceled = true; 5698 mIntentSenderRecords.remove(rec.key); 5699 if (cleanActivity && rec.key.activity != null) { 5700 rec.key.activity.pendingResults.remove(rec.ref); 5701 } 5702 } 5703 5704 @Override 5705 public String getPackageForIntentSender(IIntentSender pendingResult) { 5706 if (!(pendingResult instanceof PendingIntentRecord)) { 5707 return null; 5708 } 5709 try { 5710 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5711 return res.key.packageName; 5712 } catch (ClassCastException e) { 5713 } 5714 return null; 5715 } 5716 5717 @Override 5718 public int getUidForIntentSender(IIntentSender sender) { 5719 if (sender instanceof PendingIntentRecord) { 5720 try { 5721 PendingIntentRecord res = (PendingIntentRecord)sender; 5722 return res.uid; 5723 } catch (ClassCastException e) { 5724 } 5725 } 5726 return -1; 5727 } 5728 5729 @Override 5730 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5731 if (!(pendingResult instanceof PendingIntentRecord)) { 5732 return false; 5733 } 5734 try { 5735 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5736 if (res.key.allIntents == null) { 5737 return false; 5738 } 5739 for (int i=0; i<res.key.allIntents.length; i++) { 5740 Intent intent = res.key.allIntents[i]; 5741 if (intent.getPackage() != null && intent.getComponent() != null) { 5742 return false; 5743 } 5744 } 5745 return true; 5746 } catch (ClassCastException e) { 5747 } 5748 return false; 5749 } 5750 5751 @Override 5752 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5753 if (!(pendingResult instanceof PendingIntentRecord)) { 5754 return false; 5755 } 5756 try { 5757 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5758 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5759 return true; 5760 } 5761 return false; 5762 } catch (ClassCastException e) { 5763 } 5764 return false; 5765 } 5766 5767 @Override 5768 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5769 if (!(pendingResult instanceof PendingIntentRecord)) { 5770 return null; 5771 } 5772 try { 5773 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5774 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5775 } catch (ClassCastException e) { 5776 } 5777 return null; 5778 } 5779 5780 @Override 5781 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5782 if (!(pendingResult instanceof PendingIntentRecord)) { 5783 return null; 5784 } 5785 try { 5786 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5787 Intent intent = res.key.requestIntent; 5788 if (intent != null) { 5789 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5790 || res.lastTagPrefix.equals(prefix))) { 5791 return res.lastTag; 5792 } 5793 res.lastTagPrefix = prefix; 5794 StringBuilder sb = new StringBuilder(128); 5795 if (prefix != null) { 5796 sb.append(prefix); 5797 } 5798 if (intent.getAction() != null) { 5799 sb.append(intent.getAction()); 5800 } else if (intent.getComponent() != null) { 5801 intent.getComponent().appendShortString(sb); 5802 } else { 5803 sb.append("?"); 5804 } 5805 return res.lastTag = sb.toString(); 5806 } 5807 } catch (ClassCastException e) { 5808 } 5809 return null; 5810 } 5811 5812 @Override 5813 public void setProcessLimit(int max) { 5814 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5815 "setProcessLimit()"); 5816 synchronized (this) { 5817 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5818 mProcessLimitOverride = max; 5819 } 5820 trimApplications(); 5821 } 5822 5823 @Override 5824 public int getProcessLimit() { 5825 synchronized (this) { 5826 return mProcessLimitOverride; 5827 } 5828 } 5829 5830 void foregroundTokenDied(ForegroundToken token) { 5831 synchronized (ActivityManagerService.this) { 5832 synchronized (mPidsSelfLocked) { 5833 ForegroundToken cur 5834 = mForegroundProcesses.get(token.pid); 5835 if (cur != token) { 5836 return; 5837 } 5838 mForegroundProcesses.remove(token.pid); 5839 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5840 if (pr == null) { 5841 return; 5842 } 5843 pr.forcingToForeground = null; 5844 updateProcessForegroundLocked(pr, false, false); 5845 } 5846 updateOomAdjLocked(); 5847 } 5848 } 5849 5850 @Override 5851 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5852 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5853 "setProcessForeground()"); 5854 synchronized(this) { 5855 boolean changed = false; 5856 5857 synchronized (mPidsSelfLocked) { 5858 ProcessRecord pr = mPidsSelfLocked.get(pid); 5859 if (pr == null && isForeground) { 5860 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5861 return; 5862 } 5863 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5864 if (oldToken != null) { 5865 oldToken.token.unlinkToDeath(oldToken, 0); 5866 mForegroundProcesses.remove(pid); 5867 if (pr != null) { 5868 pr.forcingToForeground = null; 5869 } 5870 changed = true; 5871 } 5872 if (isForeground && token != null) { 5873 ForegroundToken newToken = new ForegroundToken() { 5874 @Override 5875 public void binderDied() { 5876 foregroundTokenDied(this); 5877 } 5878 }; 5879 newToken.pid = pid; 5880 newToken.token = token; 5881 try { 5882 token.linkToDeath(newToken, 0); 5883 mForegroundProcesses.put(pid, newToken); 5884 pr.forcingToForeground = token; 5885 changed = true; 5886 } catch (RemoteException e) { 5887 // If the process died while doing this, we will later 5888 // do the cleanup with the process death link. 5889 } 5890 } 5891 } 5892 5893 if (changed) { 5894 updateOomAdjLocked(); 5895 } 5896 } 5897 } 5898 5899 // ========================================================= 5900 // PERMISSIONS 5901 // ========================================================= 5902 5903 static class PermissionController extends IPermissionController.Stub { 5904 ActivityManagerService mActivityManagerService; 5905 PermissionController(ActivityManagerService activityManagerService) { 5906 mActivityManagerService = activityManagerService; 5907 } 5908 5909 @Override 5910 public boolean checkPermission(String permission, int pid, int uid) { 5911 return mActivityManagerService.checkPermission(permission, pid, 5912 uid) == PackageManager.PERMISSION_GRANTED; 5913 } 5914 } 5915 5916 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5917 @Override 5918 public int checkComponentPermission(String permission, int pid, int uid, 5919 int owningUid, boolean exported) { 5920 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5921 owningUid, exported); 5922 } 5923 5924 @Override 5925 public Object getAMSLock() { 5926 return ActivityManagerService.this; 5927 } 5928 } 5929 5930 /** 5931 * This can be called with or without the global lock held. 5932 */ 5933 int checkComponentPermission(String permission, int pid, int uid, 5934 int owningUid, boolean exported) { 5935 // We might be performing an operation on behalf of an indirect binder 5936 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5937 // client identity accordingly before proceeding. 5938 Identity tlsIdentity = sCallerIdentity.get(); 5939 if (tlsIdentity != null) { 5940 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5941 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5942 uid = tlsIdentity.uid; 5943 pid = tlsIdentity.pid; 5944 } 5945 5946 if (pid == MY_PID) { 5947 return PackageManager.PERMISSION_GRANTED; 5948 } 5949 5950 return ActivityManager.checkComponentPermission(permission, uid, 5951 owningUid, exported); 5952 } 5953 5954 /** 5955 * As the only public entry point for permissions checking, this method 5956 * can enforce the semantic that requesting a check on a null global 5957 * permission is automatically denied. (Internally a null permission 5958 * string is used when calling {@link #checkComponentPermission} in cases 5959 * when only uid-based security is needed.) 5960 * 5961 * This can be called with or without the global lock held. 5962 */ 5963 @Override 5964 public int checkPermission(String permission, int pid, int uid) { 5965 if (permission == null) { 5966 return PackageManager.PERMISSION_DENIED; 5967 } 5968 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5969 } 5970 5971 /** 5972 * Binder IPC calls go through the public entry point. 5973 * This can be called with or without the global lock held. 5974 */ 5975 int checkCallingPermission(String permission) { 5976 return checkPermission(permission, 5977 Binder.getCallingPid(), 5978 UserHandle.getAppId(Binder.getCallingUid())); 5979 } 5980 5981 /** 5982 * This can be called with or without the global lock held. 5983 */ 5984 void enforceCallingPermission(String permission, String func) { 5985 if (checkCallingPermission(permission) 5986 == PackageManager.PERMISSION_GRANTED) { 5987 return; 5988 } 5989 5990 String msg = "Permission Denial: " + func + " from pid=" 5991 + Binder.getCallingPid() 5992 + ", uid=" + Binder.getCallingUid() 5993 + " requires " + permission; 5994 Slog.w(TAG, msg); 5995 throw new SecurityException(msg); 5996 } 5997 5998 /** 5999 * Determine if UID is holding permissions required to access {@link Uri} in 6000 * the given {@link ProviderInfo}. Final permission checking is always done 6001 * in {@link ContentProvider}. 6002 */ 6003 private final boolean checkHoldingPermissionsLocked( 6004 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) { 6005 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6006 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 6007 6008 if (pi.applicationInfo.uid == uid) { 6009 return true; 6010 } else if (!pi.exported) { 6011 return false; 6012 } 6013 6014 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6015 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6016 try { 6017 // check if target holds top-level <provider> permissions 6018 if (!readMet && pi.readPermission != null 6019 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6020 readMet = true; 6021 } 6022 if (!writeMet && pi.writePermission != null 6023 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6024 writeMet = true; 6025 } 6026 6027 // track if unprotected read/write is allowed; any denied 6028 // <path-permission> below removes this ability 6029 boolean allowDefaultRead = pi.readPermission == null; 6030 boolean allowDefaultWrite = pi.writePermission == null; 6031 6032 // check if target holds any <path-permission> that match uri 6033 final PathPermission[] pps = pi.pathPermissions; 6034 if (pps != null) { 6035 final String path = uri.getPath(); 6036 int i = pps.length; 6037 while (i > 0 && (!readMet || !writeMet)) { 6038 i--; 6039 PathPermission pp = pps[i]; 6040 if (pp.match(path)) { 6041 if (!readMet) { 6042 final String pprperm = pp.getReadPermission(); 6043 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6044 + pprperm + " for " + pp.getPath() 6045 + ": match=" + pp.match(path) 6046 + " check=" + pm.checkUidPermission(pprperm, uid)); 6047 if (pprperm != null) { 6048 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 6049 readMet = true; 6050 } else { 6051 allowDefaultRead = false; 6052 } 6053 } 6054 } 6055 if (!writeMet) { 6056 final String ppwperm = pp.getWritePermission(); 6057 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6058 + ppwperm + " for " + pp.getPath() 6059 + ": match=" + pp.match(path) 6060 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6061 if (ppwperm != null) { 6062 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 6063 writeMet = true; 6064 } else { 6065 allowDefaultWrite = false; 6066 } 6067 } 6068 } 6069 } 6070 } 6071 } 6072 6073 // grant unprotected <provider> read/write, if not blocked by 6074 // <path-permission> above 6075 if (allowDefaultRead) readMet = true; 6076 if (allowDefaultWrite) writeMet = true; 6077 6078 } catch (RemoteException e) { 6079 return false; 6080 } 6081 6082 return readMet && writeMet; 6083 } 6084 6085 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6086 ProviderInfo pi = null; 6087 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6088 if (cpr != null) { 6089 pi = cpr.info; 6090 } else { 6091 try { 6092 pi = AppGlobals.getPackageManager().resolveContentProvider( 6093 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6094 } catch (RemoteException ex) { 6095 } 6096 } 6097 return pi; 6098 } 6099 6100 private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) { 6101 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6102 if (targetUris != null) { 6103 return targetUris.get(uri); 6104 } 6105 return null; 6106 } 6107 6108 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6109 String targetPkg, int targetUid, GrantUri uri) { 6110 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6111 if (targetUris == null) { 6112 targetUris = Maps.newArrayMap(); 6113 mGrantedUriPermissions.put(targetUid, targetUris); 6114 } 6115 6116 UriPermission perm = targetUris.get(uri); 6117 if (perm == null) { 6118 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 6119 targetUris.put(uri, perm); 6120 } 6121 6122 return perm; 6123 } 6124 6125 private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) { 6126 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6127 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6128 : UriPermission.STRENGTH_OWNED; 6129 6130 // Root gets to do everything. 6131 if (uid == 0) { 6132 return true; 6133 } 6134 6135 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6136 if (perms == null) return false; 6137 6138 // First look for exact match 6139 final UriPermission exactPerm = perms.get(new GrantUri(uri, false)); 6140 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6141 return true; 6142 } 6143 6144 // No exact match, look for prefixes 6145 final int N = perms.size(); 6146 for (int i = 0; i < N; i++) { 6147 final UriPermission perm = perms.valueAt(i); 6148 if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri) 6149 && perm.getStrength(modeFlags) >= minStrength) { 6150 return true; 6151 } 6152 } 6153 6154 return false; 6155 } 6156 6157 @Override 6158 public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) { 6159 enforceNotIsolatedCaller("checkUriPermission"); 6160 6161 // Another redirected-binder-call permissions check as in 6162 // {@link checkComponentPermission}. 6163 Identity tlsIdentity = sCallerIdentity.get(); 6164 if (tlsIdentity != null) { 6165 uid = tlsIdentity.uid; 6166 pid = tlsIdentity.pid; 6167 } 6168 6169 // Our own process gets to do everything. 6170 if (pid == MY_PID) { 6171 return PackageManager.PERMISSION_GRANTED; 6172 } 6173 synchronized (this) { 6174 return checkUriPermissionLocked(uri, uid, modeFlags) 6175 ? PackageManager.PERMISSION_GRANTED 6176 : PackageManager.PERMISSION_DENIED; 6177 } 6178 } 6179 6180 /** 6181 * Check if the targetPkg can be granted permission to access uri by 6182 * the callingUid using the given modeFlags. Throws a security exception 6183 * if callingUid is not allowed to do this. Returns the uid of the target 6184 * if the URI permission grant should be performed; returns -1 if it is not 6185 * needed (for example targetPkg already has permission to access the URI). 6186 * If you already know the uid of the target, you can supply it in 6187 * lastTargetUid else set that to -1. 6188 */ 6189 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 6190 Uri uri, final int modeFlags, int lastTargetUid) { 6191 if (!Intent.isAccessUriMode(modeFlags)) { 6192 return -1; 6193 } 6194 6195 if (targetPkg != null) { 6196 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6197 "Checking grant " + targetPkg + " permission to " + uri); 6198 } 6199 6200 final IPackageManager pm = AppGlobals.getPackageManager(); 6201 6202 // If this is not a content: uri, we can't do anything with it. 6203 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 6204 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6205 "Can't grant URI permission for non-content URI: " + uri); 6206 return -1; 6207 } 6208 6209 final String authority = uri.getAuthority(); 6210 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6211 if (pi == null) { 6212 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 6213 return -1; 6214 } 6215 6216 int targetUid = lastTargetUid; 6217 if (targetUid < 0 && targetPkg != null) { 6218 try { 6219 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6220 if (targetUid < 0) { 6221 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6222 "Can't grant URI permission no uid for: " + targetPkg); 6223 return -1; 6224 } 6225 } catch (RemoteException ex) { 6226 return -1; 6227 } 6228 } 6229 6230 if (targetUid >= 0) { 6231 // First... does the target actually need this permission? 6232 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 6233 // No need to grant the target this permission. 6234 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6235 "Target " + targetPkg + " already has full permission to " + uri); 6236 return -1; 6237 } 6238 } else { 6239 // First... there is no target package, so can anyone access it? 6240 boolean allowed = pi.exported; 6241 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6242 if (pi.readPermission != null) { 6243 allowed = false; 6244 } 6245 } 6246 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6247 if (pi.writePermission != null) { 6248 allowed = false; 6249 } 6250 } 6251 if (allowed) { 6252 return -1; 6253 } 6254 } 6255 6256 // Second... is the provider allowing granting of URI permissions? 6257 if (!pi.grantUriPermissions) { 6258 throw new SecurityException("Provider " + pi.packageName 6259 + "/" + pi.name 6260 + " does not allow granting of Uri permissions (uri " 6261 + uri + ")"); 6262 } 6263 if (pi.uriPermissionPatterns != null) { 6264 final int N = pi.uriPermissionPatterns.length; 6265 boolean allowed = false; 6266 for (int i=0; i<N; i++) { 6267 if (pi.uriPermissionPatterns[i] != null 6268 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6269 allowed = true; 6270 break; 6271 } 6272 } 6273 if (!allowed) { 6274 throw new SecurityException("Provider " + pi.packageName 6275 + "/" + pi.name 6276 + " does not allow granting of permission to path of Uri " 6277 + uri); 6278 } 6279 } 6280 6281 // Third... does the caller itself have permission to access 6282 // this uri? 6283 if (callingUid != Process.myUid()) { 6284 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6285 // Require they hold a strong enough Uri permission 6286 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6287 throw new SecurityException("Uid " + callingUid 6288 + " does not have permission to uri " + uri); 6289 } 6290 } 6291 } 6292 6293 return targetUid; 6294 } 6295 6296 @Override 6297 public int checkGrantUriPermission(int callingUid, String targetPkg, 6298 Uri uri, final int modeFlags) { 6299 enforceNotIsolatedCaller("checkGrantUriPermission"); 6300 synchronized(this) { 6301 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6302 } 6303 } 6304 6305 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri, 6306 final int modeFlags, UriPermissionOwner owner) { 6307 if (!Intent.isAccessUriMode(modeFlags)) { 6308 return; 6309 } 6310 6311 // So here we are: the caller has the assumed permission 6312 // to the uri, and the target doesn't. Let's now give this to 6313 // the target. 6314 6315 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6316 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6317 6318 final String authority = uri.getAuthority(); 6319 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6320 if (pi == null) { 6321 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6322 return; 6323 } 6324 6325 final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0; 6326 final UriPermission perm = findOrCreateUriPermissionLocked( 6327 pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix)); 6328 perm.grantModes(modeFlags, owner); 6329 } 6330 6331 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6332 final int modeFlags, UriPermissionOwner owner) { 6333 if (targetPkg == null) { 6334 throw new NullPointerException("targetPkg"); 6335 } 6336 6337 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6338 if (targetUid < 0) { 6339 return; 6340 } 6341 6342 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6343 } 6344 6345 static class NeededUriGrants extends ArrayList<Uri> { 6346 final String targetPkg; 6347 final int targetUid; 6348 final int flags; 6349 6350 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6351 this.targetPkg = targetPkg; 6352 this.targetUid = targetUid; 6353 this.flags = flags; 6354 } 6355 } 6356 6357 /** 6358 * Like checkGrantUriPermissionLocked, but takes an Intent. 6359 */ 6360 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6361 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6362 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6363 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6364 + " clip=" + (intent != null ? intent.getClipData() : null) 6365 + " from " + intent + "; flags=0x" 6366 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6367 6368 if (targetPkg == null) { 6369 throw new NullPointerException("targetPkg"); 6370 } 6371 6372 if (intent == null) { 6373 return null; 6374 } 6375 Uri data = intent.getData(); 6376 ClipData clip = intent.getClipData(); 6377 if (data == null && clip == null) { 6378 return null; 6379 } 6380 6381 if (data != null) { 6382 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6383 mode, needed != null ? needed.targetUid : -1); 6384 if (targetUid > 0) { 6385 if (needed == null) { 6386 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6387 } 6388 needed.add(data); 6389 } 6390 } 6391 if (clip != null) { 6392 for (int i=0; i<clip.getItemCount(); i++) { 6393 Uri uri = clip.getItemAt(i).getUri(); 6394 if (uri != null) { 6395 int targetUid = -1; 6396 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6397 mode, needed != null ? needed.targetUid : -1); 6398 if (targetUid > 0) { 6399 if (needed == null) { 6400 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6401 } 6402 needed.add(uri); 6403 } 6404 } else { 6405 Intent clipIntent = clip.getItemAt(i).getIntent(); 6406 if (clipIntent != null) { 6407 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6408 callingUid, targetPkg, clipIntent, mode, needed); 6409 if (newNeeded != null) { 6410 needed = newNeeded; 6411 } 6412 } 6413 } 6414 } 6415 } 6416 6417 return needed; 6418 } 6419 6420 /** 6421 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6422 */ 6423 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6424 UriPermissionOwner owner) { 6425 if (needed != null) { 6426 for (int i=0; i<needed.size(); i++) { 6427 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6428 needed.get(i), needed.flags, owner); 6429 } 6430 } 6431 } 6432 6433 void grantUriPermissionFromIntentLocked(int callingUid, 6434 String targetPkg, Intent intent, UriPermissionOwner owner) { 6435 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6436 intent, intent != null ? intent.getFlags() : 0, null); 6437 if (needed == null) { 6438 return; 6439 } 6440 6441 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6442 } 6443 6444 @Override 6445 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6446 Uri uri, final int modeFlags) { 6447 enforceNotIsolatedCaller("grantUriPermission"); 6448 synchronized(this) { 6449 final ProcessRecord r = getRecordForAppLocked(caller); 6450 if (r == null) { 6451 throw new SecurityException("Unable to find app for caller " 6452 + caller 6453 + " when granting permission to uri " + uri); 6454 } 6455 if (targetPkg == null) { 6456 throw new IllegalArgumentException("null target"); 6457 } 6458 if (uri == null) { 6459 throw new IllegalArgumentException("null uri"); 6460 } 6461 6462 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6463 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6464 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6465 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6466 6467 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null); 6468 } 6469 } 6470 6471 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6472 if (perm.modeFlags == 0) { 6473 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6474 perm.targetUid); 6475 if (perms != null) { 6476 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6477 "Removing " + perm.targetUid + " permission to " + perm.uri); 6478 6479 perms.remove(perm.uri); 6480 if (perms.isEmpty()) { 6481 mGrantedUriPermissions.remove(perm.targetUid); 6482 } 6483 } 6484 } 6485 } 6486 6487 private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) { 6488 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6489 6490 final IPackageManager pm = AppGlobals.getPackageManager(); 6491 final String authority = uri.getAuthority(); 6492 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6493 if (pi == null) { 6494 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6495 return; 6496 } 6497 6498 // Does the caller have this permission on the URI? 6499 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6500 // Right now, if you are not the original owner of the permission, 6501 // you are not allowed to revoke it. 6502 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6503 throw new SecurityException("Uid " + callingUid 6504 + " does not have permission to uri " + uri); 6505 //} 6506 } 6507 6508 boolean persistChanged = false; 6509 6510 // Go through all of the permissions and remove any that match. 6511 int N = mGrantedUriPermissions.size(); 6512 for (int i = 0; i < N; i++) { 6513 final int targetUid = mGrantedUriPermissions.keyAt(i); 6514 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6515 6516 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6517 final UriPermission perm = it.next(); 6518 if (perm.uri.uri.isPathPrefixMatch(uri)) { 6519 if (DEBUG_URI_PERMISSION) 6520 Slog.v(TAG, 6521 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6522 persistChanged |= perm.revokeModes( 6523 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6524 if (perm.modeFlags == 0) { 6525 it.remove(); 6526 } 6527 } 6528 } 6529 6530 if (perms.isEmpty()) { 6531 mGrantedUriPermissions.remove(targetUid); 6532 N--; 6533 i--; 6534 } 6535 } 6536 6537 if (persistChanged) { 6538 schedulePersistUriGrants(); 6539 } 6540 } 6541 6542 @Override 6543 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6544 final int modeFlags) { 6545 enforceNotIsolatedCaller("revokeUriPermission"); 6546 synchronized(this) { 6547 final ProcessRecord r = getRecordForAppLocked(caller); 6548 if (r == null) { 6549 throw new SecurityException("Unable to find app for caller " 6550 + caller 6551 + " when revoking permission to uri " + uri); 6552 } 6553 if (uri == null) { 6554 Slog.w(TAG, "revokeUriPermission: null uri"); 6555 return; 6556 } 6557 6558 if (!Intent.isAccessUriMode(modeFlags)) { 6559 return; 6560 } 6561 6562 final IPackageManager pm = AppGlobals.getPackageManager(); 6563 final String authority = uri.getAuthority(); 6564 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6565 if (pi == null) { 6566 Slog.w(TAG, "No content provider found for permission revoke: " 6567 + uri.toSafeString()); 6568 return; 6569 } 6570 6571 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6572 } 6573 } 6574 6575 /** 6576 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6577 * given package. 6578 * 6579 * @param packageName Package name to match, or {@code null} to apply to all 6580 * packages. 6581 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6582 * to all users. 6583 * @param persistable If persistable grants should be removed. 6584 */ 6585 private void removeUriPermissionsForPackageLocked( 6586 String packageName, int userHandle, boolean persistable) { 6587 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6588 throw new IllegalArgumentException("Must narrow by either package or user"); 6589 } 6590 6591 boolean persistChanged = false; 6592 6593 int N = mGrantedUriPermissions.size(); 6594 for (int i = 0; i < N; i++) { 6595 final int targetUid = mGrantedUriPermissions.keyAt(i); 6596 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6597 6598 // Only inspect grants matching user 6599 if (userHandle == UserHandle.USER_ALL 6600 || userHandle == UserHandle.getUserId(targetUid)) { 6601 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6602 final UriPermission perm = it.next(); 6603 6604 // Only inspect grants matching package 6605 if (packageName == null || perm.sourcePkg.equals(packageName) 6606 || perm.targetPkg.equals(packageName)) { 6607 persistChanged |= perm.revokeModes( 6608 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6609 6610 // Only remove when no modes remain; any persisted grants 6611 // will keep this alive. 6612 if (perm.modeFlags == 0) { 6613 it.remove(); 6614 } 6615 } 6616 } 6617 6618 if (perms.isEmpty()) { 6619 mGrantedUriPermissions.remove(targetUid); 6620 N--; 6621 i--; 6622 } 6623 } 6624 } 6625 6626 if (persistChanged) { 6627 schedulePersistUriGrants(); 6628 } 6629 } 6630 6631 @Override 6632 public IBinder newUriPermissionOwner(String name) { 6633 enforceNotIsolatedCaller("newUriPermissionOwner"); 6634 synchronized(this) { 6635 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6636 return owner.getExternalTokenLocked(); 6637 } 6638 } 6639 6640 @Override 6641 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6642 Uri uri, final int modeFlags) { 6643 synchronized(this) { 6644 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6645 if (owner == null) { 6646 throw new IllegalArgumentException("Unknown owner: " + token); 6647 } 6648 if (fromUid != Binder.getCallingUid()) { 6649 if (Binder.getCallingUid() != Process.myUid()) { 6650 // Only system code can grant URI permissions on behalf 6651 // of other users. 6652 throw new SecurityException("nice try"); 6653 } 6654 } 6655 if (targetPkg == null) { 6656 throw new IllegalArgumentException("null target"); 6657 } 6658 if (uri == null) { 6659 throw new IllegalArgumentException("null uri"); 6660 } 6661 6662 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6663 } 6664 } 6665 6666 @Override 6667 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6668 synchronized(this) { 6669 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6670 if (owner == null) { 6671 throw new IllegalArgumentException("Unknown owner: " + token); 6672 } 6673 6674 if (uri == null) { 6675 owner.removeUriPermissionsLocked(mode); 6676 } else { 6677 owner.removeUriPermissionLocked(uri, mode); 6678 } 6679 } 6680 } 6681 6682 private void schedulePersistUriGrants() { 6683 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6684 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6685 10 * DateUtils.SECOND_IN_MILLIS); 6686 } 6687 } 6688 6689 private void writeGrantedUriPermissions() { 6690 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6691 6692 // Snapshot permissions so we can persist without lock 6693 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6694 synchronized (this) { 6695 final int size = mGrantedUriPermissions.size(); 6696 for (int i = 0; i < size; i++) { 6697 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6698 for (UriPermission perm : perms.values()) { 6699 if (perm.persistedModeFlags != 0) { 6700 persist.add(perm.snapshot()); 6701 } 6702 } 6703 } 6704 } 6705 6706 FileOutputStream fos = null; 6707 try { 6708 fos = mGrantFile.startWrite(); 6709 6710 XmlSerializer out = new FastXmlSerializer(); 6711 out.setOutput(fos, "utf-8"); 6712 out.startDocument(null, true); 6713 out.startTag(null, TAG_URI_GRANTS); 6714 for (UriPermission.Snapshot perm : persist) { 6715 out.startTag(null, TAG_URI_GRANT); 6716 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6717 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6718 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6719 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6720 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6721 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6722 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6723 out.endTag(null, TAG_URI_GRANT); 6724 } 6725 out.endTag(null, TAG_URI_GRANTS); 6726 out.endDocument(); 6727 6728 mGrantFile.finishWrite(fos); 6729 } catch (IOException e) { 6730 if (fos != null) { 6731 mGrantFile.failWrite(fos); 6732 } 6733 } 6734 } 6735 6736 private void readGrantedUriPermissionsLocked() { 6737 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6738 6739 final long now = System.currentTimeMillis(); 6740 6741 FileInputStream fis = null; 6742 try { 6743 fis = mGrantFile.openRead(); 6744 final XmlPullParser in = Xml.newPullParser(); 6745 in.setInput(fis, null); 6746 6747 int type; 6748 while ((type = in.next()) != END_DOCUMENT) { 6749 final String tag = in.getName(); 6750 if (type == START_TAG) { 6751 if (TAG_URI_GRANT.equals(tag)) { 6752 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6753 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6754 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6755 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6756 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6757 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6758 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6759 6760 // Sanity check that provider still belongs to source package 6761 final ProviderInfo pi = getProviderInfoLocked( 6762 uri.getAuthority(), userHandle); 6763 if (pi != null && sourcePkg.equals(pi.packageName)) { 6764 int targetUid = -1; 6765 try { 6766 targetUid = AppGlobals.getPackageManager() 6767 .getPackageUid(targetPkg, userHandle); 6768 } catch (RemoteException e) { 6769 } 6770 if (targetUid != -1) { 6771 final UriPermission perm = findOrCreateUriPermissionLocked( 6772 sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix)); 6773 perm.initPersistedModes(modeFlags, createdTime); 6774 } 6775 } else { 6776 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6777 + " but instead found " + pi); 6778 } 6779 } 6780 } 6781 } 6782 } catch (FileNotFoundException e) { 6783 // Missing grants is okay 6784 } catch (IOException e) { 6785 Log.wtf(TAG, "Failed reading Uri grants", e); 6786 } catch (XmlPullParserException e) { 6787 Log.wtf(TAG, "Failed reading Uri grants", e); 6788 } finally { 6789 IoUtils.closeQuietly(fis); 6790 } 6791 } 6792 6793 @Override 6794 public void takePersistableUriPermission(Uri uri, final int modeFlags) { 6795 enforceNotIsolatedCaller("takePersistableUriPermission"); 6796 6797 Preconditions.checkFlagsArgument(modeFlags, 6798 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6799 6800 synchronized (this) { 6801 final int callingUid = Binder.getCallingUid(); 6802 boolean persistChanged = false; 6803 6804 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6805 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6806 6807 final boolean exactValid = (exactPerm != null) 6808 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6809 final boolean prefixValid = (prefixPerm != null) 6810 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6811 6812 if (!(exactValid || prefixValid)) { 6813 throw new SecurityException("No persistable permission grants found for UID " 6814 + callingUid + " and Uri " + uri.toSafeString()); 6815 } 6816 6817 if (exactValid) { 6818 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6819 } 6820 if (prefixValid) { 6821 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6822 } 6823 6824 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6825 6826 if (persistChanged) { 6827 schedulePersistUriGrants(); 6828 } 6829 } 6830 } 6831 6832 @Override 6833 public void releasePersistableUriPermission(Uri uri, final int modeFlags) { 6834 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6835 6836 Preconditions.checkFlagsArgument(modeFlags, 6837 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6838 6839 synchronized (this) { 6840 final int callingUid = Binder.getCallingUid(); 6841 boolean persistChanged = false; 6842 6843 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6844 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6845 if (exactPerm == null && prefixPerm == null) { 6846 throw new SecurityException("No permission grants found for UID " + callingUid 6847 + " and Uri " + uri.toSafeString()); 6848 } 6849 6850 if (exactPerm != null) { 6851 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6852 removeUriPermissionIfNeededLocked(exactPerm); 6853 } 6854 if (prefixPerm != null) { 6855 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6856 removeUriPermissionIfNeededLocked(prefixPerm); 6857 } 6858 6859 if (persistChanged) { 6860 schedulePersistUriGrants(); 6861 } 6862 } 6863 } 6864 6865 /** 6866 * Prune any older {@link UriPermission} for the given UID until outstanding 6867 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6868 * 6869 * @return if any mutations occured that require persisting. 6870 */ 6871 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6872 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6873 if (perms == null) return false; 6874 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6875 6876 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6877 for (UriPermission perm : perms.values()) { 6878 if (perm.persistedModeFlags != 0) { 6879 persisted.add(perm); 6880 } 6881 } 6882 6883 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6884 if (trimCount <= 0) return false; 6885 6886 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6887 for (int i = 0; i < trimCount; i++) { 6888 final UriPermission perm = persisted.get(i); 6889 6890 if (DEBUG_URI_PERMISSION) { 6891 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6892 } 6893 6894 perm.releasePersistableModes(~0); 6895 removeUriPermissionIfNeededLocked(perm); 6896 } 6897 6898 return true; 6899 } 6900 6901 @Override 6902 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6903 String packageName, boolean incoming) { 6904 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6905 Preconditions.checkNotNull(packageName, "packageName"); 6906 6907 final int callingUid = Binder.getCallingUid(); 6908 final IPackageManager pm = AppGlobals.getPackageManager(); 6909 try { 6910 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6911 if (packageUid != callingUid) { 6912 throw new SecurityException( 6913 "Package " + packageName + " does not belong to calling UID " + callingUid); 6914 } 6915 } catch (RemoteException e) { 6916 throw new SecurityException("Failed to verify package name ownership"); 6917 } 6918 6919 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6920 synchronized (this) { 6921 if (incoming) { 6922 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6923 callingUid); 6924 if (perms == null) { 6925 Slog.w(TAG, "No permission grants found for " + packageName); 6926 } else { 6927 for (UriPermission perm : perms.values()) { 6928 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6929 result.add(perm.buildPersistedPublicApiObject()); 6930 } 6931 } 6932 } 6933 } else { 6934 final int size = mGrantedUriPermissions.size(); 6935 for (int i = 0; i < size; i++) { 6936 final ArrayMap<GrantUri, UriPermission> perms = 6937 mGrantedUriPermissions.valueAt(i); 6938 for (UriPermission perm : perms.values()) { 6939 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6940 result.add(perm.buildPersistedPublicApiObject()); 6941 } 6942 } 6943 } 6944 } 6945 } 6946 return new ParceledListSlice<android.content.UriPermission>(result); 6947 } 6948 6949 @Override 6950 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6951 synchronized (this) { 6952 ProcessRecord app = 6953 who != null ? getRecordForAppLocked(who) : null; 6954 if (app == null) return; 6955 6956 Message msg = Message.obtain(); 6957 msg.what = WAIT_FOR_DEBUGGER_MSG; 6958 msg.obj = app; 6959 msg.arg1 = waiting ? 1 : 0; 6960 mHandler.sendMessage(msg); 6961 } 6962 } 6963 6964 @Override 6965 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6966 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6967 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6968 outInfo.availMem = Process.getFreeMemory(); 6969 outInfo.totalMem = Process.getTotalMemory(); 6970 outInfo.threshold = homeAppMem; 6971 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6972 outInfo.hiddenAppThreshold = cachedAppMem; 6973 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6974 ProcessList.SERVICE_ADJ); 6975 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6976 ProcessList.VISIBLE_APP_ADJ); 6977 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6978 ProcessList.FOREGROUND_APP_ADJ); 6979 } 6980 6981 // ========================================================= 6982 // TASK MANAGEMENT 6983 // ========================================================= 6984 6985 @Override 6986 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6987 IThumbnailReceiver receiver) { 6988 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6989 6990 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6991 ActivityRecord topRecord = null; 6992 6993 synchronized(this) { 6994 if (localLOGV) Slog.v( 6995 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6996 + ", receiver=" + receiver); 6997 6998 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6999 != PackageManager.PERMISSION_GRANTED) { 7000 if (receiver != null) { 7001 // If the caller wants to wait for pending thumbnails, 7002 // it ain't gonna get them. 7003 try { 7004 receiver.finished(); 7005 } catch (RemoteException ex) { 7006 } 7007 } 7008 String msg = "Permission Denial: getTasks() from pid=" 7009 + Binder.getCallingPid() 7010 + ", uid=" + Binder.getCallingUid() 7011 + " requires " + android.Manifest.permission.GET_TASKS; 7012 Slog.w(TAG, msg); 7013 throw new SecurityException(msg); 7014 } 7015 7016 // TODO: Improve with MRU list from all ActivityStacks. 7017 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 7018 7019 if (!pending.pendingRecords.isEmpty()) { 7020 mPendingThumbnails.add(pending); 7021 } 7022 } 7023 7024 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 7025 7026 if (topRecord != null) { 7027 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 7028 try { 7029 IApplicationThread topThumbnail = topRecord.app.thread; 7030 topThumbnail.requestThumbnail(topRecord.appToken); 7031 } catch (Exception e) { 7032 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 7033 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 7034 } 7035 } 7036 7037 if (pending.pendingRecords.isEmpty() && receiver != null) { 7038 // In this case all thumbnails were available and the client 7039 // is being asked to be told when the remaining ones come in... 7040 // which is unusually, since the top-most currently running 7041 // activity should never have a canned thumbnail! Oh well. 7042 try { 7043 receiver.finished(); 7044 } catch (RemoteException ex) { 7045 } 7046 } 7047 7048 return list; 7049 } 7050 7051 TaskRecord getMostRecentTask() { 7052 return mRecentTasks.get(0); 7053 } 7054 7055 @Override 7056 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7057 int flags, int userId) { 7058 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7059 false, true, "getRecentTasks", null); 7060 7061 synchronized (this) { 7062 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 7063 "getRecentTasks()"); 7064 final boolean detailed = checkCallingPermission( 7065 android.Manifest.permission.GET_DETAILED_TASKS) 7066 == PackageManager.PERMISSION_GRANTED; 7067 7068 IPackageManager pm = AppGlobals.getPackageManager(); 7069 7070 final int N = mRecentTasks.size(); 7071 ArrayList<ActivityManager.RecentTaskInfo> res 7072 = new ArrayList<ActivityManager.RecentTaskInfo>( 7073 maxNum < N ? maxNum : N); 7074 7075 final Set<Integer> includedUsers; 7076 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7077 includedUsers = getProfileIdsLocked(userId); 7078 } else { 7079 includedUsers = new HashSet<Integer>(); 7080 } 7081 includedUsers.add(Integer.valueOf(userId)); 7082 for (int i=0; i<N && maxNum > 0; i++) { 7083 TaskRecord tr = mRecentTasks.get(i); 7084 // Only add calling user or related users recent tasks 7085 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7086 7087 // Return the entry if desired by the caller. We always return 7088 // the first entry, because callers always expect this to be the 7089 // foreground app. We may filter others if the caller has 7090 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7091 // we should exclude the entry. 7092 7093 if (i == 0 7094 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7095 || (tr.intent == null) 7096 || ((tr.intent.getFlags() 7097 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7098 ActivityManager.RecentTaskInfo rti 7099 = new ActivityManager.RecentTaskInfo(); 7100 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 7101 rti.persistentId = tr.taskId; 7102 rti.baseIntent = new Intent( 7103 tr.intent != null ? tr.intent : tr.affinityIntent); 7104 if (!detailed) { 7105 rti.baseIntent.replaceExtras((Bundle)null); 7106 } 7107 rti.origActivity = tr.origActivity; 7108 rti.description = tr.lastDescription; 7109 rti.stackId = tr.stack.mStackId; 7110 rti.userId = tr.userId; 7111 7112 // Traverse upwards looking for any break between main task activities and 7113 // utility activities. 7114 final ArrayList<ActivityRecord> activities = tr.mActivities; 7115 int activityNdx; 7116 final int numActivities = activities.size(); 7117 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities; 7118 ++activityNdx) { 7119 final ActivityRecord r = activities.get(activityNdx); 7120 if (r.intent != null && 7121 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) 7122 != 0) { 7123 break; 7124 } 7125 } 7126 // Traverse downwards starting below break looking for set label and icon. 7127 for (--activityNdx; activityNdx >= 0; --activityNdx) { 7128 final ActivityRecord r = activities.get(activityNdx); 7129 if (r.activityLabel != null || r.activityIcon != null) { 7130 rti.activityLabel = r.activityLabel; 7131 rti.activityIcon = r.activityIcon; 7132 break; 7133 } 7134 } 7135 7136 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7137 // Check whether this activity is currently available. 7138 try { 7139 if (rti.origActivity != null) { 7140 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7141 == null) { 7142 continue; 7143 } 7144 } else if (rti.baseIntent != null) { 7145 if (pm.queryIntentActivities(rti.baseIntent, 7146 null, 0, userId) == null) { 7147 continue; 7148 } 7149 } 7150 } catch (RemoteException e) { 7151 // Will never happen. 7152 } 7153 } 7154 7155 res.add(rti); 7156 maxNum--; 7157 } 7158 } 7159 return res; 7160 } 7161 } 7162 7163 private TaskRecord recentTaskForIdLocked(int id) { 7164 final int N = mRecentTasks.size(); 7165 for (int i=0; i<N; i++) { 7166 TaskRecord tr = mRecentTasks.get(i); 7167 if (tr.taskId == id) { 7168 return tr; 7169 } 7170 } 7171 return null; 7172 } 7173 7174 @Override 7175 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7176 synchronized (this) { 7177 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7178 "getTaskThumbnails()"); 7179 TaskRecord tr = recentTaskForIdLocked(id); 7180 if (tr != null) { 7181 return tr.getTaskThumbnailsLocked(); 7182 } 7183 } 7184 return null; 7185 } 7186 7187 @Override 7188 public Bitmap getTaskTopThumbnail(int id) { 7189 synchronized (this) { 7190 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7191 "getTaskTopThumbnail()"); 7192 TaskRecord tr = recentTaskForIdLocked(id); 7193 if (tr != null) { 7194 return tr.getTaskTopThumbnailLocked(); 7195 } 7196 } 7197 return null; 7198 } 7199 7200 @Override 7201 public void setActivityLabelAndIcon(IBinder token, CharSequence activityLabel, 7202 Bitmap activityIcon) { 7203 synchronized (this) { 7204 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7205 if (r != null) { 7206 r.activityLabel = activityLabel.toString(); 7207 r.activityIcon = activityIcon; 7208 } 7209 } 7210 } 7211 7212 @Override 7213 public boolean removeSubTask(int taskId, int subTaskIndex) { 7214 synchronized (this) { 7215 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7216 "removeSubTask()"); 7217 long ident = Binder.clearCallingIdentity(); 7218 try { 7219 TaskRecord tr = recentTaskForIdLocked(taskId); 7220 if (tr != null) { 7221 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7222 } 7223 return false; 7224 } finally { 7225 Binder.restoreCallingIdentity(ident); 7226 } 7227 } 7228 } 7229 7230 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7231 if (!pr.killedByAm) { 7232 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7233 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7234 pr.processName, pr.setAdj, reason); 7235 pr.killedByAm = true; 7236 Process.killProcessQuiet(pr.pid); 7237 } 7238 } 7239 7240 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7241 tr.disposeThumbnail(); 7242 mRecentTasks.remove(tr); 7243 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7244 Intent baseIntent = new Intent( 7245 tr.intent != null ? tr.intent : tr.affinityIntent); 7246 ComponentName component = baseIntent.getComponent(); 7247 if (component == null) { 7248 Slog.w(TAG, "Now component for base intent of task: " + tr); 7249 return; 7250 } 7251 7252 // Find any running services associated with this app. 7253 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7254 7255 if (killProcesses) { 7256 // Find any running processes associated with this app. 7257 final String pkg = component.getPackageName(); 7258 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7259 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7260 for (int i=0; i<pmap.size(); i++) { 7261 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7262 for (int j=0; j<uids.size(); j++) { 7263 ProcessRecord proc = uids.valueAt(j); 7264 if (proc.userId != tr.userId) { 7265 continue; 7266 } 7267 if (!proc.pkgList.containsKey(pkg)) { 7268 continue; 7269 } 7270 procs.add(proc); 7271 } 7272 } 7273 7274 // Kill the running processes. 7275 for (int i=0; i<procs.size(); i++) { 7276 ProcessRecord pr = procs.get(i); 7277 if (pr == mHomeProcess) { 7278 // Don't kill the home process along with tasks from the same package. 7279 continue; 7280 } 7281 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7282 killUnneededProcessLocked(pr, "remove task"); 7283 } else { 7284 pr.waitingToKill = "remove task"; 7285 } 7286 } 7287 } 7288 } 7289 7290 /** 7291 * Removes the task with the specified task id. 7292 * 7293 * @param taskId Identifier of the task to be removed. 7294 * @param flags Additional operational flags. May be 0 or 7295 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7296 * @return Returns true if the given task was found and removed. 7297 */ 7298 private boolean removeTaskByIdLocked(int taskId, int flags) { 7299 TaskRecord tr = recentTaskForIdLocked(taskId); 7300 if (tr != null) { 7301 tr.removeTaskActivitiesLocked(-1, false); 7302 cleanUpRemovedTaskLocked(tr, flags); 7303 return true; 7304 } 7305 return false; 7306 } 7307 7308 @Override 7309 public boolean removeTask(int taskId, int flags) { 7310 synchronized (this) { 7311 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7312 "removeTask()"); 7313 long ident = Binder.clearCallingIdentity(); 7314 try { 7315 return removeTaskByIdLocked(taskId, flags); 7316 } finally { 7317 Binder.restoreCallingIdentity(ident); 7318 } 7319 } 7320 } 7321 7322 /** 7323 * TODO: Add mController hook 7324 */ 7325 @Override 7326 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7327 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7328 "moveTaskToFront()"); 7329 7330 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7331 synchronized(this) { 7332 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7333 Binder.getCallingUid(), "Task to front")) { 7334 ActivityOptions.abort(options); 7335 return; 7336 } 7337 final long origId = Binder.clearCallingIdentity(); 7338 try { 7339 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7340 if (task == null) { 7341 return; 7342 } 7343 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7344 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7345 return; 7346 } 7347 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7348 } finally { 7349 Binder.restoreCallingIdentity(origId); 7350 } 7351 ActivityOptions.abort(options); 7352 } 7353 } 7354 7355 @Override 7356 public void moveTaskToBack(int taskId) { 7357 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7358 "moveTaskToBack()"); 7359 7360 synchronized(this) { 7361 TaskRecord tr = recentTaskForIdLocked(taskId); 7362 if (tr != null) { 7363 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7364 ActivityStack stack = tr.stack; 7365 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7366 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7367 Binder.getCallingUid(), "Task to back")) { 7368 return; 7369 } 7370 } 7371 final long origId = Binder.clearCallingIdentity(); 7372 try { 7373 stack.moveTaskToBackLocked(taskId, null); 7374 } finally { 7375 Binder.restoreCallingIdentity(origId); 7376 } 7377 } 7378 } 7379 } 7380 7381 /** 7382 * Moves an activity, and all of the other activities within the same task, to the bottom 7383 * of the history stack. The activity's order within the task is unchanged. 7384 * 7385 * @param token A reference to the activity we wish to move 7386 * @param nonRoot If false then this only works if the activity is the root 7387 * of a task; if true it will work for any activity in a task. 7388 * @return Returns true if the move completed, false if not. 7389 */ 7390 @Override 7391 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7392 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7393 synchronized(this) { 7394 final long origId = Binder.clearCallingIdentity(); 7395 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7396 if (taskId >= 0) { 7397 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7398 } 7399 Binder.restoreCallingIdentity(origId); 7400 } 7401 return false; 7402 } 7403 7404 @Override 7405 public void moveTaskBackwards(int task) { 7406 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7407 "moveTaskBackwards()"); 7408 7409 synchronized(this) { 7410 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7411 Binder.getCallingUid(), "Task backwards")) { 7412 return; 7413 } 7414 final long origId = Binder.clearCallingIdentity(); 7415 moveTaskBackwardsLocked(task); 7416 Binder.restoreCallingIdentity(origId); 7417 } 7418 } 7419 7420 private final void moveTaskBackwardsLocked(int task) { 7421 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7422 } 7423 7424 @Override 7425 public IBinder getHomeActivityToken() throws RemoteException { 7426 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7427 "getHomeActivityToken()"); 7428 synchronized (this) { 7429 return mStackSupervisor.getHomeActivityToken(); 7430 } 7431 } 7432 7433 @Override 7434 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7435 IActivityContainerCallback callback) throws RemoteException { 7436 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7437 "createActivityContainer()"); 7438 synchronized (this) { 7439 if (parentActivityToken == null) { 7440 throw new IllegalArgumentException("parent token must not be null"); 7441 } 7442 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7443 if (r == null) { 7444 return null; 7445 } 7446 if (callback == null) { 7447 throw new IllegalArgumentException("callback must not be null"); 7448 } 7449 return mStackSupervisor.createActivityContainer(r, callback); 7450 } 7451 } 7452 7453 @Override 7454 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7455 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7456 "deleteActivityContainer()"); 7457 synchronized (this) { 7458 mStackSupervisor.deleteActivityContainer(container); 7459 } 7460 } 7461 7462 @Override 7463 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7464 throws RemoteException { 7465 synchronized (this) { 7466 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7467 if (stack != null) { 7468 return stack.mActivityContainer; 7469 } 7470 return null; 7471 } 7472 } 7473 7474 @Override 7475 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7476 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7477 "moveTaskToStack()"); 7478 if (stackId == HOME_STACK_ID) { 7479 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7480 new RuntimeException("here").fillInStackTrace()); 7481 } 7482 synchronized (this) { 7483 long ident = Binder.clearCallingIdentity(); 7484 try { 7485 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7486 + stackId + " toTop=" + toTop); 7487 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7488 } finally { 7489 Binder.restoreCallingIdentity(ident); 7490 } 7491 } 7492 } 7493 7494 @Override 7495 public void resizeStack(int stackBoxId, Rect bounds) { 7496 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7497 "resizeStackBox()"); 7498 long ident = Binder.clearCallingIdentity(); 7499 try { 7500 mWindowManager.resizeStack(stackBoxId, bounds); 7501 } finally { 7502 Binder.restoreCallingIdentity(ident); 7503 } 7504 } 7505 7506 @Override 7507 public List<StackInfo> getAllStackInfos() { 7508 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7509 "getAllStackInfos()"); 7510 long ident = Binder.clearCallingIdentity(); 7511 try { 7512 synchronized (this) { 7513 return mStackSupervisor.getAllStackInfosLocked(); 7514 } 7515 } finally { 7516 Binder.restoreCallingIdentity(ident); 7517 } 7518 } 7519 7520 @Override 7521 public StackInfo getStackInfo(int stackId) { 7522 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7523 "getStackInfo()"); 7524 long ident = Binder.clearCallingIdentity(); 7525 try { 7526 synchronized (this) { 7527 return mStackSupervisor.getStackInfoLocked(stackId); 7528 } 7529 } finally { 7530 Binder.restoreCallingIdentity(ident); 7531 } 7532 } 7533 7534 @Override 7535 public boolean isInHomeStack(int taskId) { 7536 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7537 "getStackInfo()"); 7538 long ident = Binder.clearCallingIdentity(); 7539 try { 7540 synchronized (this) { 7541 TaskRecord tr = recentTaskForIdLocked(taskId); 7542 if (tr != null) { 7543 return tr.stack.isHomeStack(); 7544 } 7545 } 7546 } finally { 7547 Binder.restoreCallingIdentity(ident); 7548 } 7549 return false; 7550 } 7551 7552 @Override 7553 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7554 synchronized(this) { 7555 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7556 } 7557 } 7558 7559 private boolean isLockTaskAuthorized(ComponentName name) { 7560// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7561// "startLockTaskMode()"); 7562// DevicePolicyManager dpm = (DevicePolicyManager) 7563// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7564// return dpm != null && dpm.isLockTaskPermitted(name); 7565 return true; 7566 } 7567 7568 private void startLockTaskMode(TaskRecord task) { 7569 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7570 return; 7571 } 7572 long ident = Binder.clearCallingIdentity(); 7573 try { 7574 synchronized (this) { 7575 // Since we lost lock on task, make sure it is still there. 7576 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7577 if (task != null) { 7578 mStackSupervisor.setLockTaskModeLocked(task); 7579 } 7580 } 7581 } finally { 7582 Binder.restoreCallingIdentity(ident); 7583 } 7584 } 7585 7586 @Override 7587 public void startLockTaskMode(int taskId) { 7588 long ident = Binder.clearCallingIdentity(); 7589 try { 7590 final TaskRecord task; 7591 synchronized (this) { 7592 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7593 } 7594 if (task != null) { 7595 startLockTaskMode(task); 7596 } 7597 } finally { 7598 Binder.restoreCallingIdentity(ident); 7599 } 7600 } 7601 7602 @Override 7603 public void startLockTaskMode(IBinder token) { 7604 long ident = Binder.clearCallingIdentity(); 7605 try { 7606 final TaskRecord task; 7607 synchronized (this) { 7608 final ActivityRecord r = ActivityRecord.forToken(token); 7609 if (r == null) { 7610 return; 7611 } 7612 task = r.task; 7613 } 7614 if (task != null) { 7615 startLockTaskMode(task); 7616 } 7617 } finally { 7618 Binder.restoreCallingIdentity(ident); 7619 } 7620 } 7621 7622 @Override 7623 public void stopLockTaskMode() { 7624// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7625// "stopLockTaskMode()"); 7626 synchronized (this) { 7627 mStackSupervisor.setLockTaskModeLocked(null); 7628 } 7629 } 7630 7631 @Override 7632 public boolean isInLockTaskMode() { 7633 synchronized (this) { 7634 return mStackSupervisor.isInLockTaskMode(); 7635 } 7636 } 7637 7638 // ========================================================= 7639 // THUMBNAILS 7640 // ========================================================= 7641 7642 public void reportThumbnail(IBinder token, 7643 Bitmap thumbnail, CharSequence description) { 7644 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7645 final long origId = Binder.clearCallingIdentity(); 7646 sendPendingThumbnail(null, token, thumbnail, description, true); 7647 Binder.restoreCallingIdentity(origId); 7648 } 7649 7650 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7651 Bitmap thumbnail, CharSequence description, boolean always) { 7652 TaskRecord task; 7653 ArrayList<PendingThumbnailsRecord> receivers = null; 7654 7655 //System.out.println("Send pending thumbnail: " + r); 7656 7657 synchronized(this) { 7658 if (r == null) { 7659 r = ActivityRecord.isInStackLocked(token); 7660 if (r == null) { 7661 return; 7662 } 7663 } 7664 if (thumbnail == null && r.thumbHolder != null) { 7665 thumbnail = r.thumbHolder.lastThumbnail; 7666 description = r.thumbHolder.lastDescription; 7667 } 7668 if (thumbnail == null && !always) { 7669 // If there is no thumbnail, and this entry is not actually 7670 // going away, then abort for now and pick up the next 7671 // thumbnail we get. 7672 return; 7673 } 7674 task = r.task; 7675 7676 int N = mPendingThumbnails.size(); 7677 int i=0; 7678 while (i<N) { 7679 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7680 //System.out.println("Looking in " + pr.pendingRecords); 7681 if (pr.pendingRecords.remove(r)) { 7682 if (receivers == null) { 7683 receivers = new ArrayList<PendingThumbnailsRecord>(); 7684 } 7685 receivers.add(pr); 7686 if (pr.pendingRecords.size() == 0) { 7687 pr.finished = true; 7688 mPendingThumbnails.remove(i); 7689 N--; 7690 continue; 7691 } 7692 } 7693 i++; 7694 } 7695 } 7696 7697 if (receivers != null) { 7698 final int N = receivers.size(); 7699 for (int i=0; i<N; i++) { 7700 try { 7701 PendingThumbnailsRecord pr = receivers.get(i); 7702 pr.receiver.newThumbnail( 7703 task != null ? task.taskId : -1, thumbnail, description); 7704 if (pr.finished) { 7705 pr.receiver.finished(); 7706 } 7707 } catch (Exception e) { 7708 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7709 } 7710 } 7711 } 7712 } 7713 7714 // ========================================================= 7715 // CONTENT PROVIDERS 7716 // ========================================================= 7717 7718 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7719 List<ProviderInfo> providers = null; 7720 try { 7721 providers = AppGlobals.getPackageManager(). 7722 queryContentProviders(app.processName, app.uid, 7723 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7724 } catch (RemoteException ex) { 7725 } 7726 if (DEBUG_MU) 7727 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7728 int userId = app.userId; 7729 if (providers != null) { 7730 int N = providers.size(); 7731 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7732 for (int i=0; i<N; i++) { 7733 ProviderInfo cpi = 7734 (ProviderInfo)providers.get(i); 7735 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7736 cpi.name, cpi.flags); 7737 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7738 // This is a singleton provider, but a user besides the 7739 // default user is asking to initialize a process it runs 7740 // in... well, no, it doesn't actually run in this process, 7741 // it runs in the process of the default user. Get rid of it. 7742 providers.remove(i); 7743 N--; 7744 i--; 7745 continue; 7746 } 7747 7748 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7749 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7750 if (cpr == null) { 7751 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7752 mProviderMap.putProviderByClass(comp, cpr); 7753 } 7754 if (DEBUG_MU) 7755 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7756 app.pubProviders.put(cpi.name, cpr); 7757 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7758 // Don't add this if it is a platform component that is marked 7759 // to run in multiple processes, because this is actually 7760 // part of the framework so doesn't make sense to track as a 7761 // separate apk in the process. 7762 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7763 } 7764 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7765 } 7766 } 7767 return providers; 7768 } 7769 7770 /** 7771 * Check if {@link ProcessRecord} has a possible chance at accessing the 7772 * given {@link ProviderInfo}. Final permission checking is always done 7773 * in {@link ContentProvider}. 7774 */ 7775 private final String checkContentProviderPermissionLocked( 7776 ProviderInfo cpi, ProcessRecord r) { 7777 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7778 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7779 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7780 cpi.applicationInfo.uid, cpi.exported) 7781 == PackageManager.PERMISSION_GRANTED) { 7782 return null; 7783 } 7784 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7785 cpi.applicationInfo.uid, cpi.exported) 7786 == PackageManager.PERMISSION_GRANTED) { 7787 return null; 7788 } 7789 7790 PathPermission[] pps = cpi.pathPermissions; 7791 if (pps != null) { 7792 int i = pps.length; 7793 while (i > 0) { 7794 i--; 7795 PathPermission pp = pps[i]; 7796 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7797 cpi.applicationInfo.uid, cpi.exported) 7798 == PackageManager.PERMISSION_GRANTED) { 7799 return null; 7800 } 7801 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7802 cpi.applicationInfo.uid, cpi.exported) 7803 == PackageManager.PERMISSION_GRANTED) { 7804 return null; 7805 } 7806 } 7807 } 7808 7809 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7810 if (perms != null) { 7811 for (GrantUri uri : perms.keySet()) { 7812 if (uri.uri.getAuthority().equals(cpi.authority)) { 7813 return null; 7814 } 7815 } 7816 } 7817 7818 String msg; 7819 if (!cpi.exported) { 7820 msg = "Permission Denial: opening provider " + cpi.name 7821 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7822 + ", uid=" + callingUid + ") that is not exported from uid " 7823 + cpi.applicationInfo.uid; 7824 } else { 7825 msg = "Permission Denial: opening provider " + cpi.name 7826 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7827 + ", uid=" + callingUid + ") requires " 7828 + cpi.readPermission + " or " + cpi.writePermission; 7829 } 7830 Slog.w(TAG, msg); 7831 return msg; 7832 } 7833 7834 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7835 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7836 if (r != null) { 7837 for (int i=0; i<r.conProviders.size(); i++) { 7838 ContentProviderConnection conn = r.conProviders.get(i); 7839 if (conn.provider == cpr) { 7840 if (DEBUG_PROVIDER) Slog.v(TAG, 7841 "Adding provider requested by " 7842 + r.processName + " from process " 7843 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7844 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7845 if (stable) { 7846 conn.stableCount++; 7847 conn.numStableIncs++; 7848 } else { 7849 conn.unstableCount++; 7850 conn.numUnstableIncs++; 7851 } 7852 return conn; 7853 } 7854 } 7855 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7856 if (stable) { 7857 conn.stableCount = 1; 7858 conn.numStableIncs = 1; 7859 } else { 7860 conn.unstableCount = 1; 7861 conn.numUnstableIncs = 1; 7862 } 7863 cpr.connections.add(conn); 7864 r.conProviders.add(conn); 7865 return conn; 7866 } 7867 cpr.addExternalProcessHandleLocked(externalProcessToken); 7868 return null; 7869 } 7870 7871 boolean decProviderCountLocked(ContentProviderConnection conn, 7872 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7873 if (conn != null) { 7874 cpr = conn.provider; 7875 if (DEBUG_PROVIDER) Slog.v(TAG, 7876 "Removing provider requested by " 7877 + conn.client.processName + " from process " 7878 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7879 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7880 if (stable) { 7881 conn.stableCount--; 7882 } else { 7883 conn.unstableCount--; 7884 } 7885 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7886 cpr.connections.remove(conn); 7887 conn.client.conProviders.remove(conn); 7888 return true; 7889 } 7890 return false; 7891 } 7892 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7893 return false; 7894 } 7895 7896 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7897 String name, IBinder token, boolean stable, int userId) { 7898 ContentProviderRecord cpr; 7899 ContentProviderConnection conn = null; 7900 ProviderInfo cpi = null; 7901 7902 synchronized(this) { 7903 ProcessRecord r = null; 7904 if (caller != null) { 7905 r = getRecordForAppLocked(caller); 7906 if (r == null) { 7907 throw new SecurityException( 7908 "Unable to find app for caller " + caller 7909 + " (pid=" + Binder.getCallingPid() 7910 + ") when getting content provider " + name); 7911 } 7912 } 7913 7914 // First check if this content provider has been published... 7915 cpr = mProviderMap.getProviderByName(name, userId); 7916 boolean providerRunning = cpr != null; 7917 if (providerRunning) { 7918 cpi = cpr.info; 7919 String msg; 7920 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7921 throw new SecurityException(msg); 7922 } 7923 7924 if (r != null && cpr.canRunHere(r)) { 7925 // This provider has been published or is in the process 7926 // of being published... but it is also allowed to run 7927 // in the caller's process, so don't make a connection 7928 // and just let the caller instantiate its own instance. 7929 ContentProviderHolder holder = cpr.newHolder(null); 7930 // don't give caller the provider object, it needs 7931 // to make its own. 7932 holder.provider = null; 7933 return holder; 7934 } 7935 7936 final long origId = Binder.clearCallingIdentity(); 7937 7938 // In this case the provider instance already exists, so we can 7939 // return it right away. 7940 conn = incProviderCountLocked(r, cpr, token, stable); 7941 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7942 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7943 // If this is a perceptible app accessing the provider, 7944 // make sure to count it as being accessed and thus 7945 // back up on the LRU list. This is good because 7946 // content providers are often expensive to start. 7947 updateLruProcessLocked(cpr.proc, false, null); 7948 } 7949 } 7950 7951 if (cpr.proc != null) { 7952 if (false) { 7953 if (cpr.name.flattenToShortString().equals( 7954 "com.android.providers.calendar/.CalendarProvider2")) { 7955 Slog.v(TAG, "****************** KILLING " 7956 + cpr.name.flattenToShortString()); 7957 Process.killProcess(cpr.proc.pid); 7958 } 7959 } 7960 boolean success = updateOomAdjLocked(cpr.proc); 7961 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7962 // NOTE: there is still a race here where a signal could be 7963 // pending on the process even though we managed to update its 7964 // adj level. Not sure what to do about this, but at least 7965 // the race is now smaller. 7966 if (!success) { 7967 // Uh oh... it looks like the provider's process 7968 // has been killed on us. We need to wait for a new 7969 // process to be started, and make sure its death 7970 // doesn't kill our process. 7971 Slog.i(TAG, 7972 "Existing provider " + cpr.name.flattenToShortString() 7973 + " is crashing; detaching " + r); 7974 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7975 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7976 if (!lastRef) { 7977 // This wasn't the last ref our process had on 7978 // the provider... we have now been killed, bail. 7979 return null; 7980 } 7981 providerRunning = false; 7982 conn = null; 7983 } 7984 } 7985 7986 Binder.restoreCallingIdentity(origId); 7987 } 7988 7989 boolean singleton; 7990 if (!providerRunning) { 7991 try { 7992 cpi = AppGlobals.getPackageManager(). 7993 resolveContentProvider(name, 7994 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7995 } catch (RemoteException ex) { 7996 } 7997 if (cpi == null) { 7998 return null; 7999 } 8000 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8001 cpi.name, cpi.flags); 8002 if (singleton) { 8003 userId = 0; 8004 } 8005 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 8006 8007 String msg; 8008 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 8009 throw new SecurityException(msg); 8010 } 8011 8012 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 8013 && !cpi.processName.equals("system")) { 8014 // If this content provider does not run in the system 8015 // process, and the system is not yet ready to run other 8016 // processes, then fail fast instead of hanging. 8017 throw new IllegalArgumentException( 8018 "Attempt to launch content provider before system ready"); 8019 } 8020 8021 // Make sure that the user who owns this provider is started. If not, 8022 // we don't want to allow it to run. 8023 if (mStartedUsers.get(userId) == null) { 8024 Slog.w(TAG, "Unable to launch app " 8025 + cpi.applicationInfo.packageName + "/" 8026 + cpi.applicationInfo.uid + " for provider " 8027 + name + ": user " + userId + " is stopped"); 8028 return null; 8029 } 8030 8031 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8032 cpr = mProviderMap.getProviderByClass(comp, userId); 8033 final boolean firstClass = cpr == null; 8034 if (firstClass) { 8035 try { 8036 ApplicationInfo ai = 8037 AppGlobals.getPackageManager(). 8038 getApplicationInfo( 8039 cpi.applicationInfo.packageName, 8040 STOCK_PM_FLAGS, userId); 8041 if (ai == null) { 8042 Slog.w(TAG, "No package info for content provider " 8043 + cpi.name); 8044 return null; 8045 } 8046 ai = getAppInfoForUser(ai, userId); 8047 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8048 } catch (RemoteException ex) { 8049 // pm is in same process, this will never happen. 8050 } 8051 } 8052 8053 if (r != null && cpr.canRunHere(r)) { 8054 // If this is a multiprocess provider, then just return its 8055 // info and allow the caller to instantiate it. Only do 8056 // this if the provider is the same user as the caller's 8057 // process, or can run as root (so can be in any process). 8058 return cpr.newHolder(null); 8059 } 8060 8061 if (DEBUG_PROVIDER) { 8062 RuntimeException e = new RuntimeException("here"); 8063 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8064 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8065 } 8066 8067 // This is single process, and our app is now connecting to it. 8068 // See if we are already in the process of launching this 8069 // provider. 8070 final int N = mLaunchingProviders.size(); 8071 int i; 8072 for (i=0; i<N; i++) { 8073 if (mLaunchingProviders.get(i) == cpr) { 8074 break; 8075 } 8076 } 8077 8078 // If the provider is not already being launched, then get it 8079 // started. 8080 if (i >= N) { 8081 final long origId = Binder.clearCallingIdentity(); 8082 8083 try { 8084 // Content provider is now in use, its package can't be stopped. 8085 try { 8086 AppGlobals.getPackageManager().setPackageStoppedState( 8087 cpr.appInfo.packageName, false, userId); 8088 } catch (RemoteException e) { 8089 } catch (IllegalArgumentException e) { 8090 Slog.w(TAG, "Failed trying to unstop package " 8091 + cpr.appInfo.packageName + ": " + e); 8092 } 8093 8094 // Use existing process if already started 8095 ProcessRecord proc = getProcessRecordLocked( 8096 cpi.processName, cpr.appInfo.uid, false); 8097 if (proc != null && proc.thread != null) { 8098 if (DEBUG_PROVIDER) { 8099 Slog.d(TAG, "Installing in existing process " + proc); 8100 } 8101 proc.pubProviders.put(cpi.name, cpr); 8102 try { 8103 proc.thread.scheduleInstallProvider(cpi); 8104 } catch (RemoteException e) { 8105 } 8106 } else { 8107 proc = startProcessLocked(cpi.processName, 8108 cpr.appInfo, false, 0, "content provider", 8109 new ComponentName(cpi.applicationInfo.packageName, 8110 cpi.name), false, false, false); 8111 if (proc == null) { 8112 Slog.w(TAG, "Unable to launch app " 8113 + cpi.applicationInfo.packageName + "/" 8114 + cpi.applicationInfo.uid + " for provider " 8115 + name + ": process is bad"); 8116 return null; 8117 } 8118 } 8119 cpr.launchingApp = proc; 8120 mLaunchingProviders.add(cpr); 8121 } finally { 8122 Binder.restoreCallingIdentity(origId); 8123 } 8124 } 8125 8126 // Make sure the provider is published (the same provider class 8127 // may be published under multiple names). 8128 if (firstClass) { 8129 mProviderMap.putProviderByClass(comp, cpr); 8130 } 8131 8132 mProviderMap.putProviderByName(name, cpr); 8133 conn = incProviderCountLocked(r, cpr, token, stable); 8134 if (conn != null) { 8135 conn.waiting = true; 8136 } 8137 } 8138 } 8139 8140 // Wait for the provider to be published... 8141 synchronized (cpr) { 8142 while (cpr.provider == null) { 8143 if (cpr.launchingApp == null) { 8144 Slog.w(TAG, "Unable to launch app " 8145 + cpi.applicationInfo.packageName + "/" 8146 + cpi.applicationInfo.uid + " for provider " 8147 + name + ": launching app became null"); 8148 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8149 UserHandle.getUserId(cpi.applicationInfo.uid), 8150 cpi.applicationInfo.packageName, 8151 cpi.applicationInfo.uid, name); 8152 return null; 8153 } 8154 try { 8155 if (DEBUG_MU) { 8156 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8157 + cpr.launchingApp); 8158 } 8159 if (conn != null) { 8160 conn.waiting = true; 8161 } 8162 cpr.wait(); 8163 } catch (InterruptedException ex) { 8164 } finally { 8165 if (conn != null) { 8166 conn.waiting = false; 8167 } 8168 } 8169 } 8170 } 8171 return cpr != null ? cpr.newHolder(conn) : null; 8172 } 8173 8174 public final ContentProviderHolder getContentProvider( 8175 IApplicationThread caller, String name, int userId, boolean stable) { 8176 enforceNotIsolatedCaller("getContentProvider"); 8177 if (caller == null) { 8178 String msg = "null IApplicationThread when getting content provider " 8179 + name; 8180 Slog.w(TAG, msg); 8181 throw new SecurityException(msg); 8182 } 8183 8184 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8185 false, true, "getContentProvider", null); 8186 return getContentProviderImpl(caller, name, null, stable, userId); 8187 } 8188 8189 public ContentProviderHolder getContentProviderExternal( 8190 String name, int userId, IBinder token) { 8191 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8192 "Do not have permission in call getContentProviderExternal()"); 8193 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8194 false, true, "getContentProvider", null); 8195 return getContentProviderExternalUnchecked(name, token, userId); 8196 } 8197 8198 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8199 IBinder token, int userId) { 8200 return getContentProviderImpl(null, name, token, true, userId); 8201 } 8202 8203 /** 8204 * Drop a content provider from a ProcessRecord's bookkeeping 8205 */ 8206 public void removeContentProvider(IBinder connection, boolean stable) { 8207 enforceNotIsolatedCaller("removeContentProvider"); 8208 long ident = Binder.clearCallingIdentity(); 8209 try { 8210 synchronized (this) { 8211 ContentProviderConnection conn; 8212 try { 8213 conn = (ContentProviderConnection)connection; 8214 } catch (ClassCastException e) { 8215 String msg ="removeContentProvider: " + connection 8216 + " not a ContentProviderConnection"; 8217 Slog.w(TAG, msg); 8218 throw new IllegalArgumentException(msg); 8219 } 8220 if (conn == null) { 8221 throw new NullPointerException("connection is null"); 8222 } 8223 if (decProviderCountLocked(conn, null, null, stable)) { 8224 updateOomAdjLocked(); 8225 } 8226 } 8227 } finally { 8228 Binder.restoreCallingIdentity(ident); 8229 } 8230 } 8231 8232 public void removeContentProviderExternal(String name, IBinder token) { 8233 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8234 "Do not have permission in call removeContentProviderExternal()"); 8235 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8236 } 8237 8238 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8239 synchronized (this) { 8240 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8241 if(cpr == null) { 8242 //remove from mProvidersByClass 8243 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8244 return; 8245 } 8246 8247 //update content provider record entry info 8248 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8249 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8250 if (localCpr.hasExternalProcessHandles()) { 8251 if (localCpr.removeExternalProcessHandleLocked(token)) { 8252 updateOomAdjLocked(); 8253 } else { 8254 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8255 + " with no external reference for token: " 8256 + token + "."); 8257 } 8258 } else { 8259 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8260 + " with no external references."); 8261 } 8262 } 8263 } 8264 8265 public final void publishContentProviders(IApplicationThread caller, 8266 List<ContentProviderHolder> providers) { 8267 if (providers == null) { 8268 return; 8269 } 8270 8271 enforceNotIsolatedCaller("publishContentProviders"); 8272 synchronized (this) { 8273 final ProcessRecord r = getRecordForAppLocked(caller); 8274 if (DEBUG_MU) 8275 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8276 if (r == null) { 8277 throw new SecurityException( 8278 "Unable to find app for caller " + caller 8279 + " (pid=" + Binder.getCallingPid() 8280 + ") when publishing content providers"); 8281 } 8282 8283 final long origId = Binder.clearCallingIdentity(); 8284 8285 final int N = providers.size(); 8286 for (int i=0; i<N; i++) { 8287 ContentProviderHolder src = providers.get(i); 8288 if (src == null || src.info == null || src.provider == null) { 8289 continue; 8290 } 8291 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8292 if (DEBUG_MU) 8293 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8294 if (dst != null) { 8295 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8296 mProviderMap.putProviderByClass(comp, dst); 8297 String names[] = dst.info.authority.split(";"); 8298 for (int j = 0; j < names.length; j++) { 8299 mProviderMap.putProviderByName(names[j], dst); 8300 } 8301 8302 int NL = mLaunchingProviders.size(); 8303 int j; 8304 for (j=0; j<NL; j++) { 8305 if (mLaunchingProviders.get(j) == dst) { 8306 mLaunchingProviders.remove(j); 8307 j--; 8308 NL--; 8309 } 8310 } 8311 synchronized (dst) { 8312 dst.provider = src.provider; 8313 dst.proc = r; 8314 dst.notifyAll(); 8315 } 8316 updateOomAdjLocked(r); 8317 } 8318 } 8319 8320 Binder.restoreCallingIdentity(origId); 8321 } 8322 } 8323 8324 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8325 ContentProviderConnection conn; 8326 try { 8327 conn = (ContentProviderConnection)connection; 8328 } catch (ClassCastException e) { 8329 String msg ="refContentProvider: " + connection 8330 + " not a ContentProviderConnection"; 8331 Slog.w(TAG, msg); 8332 throw new IllegalArgumentException(msg); 8333 } 8334 if (conn == null) { 8335 throw new NullPointerException("connection is null"); 8336 } 8337 8338 synchronized (this) { 8339 if (stable > 0) { 8340 conn.numStableIncs += stable; 8341 } 8342 stable = conn.stableCount + stable; 8343 if (stable < 0) { 8344 throw new IllegalStateException("stableCount < 0: " + stable); 8345 } 8346 8347 if (unstable > 0) { 8348 conn.numUnstableIncs += unstable; 8349 } 8350 unstable = conn.unstableCount + unstable; 8351 if (unstable < 0) { 8352 throw new IllegalStateException("unstableCount < 0: " + unstable); 8353 } 8354 8355 if ((stable+unstable) <= 0) { 8356 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8357 + stable + " unstable=" + unstable); 8358 } 8359 conn.stableCount = stable; 8360 conn.unstableCount = unstable; 8361 return !conn.dead; 8362 } 8363 } 8364 8365 public void unstableProviderDied(IBinder connection) { 8366 ContentProviderConnection conn; 8367 try { 8368 conn = (ContentProviderConnection)connection; 8369 } catch (ClassCastException e) { 8370 String msg ="refContentProvider: " + connection 8371 + " not a ContentProviderConnection"; 8372 Slog.w(TAG, msg); 8373 throw new IllegalArgumentException(msg); 8374 } 8375 if (conn == null) { 8376 throw new NullPointerException("connection is null"); 8377 } 8378 8379 // Safely retrieve the content provider associated with the connection. 8380 IContentProvider provider; 8381 synchronized (this) { 8382 provider = conn.provider.provider; 8383 } 8384 8385 if (provider == null) { 8386 // Um, yeah, we're way ahead of you. 8387 return; 8388 } 8389 8390 // Make sure the caller is being honest with us. 8391 if (provider.asBinder().pingBinder()) { 8392 // Er, no, still looks good to us. 8393 synchronized (this) { 8394 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8395 + " says " + conn + " died, but we don't agree"); 8396 return; 8397 } 8398 } 8399 8400 // Well look at that! It's dead! 8401 synchronized (this) { 8402 if (conn.provider.provider != provider) { 8403 // But something changed... good enough. 8404 return; 8405 } 8406 8407 ProcessRecord proc = conn.provider.proc; 8408 if (proc == null || proc.thread == null) { 8409 // Seems like the process is already cleaned up. 8410 return; 8411 } 8412 8413 // As far as we're concerned, this is just like receiving a 8414 // death notification... just a bit prematurely. 8415 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8416 + ") early provider death"); 8417 final long ident = Binder.clearCallingIdentity(); 8418 try { 8419 appDiedLocked(proc, proc.pid, proc.thread); 8420 } finally { 8421 Binder.restoreCallingIdentity(ident); 8422 } 8423 } 8424 } 8425 8426 @Override 8427 public void appNotRespondingViaProvider(IBinder connection) { 8428 enforceCallingPermission( 8429 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8430 8431 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8432 if (conn == null) { 8433 Slog.w(TAG, "ContentProviderConnection is null"); 8434 return; 8435 } 8436 8437 final ProcessRecord host = conn.provider.proc; 8438 if (host == null) { 8439 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8440 return; 8441 } 8442 8443 final long token = Binder.clearCallingIdentity(); 8444 try { 8445 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8446 } finally { 8447 Binder.restoreCallingIdentity(token); 8448 } 8449 } 8450 8451 public final void installSystemProviders() { 8452 List<ProviderInfo> providers; 8453 synchronized (this) { 8454 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8455 providers = generateApplicationProvidersLocked(app); 8456 if (providers != null) { 8457 for (int i=providers.size()-1; i>=0; i--) { 8458 ProviderInfo pi = (ProviderInfo)providers.get(i); 8459 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8460 Slog.w(TAG, "Not installing system proc provider " + pi.name 8461 + ": not system .apk"); 8462 providers.remove(i); 8463 } 8464 } 8465 } 8466 } 8467 if (providers != null) { 8468 mSystemThread.installSystemProviders(providers); 8469 } 8470 8471 mCoreSettingsObserver = new CoreSettingsObserver(this); 8472 8473 mUsageStatsService.monitorPackages(); 8474 } 8475 8476 /** 8477 * Allows app to retrieve the MIME type of a URI without having permission 8478 * to access its content provider. 8479 * 8480 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8481 * 8482 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8483 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8484 */ 8485 public String getProviderMimeType(Uri uri, int userId) { 8486 enforceNotIsolatedCaller("getProviderMimeType"); 8487 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8488 userId, false, true, "getProviderMimeType", null); 8489 final String name = uri.getAuthority(); 8490 final long ident = Binder.clearCallingIdentity(); 8491 ContentProviderHolder holder = null; 8492 8493 try { 8494 holder = getContentProviderExternalUnchecked(name, null, userId); 8495 if (holder != null) { 8496 return holder.provider.getType(uri); 8497 } 8498 } catch (RemoteException e) { 8499 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8500 return null; 8501 } finally { 8502 if (holder != null) { 8503 removeContentProviderExternalUnchecked(name, null, userId); 8504 } 8505 Binder.restoreCallingIdentity(ident); 8506 } 8507 8508 return null; 8509 } 8510 8511 // ========================================================= 8512 // GLOBAL MANAGEMENT 8513 // ========================================================= 8514 8515 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8516 boolean isolated) { 8517 String proc = customProcess != null ? customProcess : info.processName; 8518 BatteryStatsImpl.Uid.Proc ps = null; 8519 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8520 int uid = info.uid; 8521 if (isolated) { 8522 int userId = UserHandle.getUserId(uid); 8523 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8524 while (true) { 8525 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8526 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8527 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8528 } 8529 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8530 mNextIsolatedProcessUid++; 8531 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8532 // No process for this uid, use it. 8533 break; 8534 } 8535 stepsLeft--; 8536 if (stepsLeft <= 0) { 8537 return null; 8538 } 8539 } 8540 } 8541 return new ProcessRecord(stats, info, proc, uid); 8542 } 8543 8544 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8545 ProcessRecord app; 8546 if (!isolated) { 8547 app = getProcessRecordLocked(info.processName, info.uid, true); 8548 } else { 8549 app = null; 8550 } 8551 8552 if (app == null) { 8553 app = newProcessRecordLocked(info, null, isolated); 8554 mProcessNames.put(info.processName, app.uid, app); 8555 if (isolated) { 8556 mIsolatedProcesses.put(app.uid, app); 8557 } 8558 updateLruProcessLocked(app, false, null); 8559 updateOomAdjLocked(); 8560 } 8561 8562 // This package really, really can not be stopped. 8563 try { 8564 AppGlobals.getPackageManager().setPackageStoppedState( 8565 info.packageName, false, UserHandle.getUserId(app.uid)); 8566 } catch (RemoteException e) { 8567 } catch (IllegalArgumentException e) { 8568 Slog.w(TAG, "Failed trying to unstop package " 8569 + info.packageName + ": " + e); 8570 } 8571 8572 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8573 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8574 app.persistent = true; 8575 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8576 } 8577 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8578 mPersistentStartingProcesses.add(app); 8579 startProcessLocked(app, "added application", app.processName); 8580 } 8581 8582 return app; 8583 } 8584 8585 public void unhandledBack() { 8586 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8587 "unhandledBack()"); 8588 8589 synchronized(this) { 8590 final long origId = Binder.clearCallingIdentity(); 8591 try { 8592 getFocusedStack().unhandledBackLocked(); 8593 } finally { 8594 Binder.restoreCallingIdentity(origId); 8595 } 8596 } 8597 } 8598 8599 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8600 enforceNotIsolatedCaller("openContentUri"); 8601 final int userId = UserHandle.getCallingUserId(); 8602 String name = uri.getAuthority(); 8603 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8604 ParcelFileDescriptor pfd = null; 8605 if (cph != null) { 8606 // We record the binder invoker's uid in thread-local storage before 8607 // going to the content provider to open the file. Later, in the code 8608 // that handles all permissions checks, we look for this uid and use 8609 // that rather than the Activity Manager's own uid. The effect is that 8610 // we do the check against the caller's permissions even though it looks 8611 // to the content provider like the Activity Manager itself is making 8612 // the request. 8613 sCallerIdentity.set(new Identity( 8614 Binder.getCallingPid(), Binder.getCallingUid())); 8615 try { 8616 pfd = cph.provider.openFile(null, uri, "r", null); 8617 } catch (FileNotFoundException e) { 8618 // do nothing; pfd will be returned null 8619 } finally { 8620 // Ensure that whatever happens, we clean up the identity state 8621 sCallerIdentity.remove(); 8622 } 8623 8624 // We've got the fd now, so we're done with the provider. 8625 removeContentProviderExternalUnchecked(name, null, userId); 8626 } else { 8627 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8628 } 8629 return pfd; 8630 } 8631 8632 // Actually is sleeping or shutting down or whatever else in the future 8633 // is an inactive state. 8634 public boolean isSleepingOrShuttingDown() { 8635 return mSleeping || mShuttingDown; 8636 } 8637 8638 public boolean isSleeping() { 8639 return mSleeping; 8640 } 8641 8642 void goingToSleep() { 8643 synchronized(this) { 8644 mWentToSleep = true; 8645 updateEventDispatchingLocked(); 8646 goToSleepIfNeededLocked(); 8647 } 8648 } 8649 8650 void finishRunningVoiceLocked() { 8651 if (mRunningVoice) { 8652 mRunningVoice = false; 8653 goToSleepIfNeededLocked(); 8654 } 8655 } 8656 8657 void goToSleepIfNeededLocked() { 8658 if (mWentToSleep && !mRunningVoice) { 8659 if (!mSleeping) { 8660 mSleeping = true; 8661 mStackSupervisor.goingToSleepLocked(); 8662 8663 // Initialize the wake times of all processes. 8664 checkExcessivePowerUsageLocked(false); 8665 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8666 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8667 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8668 } 8669 } 8670 } 8671 8672 @Override 8673 public boolean shutdown(int timeout) { 8674 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8675 != PackageManager.PERMISSION_GRANTED) { 8676 throw new SecurityException("Requires permission " 8677 + android.Manifest.permission.SHUTDOWN); 8678 } 8679 8680 boolean timedout = false; 8681 8682 synchronized(this) { 8683 mShuttingDown = true; 8684 updateEventDispatchingLocked(); 8685 timedout = mStackSupervisor.shutdownLocked(timeout); 8686 } 8687 8688 mAppOpsService.shutdown(); 8689 mUsageStatsService.shutdown(); 8690 mBatteryStatsService.shutdown(); 8691 synchronized (this) { 8692 mProcessStats.shutdownLocked(); 8693 } 8694 8695 return timedout; 8696 } 8697 8698 public final void activitySlept(IBinder token) { 8699 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8700 8701 final long origId = Binder.clearCallingIdentity(); 8702 8703 synchronized (this) { 8704 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8705 if (r != null) { 8706 mStackSupervisor.activitySleptLocked(r); 8707 } 8708 } 8709 8710 Binder.restoreCallingIdentity(origId); 8711 } 8712 8713 void logLockScreen(String msg) { 8714 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8715 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8716 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8717 mStackSupervisor.mDismissKeyguardOnNextActivity); 8718 } 8719 8720 private void comeOutOfSleepIfNeededLocked() { 8721 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8722 if (mSleeping) { 8723 mSleeping = false; 8724 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8725 } 8726 } 8727 } 8728 8729 void wakingUp() { 8730 synchronized(this) { 8731 mWentToSleep = false; 8732 updateEventDispatchingLocked(); 8733 comeOutOfSleepIfNeededLocked(); 8734 } 8735 } 8736 8737 void startRunningVoiceLocked() { 8738 if (!mRunningVoice) { 8739 mRunningVoice = true; 8740 comeOutOfSleepIfNeededLocked(); 8741 } 8742 } 8743 8744 private void updateEventDispatchingLocked() { 8745 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8746 } 8747 8748 public void setLockScreenShown(boolean shown) { 8749 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8750 != PackageManager.PERMISSION_GRANTED) { 8751 throw new SecurityException("Requires permission " 8752 + android.Manifest.permission.DEVICE_POWER); 8753 } 8754 8755 synchronized(this) { 8756 long ident = Binder.clearCallingIdentity(); 8757 try { 8758 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8759 mLockScreenShown = shown; 8760 comeOutOfSleepIfNeededLocked(); 8761 } finally { 8762 Binder.restoreCallingIdentity(ident); 8763 } 8764 } 8765 } 8766 8767 public void stopAppSwitches() { 8768 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8769 != PackageManager.PERMISSION_GRANTED) { 8770 throw new SecurityException("Requires permission " 8771 + android.Manifest.permission.STOP_APP_SWITCHES); 8772 } 8773 8774 synchronized(this) { 8775 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8776 + APP_SWITCH_DELAY_TIME; 8777 mDidAppSwitch = false; 8778 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8779 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8780 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8781 } 8782 } 8783 8784 public void resumeAppSwitches() { 8785 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8786 != PackageManager.PERMISSION_GRANTED) { 8787 throw new SecurityException("Requires permission " 8788 + android.Manifest.permission.STOP_APP_SWITCHES); 8789 } 8790 8791 synchronized(this) { 8792 // Note that we don't execute any pending app switches... we will 8793 // let those wait until either the timeout, or the next start 8794 // activity request. 8795 mAppSwitchesAllowedTime = 0; 8796 } 8797 } 8798 8799 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8800 String name) { 8801 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8802 return true; 8803 } 8804 8805 final int perm = checkComponentPermission( 8806 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8807 callingUid, -1, true); 8808 if (perm == PackageManager.PERMISSION_GRANTED) { 8809 return true; 8810 } 8811 8812 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8813 return false; 8814 } 8815 8816 public void setDebugApp(String packageName, boolean waitForDebugger, 8817 boolean persistent) { 8818 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8819 "setDebugApp()"); 8820 8821 long ident = Binder.clearCallingIdentity(); 8822 try { 8823 // Note that this is not really thread safe if there are multiple 8824 // callers into it at the same time, but that's not a situation we 8825 // care about. 8826 if (persistent) { 8827 final ContentResolver resolver = mContext.getContentResolver(); 8828 Settings.Global.putString( 8829 resolver, Settings.Global.DEBUG_APP, 8830 packageName); 8831 Settings.Global.putInt( 8832 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8833 waitForDebugger ? 1 : 0); 8834 } 8835 8836 synchronized (this) { 8837 if (!persistent) { 8838 mOrigDebugApp = mDebugApp; 8839 mOrigWaitForDebugger = mWaitForDebugger; 8840 } 8841 mDebugApp = packageName; 8842 mWaitForDebugger = waitForDebugger; 8843 mDebugTransient = !persistent; 8844 if (packageName != null) { 8845 forceStopPackageLocked(packageName, -1, false, false, true, true, 8846 false, UserHandle.USER_ALL, "set debug app"); 8847 } 8848 } 8849 } finally { 8850 Binder.restoreCallingIdentity(ident); 8851 } 8852 } 8853 8854 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8855 synchronized (this) { 8856 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8857 if (!isDebuggable) { 8858 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8859 throw new SecurityException("Process not debuggable: " + app.packageName); 8860 } 8861 } 8862 8863 mOpenGlTraceApp = processName; 8864 } 8865 } 8866 8867 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8868 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8869 synchronized (this) { 8870 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8871 if (!isDebuggable) { 8872 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8873 throw new SecurityException("Process not debuggable: " + app.packageName); 8874 } 8875 } 8876 mProfileApp = processName; 8877 mProfileFile = profileFile; 8878 if (mProfileFd != null) { 8879 try { 8880 mProfileFd.close(); 8881 } catch (IOException e) { 8882 } 8883 mProfileFd = null; 8884 } 8885 mProfileFd = profileFd; 8886 mProfileType = 0; 8887 mAutoStopProfiler = autoStopProfiler; 8888 } 8889 } 8890 8891 @Override 8892 public void setAlwaysFinish(boolean enabled) { 8893 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8894 "setAlwaysFinish()"); 8895 8896 Settings.Global.putInt( 8897 mContext.getContentResolver(), 8898 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8899 8900 synchronized (this) { 8901 mAlwaysFinishActivities = enabled; 8902 } 8903 } 8904 8905 @Override 8906 public void setActivityController(IActivityController controller) { 8907 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8908 "setActivityController()"); 8909 synchronized (this) { 8910 mController = controller; 8911 Watchdog.getInstance().setActivityController(controller); 8912 } 8913 } 8914 8915 @Override 8916 public void setUserIsMonkey(boolean userIsMonkey) { 8917 synchronized (this) { 8918 synchronized (mPidsSelfLocked) { 8919 final int callingPid = Binder.getCallingPid(); 8920 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8921 if (precessRecord == null) { 8922 throw new SecurityException("Unknown process: " + callingPid); 8923 } 8924 if (precessRecord.instrumentationUiAutomationConnection == null) { 8925 throw new SecurityException("Only an instrumentation process " 8926 + "with a UiAutomation can call setUserIsMonkey"); 8927 } 8928 } 8929 mUserIsMonkey = userIsMonkey; 8930 } 8931 } 8932 8933 @Override 8934 public boolean isUserAMonkey() { 8935 synchronized (this) { 8936 // If there is a controller also implies the user is a monkey. 8937 return (mUserIsMonkey || mController != null); 8938 } 8939 } 8940 8941 public void requestBugReport() { 8942 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8943 SystemProperties.set("ctl.start", "bugreport"); 8944 } 8945 8946 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8947 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8948 } 8949 8950 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8951 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8952 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8953 } 8954 return KEY_DISPATCHING_TIMEOUT; 8955 } 8956 8957 @Override 8958 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8959 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8960 != PackageManager.PERMISSION_GRANTED) { 8961 throw new SecurityException("Requires permission " 8962 + android.Manifest.permission.FILTER_EVENTS); 8963 } 8964 ProcessRecord proc; 8965 long timeout; 8966 synchronized (this) { 8967 synchronized (mPidsSelfLocked) { 8968 proc = mPidsSelfLocked.get(pid); 8969 } 8970 timeout = getInputDispatchingTimeoutLocked(proc); 8971 } 8972 8973 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8974 return -1; 8975 } 8976 8977 return timeout; 8978 } 8979 8980 /** 8981 * Handle input dispatching timeouts. 8982 * Returns whether input dispatching should be aborted or not. 8983 */ 8984 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8985 final ActivityRecord activity, final ActivityRecord parent, 8986 final boolean aboveSystem, String reason) { 8987 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8988 != PackageManager.PERMISSION_GRANTED) { 8989 throw new SecurityException("Requires permission " 8990 + android.Manifest.permission.FILTER_EVENTS); 8991 } 8992 8993 final String annotation; 8994 if (reason == null) { 8995 annotation = "Input dispatching timed out"; 8996 } else { 8997 annotation = "Input dispatching timed out (" + reason + ")"; 8998 } 8999 9000 if (proc != null) { 9001 synchronized (this) { 9002 if (proc.debugging) { 9003 return false; 9004 } 9005 9006 if (mDidDexOpt) { 9007 // Give more time since we were dexopting. 9008 mDidDexOpt = false; 9009 return false; 9010 } 9011 9012 if (proc.instrumentationClass != null) { 9013 Bundle info = new Bundle(); 9014 info.putString("shortMsg", "keyDispatchingTimedOut"); 9015 info.putString("longMsg", annotation); 9016 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 9017 return true; 9018 } 9019 } 9020 mHandler.post(new Runnable() { 9021 @Override 9022 public void run() { 9023 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9024 } 9025 }); 9026 } 9027 9028 return true; 9029 } 9030 9031 public Bundle getAssistContextExtras(int requestType) { 9032 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9033 "getAssistContextExtras()"); 9034 PendingAssistExtras pae; 9035 Bundle extras = new Bundle(); 9036 synchronized (this) { 9037 ActivityRecord activity = getFocusedStack().mResumedActivity; 9038 if (activity == null) { 9039 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9040 return null; 9041 } 9042 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9043 if (activity.app == null || activity.app.thread == null) { 9044 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9045 return extras; 9046 } 9047 if (activity.app.pid == Binder.getCallingPid()) { 9048 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9049 return extras; 9050 } 9051 pae = new PendingAssistExtras(activity); 9052 try { 9053 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9054 requestType); 9055 mPendingAssistExtras.add(pae); 9056 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9057 } catch (RemoteException e) { 9058 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9059 return extras; 9060 } 9061 } 9062 synchronized (pae) { 9063 while (!pae.haveResult) { 9064 try { 9065 pae.wait(); 9066 } catch (InterruptedException e) { 9067 } 9068 } 9069 if (pae.result != null) { 9070 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9071 } 9072 } 9073 synchronized (this) { 9074 mPendingAssistExtras.remove(pae); 9075 mHandler.removeCallbacks(pae); 9076 } 9077 return extras; 9078 } 9079 9080 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9081 PendingAssistExtras pae = (PendingAssistExtras)token; 9082 synchronized (pae) { 9083 pae.result = extras; 9084 pae.haveResult = true; 9085 pae.notifyAll(); 9086 } 9087 } 9088 9089 public void registerProcessObserver(IProcessObserver observer) { 9090 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9091 "registerProcessObserver()"); 9092 synchronized (this) { 9093 mProcessObservers.register(observer); 9094 } 9095 } 9096 9097 @Override 9098 public void unregisterProcessObserver(IProcessObserver observer) { 9099 synchronized (this) { 9100 mProcessObservers.unregister(observer); 9101 } 9102 } 9103 9104 @Override 9105 public boolean convertFromTranslucent(IBinder token) { 9106 final long origId = Binder.clearCallingIdentity(); 9107 try { 9108 synchronized (this) { 9109 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9110 if (r == null) { 9111 return false; 9112 } 9113 if (r.changeWindowTranslucency(true)) { 9114 mWindowManager.setAppFullscreen(token, true); 9115 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9116 return true; 9117 } 9118 return false; 9119 } 9120 } finally { 9121 Binder.restoreCallingIdentity(origId); 9122 } 9123 } 9124 9125 @Override 9126 public boolean convertToTranslucent(IBinder token) { 9127 final long origId = Binder.clearCallingIdentity(); 9128 try { 9129 synchronized (this) { 9130 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9131 if (r == null) { 9132 return false; 9133 } 9134 if (r.changeWindowTranslucency(false)) { 9135 r.task.stack.convertToTranslucent(r); 9136 mWindowManager.setAppFullscreen(token, false); 9137 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9138 return true; 9139 } 9140 return false; 9141 } 9142 } finally { 9143 Binder.restoreCallingIdentity(origId); 9144 } 9145 } 9146 9147 @Override 9148 public void setImmersive(IBinder token, boolean immersive) { 9149 synchronized(this) { 9150 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9151 if (r == null) { 9152 throw new IllegalArgumentException(); 9153 } 9154 r.immersive = immersive; 9155 9156 // update associated state if we're frontmost 9157 if (r == mFocusedActivity) { 9158 if (DEBUG_IMMERSIVE) { 9159 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9160 } 9161 applyUpdateLockStateLocked(r); 9162 } 9163 } 9164 } 9165 9166 @Override 9167 public boolean isImmersive(IBinder token) { 9168 synchronized (this) { 9169 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9170 if (r == null) { 9171 throw new IllegalArgumentException(); 9172 } 9173 return r.immersive; 9174 } 9175 } 9176 9177 public boolean isTopActivityImmersive() { 9178 enforceNotIsolatedCaller("startActivity"); 9179 synchronized (this) { 9180 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9181 return (r != null) ? r.immersive : false; 9182 } 9183 } 9184 9185 public final void enterSafeMode() { 9186 synchronized(this) { 9187 // It only makes sense to do this before the system is ready 9188 // and started launching other packages. 9189 if (!mSystemReady) { 9190 try { 9191 AppGlobals.getPackageManager().enterSafeMode(); 9192 } catch (RemoteException e) { 9193 } 9194 } 9195 9196 mSafeMode = true; 9197 } 9198 } 9199 9200 public final void showSafeModeOverlay() { 9201 View v = LayoutInflater.from(mContext).inflate( 9202 com.android.internal.R.layout.safe_mode, null); 9203 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9204 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9205 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9206 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9207 lp.gravity = Gravity.BOTTOM | Gravity.START; 9208 lp.format = v.getBackground().getOpacity(); 9209 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9210 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9211 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9212 ((WindowManager)mContext.getSystemService( 9213 Context.WINDOW_SERVICE)).addView(v, lp); 9214 } 9215 9216 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9217 if (!(sender instanceof PendingIntentRecord)) { 9218 return; 9219 } 9220 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9221 synchronized (stats) { 9222 if (mBatteryStatsService.isOnBattery()) { 9223 mBatteryStatsService.enforceCallingPermission(); 9224 PendingIntentRecord rec = (PendingIntentRecord)sender; 9225 int MY_UID = Binder.getCallingUid(); 9226 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9227 BatteryStatsImpl.Uid.Pkg pkg = 9228 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9229 sourcePkg != null ? sourcePkg : rec.key.packageName); 9230 pkg.incWakeupsLocked(); 9231 } 9232 } 9233 } 9234 9235 public boolean killPids(int[] pids, String pReason, boolean secure) { 9236 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9237 throw new SecurityException("killPids only available to the system"); 9238 } 9239 String reason = (pReason == null) ? "Unknown" : pReason; 9240 // XXX Note: don't acquire main activity lock here, because the window 9241 // manager calls in with its locks held. 9242 9243 boolean killed = false; 9244 synchronized (mPidsSelfLocked) { 9245 int[] types = new int[pids.length]; 9246 int worstType = 0; 9247 for (int i=0; i<pids.length; i++) { 9248 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9249 if (proc != null) { 9250 int type = proc.setAdj; 9251 types[i] = type; 9252 if (type > worstType) { 9253 worstType = type; 9254 } 9255 } 9256 } 9257 9258 // If the worst oom_adj is somewhere in the cached proc LRU range, 9259 // then constrain it so we will kill all cached procs. 9260 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9261 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9262 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9263 } 9264 9265 // If this is not a secure call, don't let it kill processes that 9266 // are important. 9267 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9268 worstType = ProcessList.SERVICE_ADJ; 9269 } 9270 9271 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9272 for (int i=0; i<pids.length; i++) { 9273 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9274 if (proc == null) { 9275 continue; 9276 } 9277 int adj = proc.setAdj; 9278 if (adj >= worstType && !proc.killedByAm) { 9279 killUnneededProcessLocked(proc, reason); 9280 killed = true; 9281 } 9282 } 9283 } 9284 return killed; 9285 } 9286 9287 @Override 9288 public void killUid(int uid, String reason) { 9289 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9290 throw new SecurityException("killUid only available to the system"); 9291 } 9292 synchronized (this) { 9293 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9294 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9295 reason != null ? reason : "kill uid"); 9296 } 9297 } 9298 9299 @Override 9300 public boolean killProcessesBelowForeground(String reason) { 9301 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9302 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9303 } 9304 9305 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9306 } 9307 9308 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9309 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9310 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9311 } 9312 9313 boolean killed = false; 9314 synchronized (mPidsSelfLocked) { 9315 final int size = mPidsSelfLocked.size(); 9316 for (int i = 0; i < size; i++) { 9317 final int pid = mPidsSelfLocked.keyAt(i); 9318 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9319 if (proc == null) continue; 9320 9321 final int adj = proc.setAdj; 9322 if (adj > belowAdj && !proc.killedByAm) { 9323 killUnneededProcessLocked(proc, reason); 9324 killed = true; 9325 } 9326 } 9327 } 9328 return killed; 9329 } 9330 9331 @Override 9332 public void hang(final IBinder who, boolean allowRestart) { 9333 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9334 != PackageManager.PERMISSION_GRANTED) { 9335 throw new SecurityException("Requires permission " 9336 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9337 } 9338 9339 final IBinder.DeathRecipient death = new DeathRecipient() { 9340 @Override 9341 public void binderDied() { 9342 synchronized (this) { 9343 notifyAll(); 9344 } 9345 } 9346 }; 9347 9348 try { 9349 who.linkToDeath(death, 0); 9350 } catch (RemoteException e) { 9351 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9352 return; 9353 } 9354 9355 synchronized (this) { 9356 Watchdog.getInstance().setAllowRestart(allowRestart); 9357 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9358 synchronized (death) { 9359 while (who.isBinderAlive()) { 9360 try { 9361 death.wait(); 9362 } catch (InterruptedException e) { 9363 } 9364 } 9365 } 9366 Watchdog.getInstance().setAllowRestart(true); 9367 } 9368 } 9369 9370 @Override 9371 public void restart() { 9372 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9373 != PackageManager.PERMISSION_GRANTED) { 9374 throw new SecurityException("Requires permission " 9375 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9376 } 9377 9378 Log.i(TAG, "Sending shutdown broadcast..."); 9379 9380 BroadcastReceiver br = new BroadcastReceiver() { 9381 @Override public void onReceive(Context context, Intent intent) { 9382 // Now the broadcast is done, finish up the low-level shutdown. 9383 Log.i(TAG, "Shutting down activity manager..."); 9384 shutdown(10000); 9385 Log.i(TAG, "Shutdown complete, restarting!"); 9386 Process.killProcess(Process.myPid()); 9387 System.exit(10); 9388 } 9389 }; 9390 9391 // First send the high-level shut down broadcast. 9392 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9393 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9394 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9395 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9396 mContext.sendOrderedBroadcastAsUser(intent, 9397 UserHandle.ALL, null, br, mHandler, 0, null, null); 9398 */ 9399 br.onReceive(mContext, intent); 9400 } 9401 9402 private long getLowRamTimeSinceIdle(long now) { 9403 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9404 } 9405 9406 @Override 9407 public void performIdleMaintenance() { 9408 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9409 != PackageManager.PERMISSION_GRANTED) { 9410 throw new SecurityException("Requires permission " 9411 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9412 } 9413 9414 synchronized (this) { 9415 final long now = SystemClock.uptimeMillis(); 9416 final long timeSinceLastIdle = now - mLastIdleTime; 9417 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9418 mLastIdleTime = now; 9419 mLowRamTimeSinceLastIdle = 0; 9420 if (mLowRamStartTime != 0) { 9421 mLowRamStartTime = now; 9422 } 9423 9424 StringBuilder sb = new StringBuilder(128); 9425 sb.append("Idle maintenance over "); 9426 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9427 sb.append(" low RAM for "); 9428 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9429 Slog.i(TAG, sb.toString()); 9430 9431 // If at least 1/3 of our time since the last idle period has been spent 9432 // with RAM low, then we want to kill processes. 9433 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9434 9435 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9436 ProcessRecord proc = mLruProcesses.get(i); 9437 if (proc.notCachedSinceIdle) { 9438 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9439 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9440 if (doKilling && proc.initialIdlePss != 0 9441 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9442 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9443 + " from " + proc.initialIdlePss + ")"); 9444 } 9445 } 9446 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9447 proc.notCachedSinceIdle = true; 9448 proc.initialIdlePss = 0; 9449 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9450 isSleeping(), now); 9451 } 9452 } 9453 9454 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9455 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9456 } 9457 } 9458 9459 private void retrieveSettings() { 9460 final ContentResolver resolver = mContext.getContentResolver(); 9461 String debugApp = Settings.Global.getString( 9462 resolver, Settings.Global.DEBUG_APP); 9463 boolean waitForDebugger = Settings.Global.getInt( 9464 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9465 boolean alwaysFinishActivities = Settings.Global.getInt( 9466 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9467 boolean forceRtl = Settings.Global.getInt( 9468 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9469 // Transfer any global setting for forcing RTL layout, into a System Property 9470 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9471 9472 Configuration configuration = new Configuration(); 9473 Settings.System.getConfiguration(resolver, configuration); 9474 if (forceRtl) { 9475 // This will take care of setting the correct layout direction flags 9476 configuration.setLayoutDirection(configuration.locale); 9477 } 9478 9479 synchronized (this) { 9480 mDebugApp = mOrigDebugApp = debugApp; 9481 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9482 mAlwaysFinishActivities = alwaysFinishActivities; 9483 // This happens before any activities are started, so we can 9484 // change mConfiguration in-place. 9485 updateConfigurationLocked(configuration, null, false, true); 9486 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9487 } 9488 } 9489 9490 public boolean testIsSystemReady() { 9491 // no need to synchronize(this) just to read & return the value 9492 return mSystemReady; 9493 } 9494 9495 private static File getCalledPreBootReceiversFile() { 9496 File dataDir = Environment.getDataDirectory(); 9497 File systemDir = new File(dataDir, "system"); 9498 File fname = new File(systemDir, "called_pre_boots.dat"); 9499 return fname; 9500 } 9501 9502 static final int LAST_DONE_VERSION = 10000; 9503 9504 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9505 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9506 File file = getCalledPreBootReceiversFile(); 9507 FileInputStream fis = null; 9508 try { 9509 fis = new FileInputStream(file); 9510 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9511 int fvers = dis.readInt(); 9512 if (fvers == LAST_DONE_VERSION) { 9513 String vers = dis.readUTF(); 9514 String codename = dis.readUTF(); 9515 String build = dis.readUTF(); 9516 if (android.os.Build.VERSION.RELEASE.equals(vers) 9517 && android.os.Build.VERSION.CODENAME.equals(codename) 9518 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9519 int num = dis.readInt(); 9520 while (num > 0) { 9521 num--; 9522 String pkg = dis.readUTF(); 9523 String cls = dis.readUTF(); 9524 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9525 } 9526 } 9527 } 9528 } catch (FileNotFoundException e) { 9529 } catch (IOException e) { 9530 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9531 } finally { 9532 if (fis != null) { 9533 try { 9534 fis.close(); 9535 } catch (IOException e) { 9536 } 9537 } 9538 } 9539 return lastDoneReceivers; 9540 } 9541 9542 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9543 File file = getCalledPreBootReceiversFile(); 9544 FileOutputStream fos = null; 9545 DataOutputStream dos = null; 9546 try { 9547 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9548 fos = new FileOutputStream(file); 9549 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9550 dos.writeInt(LAST_DONE_VERSION); 9551 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9552 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9553 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9554 dos.writeInt(list.size()); 9555 for (int i=0; i<list.size(); i++) { 9556 dos.writeUTF(list.get(i).getPackageName()); 9557 dos.writeUTF(list.get(i).getClassName()); 9558 } 9559 } catch (IOException e) { 9560 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9561 file.delete(); 9562 } finally { 9563 FileUtils.sync(fos); 9564 if (dos != null) { 9565 try { 9566 dos.close(); 9567 } catch (IOException e) { 9568 // TODO Auto-generated catch block 9569 e.printStackTrace(); 9570 } 9571 } 9572 } 9573 } 9574 9575 public void systemReady(final Runnable goingCallback) { 9576 synchronized(this) { 9577 if (mSystemReady) { 9578 if (goingCallback != null) goingCallback.run(); 9579 return; 9580 } 9581 9582 // Check to see if there are any update receivers to run. 9583 if (!mDidUpdate) { 9584 if (mWaitingUpdate) { 9585 return; 9586 } 9587 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9588 List<ResolveInfo> ris = null; 9589 try { 9590 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9591 intent, null, 0, 0); 9592 } catch (RemoteException e) { 9593 } 9594 if (ris != null) { 9595 for (int i=ris.size()-1; i>=0; i--) { 9596 if ((ris.get(i).activityInfo.applicationInfo.flags 9597 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9598 ris.remove(i); 9599 } 9600 } 9601 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9602 9603 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9604 9605 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9606 for (int i=0; i<ris.size(); i++) { 9607 ActivityInfo ai = ris.get(i).activityInfo; 9608 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9609 if (lastDoneReceivers.contains(comp)) { 9610 // We already did the pre boot receiver for this app with the current 9611 // platform version, so don't do it again... 9612 ris.remove(i); 9613 i--; 9614 // ...however, do keep it as one that has been done, so we don't 9615 // forget about it when rewriting the file of last done receivers. 9616 doneReceivers.add(comp); 9617 } 9618 } 9619 9620 final int[] users = getUsersLocked(); 9621 for (int i=0; i<ris.size(); i++) { 9622 ActivityInfo ai = ris.get(i).activityInfo; 9623 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9624 doneReceivers.add(comp); 9625 intent.setComponent(comp); 9626 for (int j=0; j<users.length; j++) { 9627 IIntentReceiver finisher = null; 9628 if (i == ris.size()-1 && j == users.length-1) { 9629 finisher = new IIntentReceiver.Stub() { 9630 public void performReceive(Intent intent, int resultCode, 9631 String data, Bundle extras, boolean ordered, 9632 boolean sticky, int sendingUser) { 9633 // The raw IIntentReceiver interface is called 9634 // with the AM lock held, so redispatch to 9635 // execute our code without the lock. 9636 mHandler.post(new Runnable() { 9637 public void run() { 9638 synchronized (ActivityManagerService.this) { 9639 mDidUpdate = true; 9640 } 9641 writeLastDonePreBootReceivers(doneReceivers); 9642 showBootMessage(mContext.getText( 9643 R.string.android_upgrading_complete), 9644 false); 9645 systemReady(goingCallback); 9646 } 9647 }); 9648 } 9649 }; 9650 } 9651 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9652 + " for user " + users[j]); 9653 broadcastIntentLocked(null, null, intent, null, finisher, 9654 0, null, null, null, AppOpsManager.OP_NONE, 9655 true, false, MY_PID, Process.SYSTEM_UID, 9656 users[j]); 9657 if (finisher != null) { 9658 mWaitingUpdate = true; 9659 } 9660 } 9661 } 9662 } 9663 if (mWaitingUpdate) { 9664 return; 9665 } 9666 mDidUpdate = true; 9667 } 9668 9669 mAppOpsService.systemReady(); 9670 mSystemReady = true; 9671 } 9672 9673 ArrayList<ProcessRecord> procsToKill = null; 9674 synchronized(mPidsSelfLocked) { 9675 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9676 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9677 if (!isAllowedWhileBooting(proc.info)){ 9678 if (procsToKill == null) { 9679 procsToKill = new ArrayList<ProcessRecord>(); 9680 } 9681 procsToKill.add(proc); 9682 } 9683 } 9684 } 9685 9686 synchronized(this) { 9687 if (procsToKill != null) { 9688 for (int i=procsToKill.size()-1; i>=0; i--) { 9689 ProcessRecord proc = procsToKill.get(i); 9690 Slog.i(TAG, "Removing system update proc: " + proc); 9691 removeProcessLocked(proc, true, false, "system update done"); 9692 } 9693 } 9694 9695 // Now that we have cleaned up any update processes, we 9696 // are ready to start launching real processes and know that 9697 // we won't trample on them any more. 9698 mProcessesReady = true; 9699 } 9700 9701 Slog.i(TAG, "System now ready"); 9702 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9703 SystemClock.uptimeMillis()); 9704 9705 synchronized(this) { 9706 // Make sure we have no pre-ready processes sitting around. 9707 9708 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9709 ResolveInfo ri = mContext.getPackageManager() 9710 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9711 STOCK_PM_FLAGS); 9712 CharSequence errorMsg = null; 9713 if (ri != null) { 9714 ActivityInfo ai = ri.activityInfo; 9715 ApplicationInfo app = ai.applicationInfo; 9716 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9717 mTopAction = Intent.ACTION_FACTORY_TEST; 9718 mTopData = null; 9719 mTopComponent = new ComponentName(app.packageName, 9720 ai.name); 9721 } else { 9722 errorMsg = mContext.getResources().getText( 9723 com.android.internal.R.string.factorytest_not_system); 9724 } 9725 } else { 9726 errorMsg = mContext.getResources().getText( 9727 com.android.internal.R.string.factorytest_no_action); 9728 } 9729 if (errorMsg != null) { 9730 mTopAction = null; 9731 mTopData = null; 9732 mTopComponent = null; 9733 Message msg = Message.obtain(); 9734 msg.what = SHOW_FACTORY_ERROR_MSG; 9735 msg.getData().putCharSequence("msg", errorMsg); 9736 mHandler.sendMessage(msg); 9737 } 9738 } 9739 } 9740 9741 retrieveSettings(); 9742 9743 synchronized (this) { 9744 readGrantedUriPermissionsLocked(); 9745 } 9746 9747 if (goingCallback != null) goingCallback.run(); 9748 9749 mSystemServiceManager.startUser(mCurrentUserId); 9750 9751 synchronized (this) { 9752 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9753 try { 9754 List apps = AppGlobals.getPackageManager(). 9755 getPersistentApplications(STOCK_PM_FLAGS); 9756 if (apps != null) { 9757 int N = apps.size(); 9758 int i; 9759 for (i=0; i<N; i++) { 9760 ApplicationInfo info 9761 = (ApplicationInfo)apps.get(i); 9762 if (info != null && 9763 !info.packageName.equals("android")) { 9764 addAppLocked(info, false); 9765 } 9766 } 9767 } 9768 } catch (RemoteException ex) { 9769 // pm is in same process, this will never happen. 9770 } 9771 } 9772 9773 // Start up initial activity. 9774 mBooting = true; 9775 9776 try { 9777 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9778 Message msg = Message.obtain(); 9779 msg.what = SHOW_UID_ERROR_MSG; 9780 mHandler.sendMessage(msg); 9781 } 9782 } catch (RemoteException e) { 9783 } 9784 9785 long ident = Binder.clearCallingIdentity(); 9786 try { 9787 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9788 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9789 | Intent.FLAG_RECEIVER_FOREGROUND); 9790 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9791 broadcastIntentLocked(null, null, intent, 9792 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9793 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9794 intent = new Intent(Intent.ACTION_USER_STARTING); 9795 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9796 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9797 broadcastIntentLocked(null, null, intent, 9798 null, new IIntentReceiver.Stub() { 9799 @Override 9800 public void performReceive(Intent intent, int resultCode, String data, 9801 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9802 throws RemoteException { 9803 } 9804 }, 0, null, null, 9805 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9806 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9807 } catch (Throwable t) { 9808 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 9809 } finally { 9810 Binder.restoreCallingIdentity(ident); 9811 } 9812 mStackSupervisor.resumeTopActivitiesLocked(); 9813 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9814 } 9815 } 9816 9817 private boolean makeAppCrashingLocked(ProcessRecord app, 9818 String shortMsg, String longMsg, String stackTrace) { 9819 app.crashing = true; 9820 app.crashingReport = generateProcessError(app, 9821 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9822 startAppProblemLocked(app); 9823 app.stopFreezingAllLocked(); 9824 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9825 } 9826 9827 private void makeAppNotRespondingLocked(ProcessRecord app, 9828 String activity, String shortMsg, String longMsg) { 9829 app.notResponding = true; 9830 app.notRespondingReport = generateProcessError(app, 9831 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9832 activity, shortMsg, longMsg, null); 9833 startAppProblemLocked(app); 9834 app.stopFreezingAllLocked(); 9835 } 9836 9837 /** 9838 * Generate a process error record, suitable for attachment to a ProcessRecord. 9839 * 9840 * @param app The ProcessRecord in which the error occurred. 9841 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9842 * ActivityManager.AppErrorStateInfo 9843 * @param activity The activity associated with the crash, if known. 9844 * @param shortMsg Short message describing the crash. 9845 * @param longMsg Long message describing the crash. 9846 * @param stackTrace Full crash stack trace, may be null. 9847 * 9848 * @return Returns a fully-formed AppErrorStateInfo record. 9849 */ 9850 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9851 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9852 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9853 9854 report.condition = condition; 9855 report.processName = app.processName; 9856 report.pid = app.pid; 9857 report.uid = app.info.uid; 9858 report.tag = activity; 9859 report.shortMsg = shortMsg; 9860 report.longMsg = longMsg; 9861 report.stackTrace = stackTrace; 9862 9863 return report; 9864 } 9865 9866 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9867 synchronized (this) { 9868 app.crashing = false; 9869 app.crashingReport = null; 9870 app.notResponding = false; 9871 app.notRespondingReport = null; 9872 if (app.anrDialog == fromDialog) { 9873 app.anrDialog = null; 9874 } 9875 if (app.waitDialog == fromDialog) { 9876 app.waitDialog = null; 9877 } 9878 if (app.pid > 0 && app.pid != MY_PID) { 9879 handleAppCrashLocked(app, null, null, null); 9880 killUnneededProcessLocked(app, "user request after error"); 9881 } 9882 } 9883 } 9884 9885 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9886 String stackTrace) { 9887 long now = SystemClock.uptimeMillis(); 9888 9889 Long crashTime; 9890 if (!app.isolated) { 9891 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9892 } else { 9893 crashTime = null; 9894 } 9895 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9896 // This process loses! 9897 Slog.w(TAG, "Process " + app.info.processName 9898 + " has crashed too many times: killing!"); 9899 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9900 app.userId, app.info.processName, app.uid); 9901 mStackSupervisor.handleAppCrashLocked(app); 9902 if (!app.persistent) { 9903 // We don't want to start this process again until the user 9904 // explicitly does so... but for persistent process, we really 9905 // need to keep it running. If a persistent process is actually 9906 // repeatedly crashing, then badness for everyone. 9907 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9908 app.info.processName); 9909 if (!app.isolated) { 9910 // XXX We don't have a way to mark isolated processes 9911 // as bad, since they don't have a peristent identity. 9912 mBadProcesses.put(app.info.processName, app.uid, 9913 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9914 mProcessCrashTimes.remove(app.info.processName, app.uid); 9915 } 9916 app.bad = true; 9917 app.removed = true; 9918 // Don't let services in this process be restarted and potentially 9919 // annoy the user repeatedly. Unless it is persistent, since those 9920 // processes run critical code. 9921 removeProcessLocked(app, false, false, "crash"); 9922 mStackSupervisor.resumeTopActivitiesLocked(); 9923 return false; 9924 } 9925 mStackSupervisor.resumeTopActivitiesLocked(); 9926 } else { 9927 mStackSupervisor.finishTopRunningActivityLocked(app); 9928 } 9929 9930 // Bump up the crash count of any services currently running in the proc. 9931 for (int i=app.services.size()-1; i>=0; i--) { 9932 // Any services running in the application need to be placed 9933 // back in the pending list. 9934 ServiceRecord sr = app.services.valueAt(i); 9935 sr.crashCount++; 9936 } 9937 9938 // If the crashing process is what we consider to be the "home process" and it has been 9939 // replaced by a third-party app, clear the package preferred activities from packages 9940 // with a home activity running in the process to prevent a repeatedly crashing app 9941 // from blocking the user to manually clear the list. 9942 final ArrayList<ActivityRecord> activities = app.activities; 9943 if (app == mHomeProcess && activities.size() > 0 9944 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9945 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9946 final ActivityRecord r = activities.get(activityNdx); 9947 if (r.isHomeActivity()) { 9948 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9949 try { 9950 ActivityThread.getPackageManager() 9951 .clearPackagePreferredActivities(r.packageName); 9952 } catch (RemoteException c) { 9953 // pm is in same process, this will never happen. 9954 } 9955 } 9956 } 9957 } 9958 9959 if (!app.isolated) { 9960 // XXX Can't keep track of crash times for isolated processes, 9961 // because they don't have a perisistent identity. 9962 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9963 } 9964 9965 return true; 9966 } 9967 9968 void startAppProblemLocked(ProcessRecord app) { 9969 if (app.userId == mCurrentUserId) { 9970 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9971 mContext, app.info.packageName, app.info.flags); 9972 } else { 9973 // If this app is not running under the current user, then we 9974 // can't give it a report button because that would require 9975 // launching the report UI under a different user. 9976 app.errorReportReceiver = null; 9977 } 9978 skipCurrentReceiverLocked(app); 9979 } 9980 9981 void skipCurrentReceiverLocked(ProcessRecord app) { 9982 for (BroadcastQueue queue : mBroadcastQueues) { 9983 queue.skipCurrentReceiverLocked(app); 9984 } 9985 } 9986 9987 /** 9988 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9989 * The application process will exit immediately after this call returns. 9990 * @param app object of the crashing app, null for the system server 9991 * @param crashInfo describing the exception 9992 */ 9993 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9994 ProcessRecord r = findAppProcess(app, "Crash"); 9995 final String processName = app == null ? "system_server" 9996 : (r == null ? "unknown" : r.processName); 9997 9998 handleApplicationCrashInner("crash", r, processName, crashInfo); 9999 } 10000 10001 /* Native crash reporting uses this inner version because it needs to be somewhat 10002 * decoupled from the AM-managed cleanup lifecycle 10003 */ 10004 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 10005 ApplicationErrorReport.CrashInfo crashInfo) { 10006 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10007 UserHandle.getUserId(Binder.getCallingUid()), processName, 10008 r == null ? -1 : r.info.flags, 10009 crashInfo.exceptionClassName, 10010 crashInfo.exceptionMessage, 10011 crashInfo.throwFileName, 10012 crashInfo.throwLineNumber); 10013 10014 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10015 10016 crashApplication(r, crashInfo); 10017 } 10018 10019 public void handleApplicationStrictModeViolation( 10020 IBinder app, 10021 int violationMask, 10022 StrictMode.ViolationInfo info) { 10023 ProcessRecord r = findAppProcess(app, "StrictMode"); 10024 if (r == null) { 10025 return; 10026 } 10027 10028 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10029 Integer stackFingerprint = info.hashCode(); 10030 boolean logIt = true; 10031 synchronized (mAlreadyLoggedViolatedStacks) { 10032 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10033 logIt = false; 10034 // TODO: sub-sample into EventLog for these, with 10035 // the info.durationMillis? Then we'd get 10036 // the relative pain numbers, without logging all 10037 // the stack traces repeatedly. We'd want to do 10038 // likewise in the client code, which also does 10039 // dup suppression, before the Binder call. 10040 } else { 10041 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10042 mAlreadyLoggedViolatedStacks.clear(); 10043 } 10044 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10045 } 10046 } 10047 if (logIt) { 10048 logStrictModeViolationToDropBox(r, info); 10049 } 10050 } 10051 10052 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10053 AppErrorResult result = new AppErrorResult(); 10054 synchronized (this) { 10055 final long origId = Binder.clearCallingIdentity(); 10056 10057 Message msg = Message.obtain(); 10058 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10059 HashMap<String, Object> data = new HashMap<String, Object>(); 10060 data.put("result", result); 10061 data.put("app", r); 10062 data.put("violationMask", violationMask); 10063 data.put("info", info); 10064 msg.obj = data; 10065 mHandler.sendMessage(msg); 10066 10067 Binder.restoreCallingIdentity(origId); 10068 } 10069 int res = result.get(); 10070 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10071 } 10072 } 10073 10074 // Depending on the policy in effect, there could be a bunch of 10075 // these in quick succession so we try to batch these together to 10076 // minimize disk writes, number of dropbox entries, and maximize 10077 // compression, by having more fewer, larger records. 10078 private void logStrictModeViolationToDropBox( 10079 ProcessRecord process, 10080 StrictMode.ViolationInfo info) { 10081 if (info == null) { 10082 return; 10083 } 10084 final boolean isSystemApp = process == null || 10085 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10086 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10087 final String processName = process == null ? "unknown" : process.processName; 10088 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10089 final DropBoxManager dbox = (DropBoxManager) 10090 mContext.getSystemService(Context.DROPBOX_SERVICE); 10091 10092 // Exit early if the dropbox isn't configured to accept this report type. 10093 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10094 10095 boolean bufferWasEmpty; 10096 boolean needsFlush; 10097 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10098 synchronized (sb) { 10099 bufferWasEmpty = sb.length() == 0; 10100 appendDropBoxProcessHeaders(process, processName, sb); 10101 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10102 sb.append("System-App: ").append(isSystemApp).append("\n"); 10103 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10104 if (info.violationNumThisLoop != 0) { 10105 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10106 } 10107 if (info.numAnimationsRunning != 0) { 10108 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10109 } 10110 if (info.broadcastIntentAction != null) { 10111 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10112 } 10113 if (info.durationMillis != -1) { 10114 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10115 } 10116 if (info.numInstances != -1) { 10117 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10118 } 10119 if (info.tags != null) { 10120 for (String tag : info.tags) { 10121 sb.append("Span-Tag: ").append(tag).append("\n"); 10122 } 10123 } 10124 sb.append("\n"); 10125 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10126 sb.append(info.crashInfo.stackTrace); 10127 } 10128 sb.append("\n"); 10129 10130 // Only buffer up to ~64k. Various logging bits truncate 10131 // things at 128k. 10132 needsFlush = (sb.length() > 64 * 1024); 10133 } 10134 10135 // Flush immediately if the buffer's grown too large, or this 10136 // is a non-system app. Non-system apps are isolated with a 10137 // different tag & policy and not batched. 10138 // 10139 // Batching is useful during internal testing with 10140 // StrictMode settings turned up high. Without batching, 10141 // thousands of separate files could be created on boot. 10142 if (!isSystemApp || needsFlush) { 10143 new Thread("Error dump: " + dropboxTag) { 10144 @Override 10145 public void run() { 10146 String report; 10147 synchronized (sb) { 10148 report = sb.toString(); 10149 sb.delete(0, sb.length()); 10150 sb.trimToSize(); 10151 } 10152 if (report.length() != 0) { 10153 dbox.addText(dropboxTag, report); 10154 } 10155 } 10156 }.start(); 10157 return; 10158 } 10159 10160 // System app batching: 10161 if (!bufferWasEmpty) { 10162 // An existing dropbox-writing thread is outstanding, so 10163 // we don't need to start it up. The existing thread will 10164 // catch the buffer appends we just did. 10165 return; 10166 } 10167 10168 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10169 // (After this point, we shouldn't access AMS internal data structures.) 10170 new Thread("Error dump: " + dropboxTag) { 10171 @Override 10172 public void run() { 10173 // 5 second sleep to let stacks arrive and be batched together 10174 try { 10175 Thread.sleep(5000); // 5 seconds 10176 } catch (InterruptedException e) {} 10177 10178 String errorReport; 10179 synchronized (mStrictModeBuffer) { 10180 errorReport = mStrictModeBuffer.toString(); 10181 if (errorReport.length() == 0) { 10182 return; 10183 } 10184 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10185 mStrictModeBuffer.trimToSize(); 10186 } 10187 dbox.addText(dropboxTag, errorReport); 10188 } 10189 }.start(); 10190 } 10191 10192 /** 10193 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10194 * @param app object of the crashing app, null for the system server 10195 * @param tag reported by the caller 10196 * @param crashInfo describing the context of the error 10197 * @return true if the process should exit immediately (WTF is fatal) 10198 */ 10199 public boolean handleApplicationWtf(IBinder app, String tag, 10200 ApplicationErrorReport.CrashInfo crashInfo) { 10201 ProcessRecord r = findAppProcess(app, "WTF"); 10202 final String processName = app == null ? "system_server" 10203 : (r == null ? "unknown" : r.processName); 10204 10205 EventLog.writeEvent(EventLogTags.AM_WTF, 10206 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10207 processName, 10208 r == null ? -1 : r.info.flags, 10209 tag, crashInfo.exceptionMessage); 10210 10211 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10212 10213 if (r != null && r.pid != Process.myPid() && 10214 Settings.Global.getInt(mContext.getContentResolver(), 10215 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10216 crashApplication(r, crashInfo); 10217 return true; 10218 } else { 10219 return false; 10220 } 10221 } 10222 10223 /** 10224 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10225 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10226 */ 10227 private ProcessRecord findAppProcess(IBinder app, String reason) { 10228 if (app == null) { 10229 return null; 10230 } 10231 10232 synchronized (this) { 10233 final int NP = mProcessNames.getMap().size(); 10234 for (int ip=0; ip<NP; ip++) { 10235 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10236 final int NA = apps.size(); 10237 for (int ia=0; ia<NA; ia++) { 10238 ProcessRecord p = apps.valueAt(ia); 10239 if (p.thread != null && p.thread.asBinder() == app) { 10240 return p; 10241 } 10242 } 10243 } 10244 10245 Slog.w(TAG, "Can't find mystery application for " + reason 10246 + " from pid=" + Binder.getCallingPid() 10247 + " uid=" + Binder.getCallingUid() + ": " + app); 10248 return null; 10249 } 10250 } 10251 10252 /** 10253 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10254 * to append various headers to the dropbox log text. 10255 */ 10256 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10257 StringBuilder sb) { 10258 // Watchdog thread ends up invoking this function (with 10259 // a null ProcessRecord) to add the stack file to dropbox. 10260 // Do not acquire a lock on this (am) in such cases, as it 10261 // could cause a potential deadlock, if and when watchdog 10262 // is invoked due to unavailability of lock on am and it 10263 // would prevent watchdog from killing system_server. 10264 if (process == null) { 10265 sb.append("Process: ").append(processName).append("\n"); 10266 return; 10267 } 10268 // Note: ProcessRecord 'process' is guarded by the service 10269 // instance. (notably process.pkgList, which could otherwise change 10270 // concurrently during execution of this method) 10271 synchronized (this) { 10272 sb.append("Process: ").append(processName).append("\n"); 10273 int flags = process.info.flags; 10274 IPackageManager pm = AppGlobals.getPackageManager(); 10275 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10276 for (int ip=0; ip<process.pkgList.size(); ip++) { 10277 String pkg = process.pkgList.keyAt(ip); 10278 sb.append("Package: ").append(pkg); 10279 try { 10280 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10281 if (pi != null) { 10282 sb.append(" v").append(pi.versionCode); 10283 if (pi.versionName != null) { 10284 sb.append(" (").append(pi.versionName).append(")"); 10285 } 10286 } 10287 } catch (RemoteException e) { 10288 Slog.e(TAG, "Error getting package info: " + pkg, e); 10289 } 10290 sb.append("\n"); 10291 } 10292 } 10293 } 10294 10295 private static String processClass(ProcessRecord process) { 10296 if (process == null || process.pid == MY_PID) { 10297 return "system_server"; 10298 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10299 return "system_app"; 10300 } else { 10301 return "data_app"; 10302 } 10303 } 10304 10305 /** 10306 * Write a description of an error (crash, WTF, ANR) to the drop box. 10307 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10308 * @param process which caused the error, null means the system server 10309 * @param activity which triggered the error, null if unknown 10310 * @param parent activity related to the error, null if unknown 10311 * @param subject line related to the error, null if absent 10312 * @param report in long form describing the error, null if absent 10313 * @param logFile to include in the report, null if none 10314 * @param crashInfo giving an application stack trace, null if absent 10315 */ 10316 public void addErrorToDropBox(String eventType, 10317 ProcessRecord process, String processName, ActivityRecord activity, 10318 ActivityRecord parent, String subject, 10319 final String report, final File logFile, 10320 final ApplicationErrorReport.CrashInfo crashInfo) { 10321 // NOTE -- this must never acquire the ActivityManagerService lock, 10322 // otherwise the watchdog may be prevented from resetting the system. 10323 10324 final String dropboxTag = processClass(process) + "_" + eventType; 10325 final DropBoxManager dbox = (DropBoxManager) 10326 mContext.getSystemService(Context.DROPBOX_SERVICE); 10327 10328 // Exit early if the dropbox isn't configured to accept this report type. 10329 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10330 10331 final StringBuilder sb = new StringBuilder(1024); 10332 appendDropBoxProcessHeaders(process, processName, sb); 10333 if (activity != null) { 10334 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10335 } 10336 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10337 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10338 } 10339 if (parent != null && parent != activity) { 10340 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10341 } 10342 if (subject != null) { 10343 sb.append("Subject: ").append(subject).append("\n"); 10344 } 10345 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10346 if (Debug.isDebuggerConnected()) { 10347 sb.append("Debugger: Connected\n"); 10348 } 10349 sb.append("\n"); 10350 10351 // Do the rest in a worker thread to avoid blocking the caller on I/O 10352 // (After this point, we shouldn't access AMS internal data structures.) 10353 Thread worker = new Thread("Error dump: " + dropboxTag) { 10354 @Override 10355 public void run() { 10356 if (report != null) { 10357 sb.append(report); 10358 } 10359 if (logFile != null) { 10360 try { 10361 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10362 "\n\n[[TRUNCATED]]")); 10363 } catch (IOException e) { 10364 Slog.e(TAG, "Error reading " + logFile, e); 10365 } 10366 } 10367 if (crashInfo != null && crashInfo.stackTrace != null) { 10368 sb.append(crashInfo.stackTrace); 10369 } 10370 10371 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10372 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10373 if (lines > 0) { 10374 sb.append("\n"); 10375 10376 // Merge several logcat streams, and take the last N lines 10377 InputStreamReader input = null; 10378 try { 10379 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10380 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10381 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10382 10383 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10384 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10385 input = new InputStreamReader(logcat.getInputStream()); 10386 10387 int num; 10388 char[] buf = new char[8192]; 10389 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10390 } catch (IOException e) { 10391 Slog.e(TAG, "Error running logcat", e); 10392 } finally { 10393 if (input != null) try { input.close(); } catch (IOException e) {} 10394 } 10395 } 10396 10397 dbox.addText(dropboxTag, sb.toString()); 10398 } 10399 }; 10400 10401 if (process == null) { 10402 // If process is null, we are being called from some internal code 10403 // and may be about to die -- run this synchronously. 10404 worker.run(); 10405 } else { 10406 worker.start(); 10407 } 10408 } 10409 10410 /** 10411 * Bring up the "unexpected error" dialog box for a crashing app. 10412 * Deal with edge cases (intercepts from instrumented applications, 10413 * ActivityController, error intent receivers, that sort of thing). 10414 * @param r the application crashing 10415 * @param crashInfo describing the failure 10416 */ 10417 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10418 long timeMillis = System.currentTimeMillis(); 10419 String shortMsg = crashInfo.exceptionClassName; 10420 String longMsg = crashInfo.exceptionMessage; 10421 String stackTrace = crashInfo.stackTrace; 10422 if (shortMsg != null && longMsg != null) { 10423 longMsg = shortMsg + ": " + longMsg; 10424 } else if (shortMsg != null) { 10425 longMsg = shortMsg; 10426 } 10427 10428 AppErrorResult result = new AppErrorResult(); 10429 synchronized (this) { 10430 if (mController != null) { 10431 try { 10432 String name = r != null ? r.processName : null; 10433 int pid = r != null ? r.pid : Binder.getCallingPid(); 10434 if (!mController.appCrashed(name, pid, 10435 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10436 Slog.w(TAG, "Force-killing crashed app " + name 10437 + " at watcher's request"); 10438 Process.killProcess(pid); 10439 return; 10440 } 10441 } catch (RemoteException e) { 10442 mController = null; 10443 Watchdog.getInstance().setActivityController(null); 10444 } 10445 } 10446 10447 final long origId = Binder.clearCallingIdentity(); 10448 10449 // If this process is running instrumentation, finish it. 10450 if (r != null && r.instrumentationClass != null) { 10451 Slog.w(TAG, "Error in app " + r.processName 10452 + " running instrumentation " + r.instrumentationClass + ":"); 10453 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10454 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10455 Bundle info = new Bundle(); 10456 info.putString("shortMsg", shortMsg); 10457 info.putString("longMsg", longMsg); 10458 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10459 Binder.restoreCallingIdentity(origId); 10460 return; 10461 } 10462 10463 // If we can't identify the process or it's already exceeded its crash quota, 10464 // quit right away without showing a crash dialog. 10465 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10466 Binder.restoreCallingIdentity(origId); 10467 return; 10468 } 10469 10470 Message msg = Message.obtain(); 10471 msg.what = SHOW_ERROR_MSG; 10472 HashMap data = new HashMap(); 10473 data.put("result", result); 10474 data.put("app", r); 10475 msg.obj = data; 10476 mHandler.sendMessage(msg); 10477 10478 Binder.restoreCallingIdentity(origId); 10479 } 10480 10481 int res = result.get(); 10482 10483 Intent appErrorIntent = null; 10484 synchronized (this) { 10485 if (r != null && !r.isolated) { 10486 // XXX Can't keep track of crash time for isolated processes, 10487 // since they don't have a persistent identity. 10488 mProcessCrashTimes.put(r.info.processName, r.uid, 10489 SystemClock.uptimeMillis()); 10490 } 10491 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10492 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10493 } 10494 } 10495 10496 if (appErrorIntent != null) { 10497 try { 10498 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10499 } catch (ActivityNotFoundException e) { 10500 Slog.w(TAG, "bug report receiver dissappeared", e); 10501 } 10502 } 10503 } 10504 10505 Intent createAppErrorIntentLocked(ProcessRecord r, 10506 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10507 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10508 if (report == null) { 10509 return null; 10510 } 10511 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10512 result.setComponent(r.errorReportReceiver); 10513 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10514 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10515 return result; 10516 } 10517 10518 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10519 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10520 if (r.errorReportReceiver == null) { 10521 return null; 10522 } 10523 10524 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10525 return null; 10526 } 10527 10528 ApplicationErrorReport report = new ApplicationErrorReport(); 10529 report.packageName = r.info.packageName; 10530 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10531 report.processName = r.processName; 10532 report.time = timeMillis; 10533 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10534 10535 if (r.crashing || r.forceCrashReport) { 10536 report.type = ApplicationErrorReport.TYPE_CRASH; 10537 report.crashInfo = crashInfo; 10538 } else if (r.notResponding) { 10539 report.type = ApplicationErrorReport.TYPE_ANR; 10540 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10541 10542 report.anrInfo.activity = r.notRespondingReport.tag; 10543 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10544 report.anrInfo.info = r.notRespondingReport.longMsg; 10545 } 10546 10547 return report; 10548 } 10549 10550 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10551 enforceNotIsolatedCaller("getProcessesInErrorState"); 10552 // assume our apps are happy - lazy create the list 10553 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10554 10555 final boolean allUsers = ActivityManager.checkUidPermission( 10556 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10557 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10558 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10559 10560 synchronized (this) { 10561 10562 // iterate across all processes 10563 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10564 ProcessRecord app = mLruProcesses.get(i); 10565 if (!allUsers && app.userId != userId) { 10566 continue; 10567 } 10568 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10569 // This one's in trouble, so we'll generate a report for it 10570 // crashes are higher priority (in case there's a crash *and* an anr) 10571 ActivityManager.ProcessErrorStateInfo report = null; 10572 if (app.crashing) { 10573 report = app.crashingReport; 10574 } else if (app.notResponding) { 10575 report = app.notRespondingReport; 10576 } 10577 10578 if (report != null) { 10579 if (errList == null) { 10580 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10581 } 10582 errList.add(report); 10583 } else { 10584 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10585 " crashing = " + app.crashing + 10586 " notResponding = " + app.notResponding); 10587 } 10588 } 10589 } 10590 } 10591 10592 return errList; 10593 } 10594 10595 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10596 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10597 if (currApp != null) { 10598 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10599 } 10600 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10601 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10602 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10603 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10604 if (currApp != null) { 10605 currApp.lru = 0; 10606 } 10607 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10608 } else if (adj >= ProcessList.SERVICE_ADJ) { 10609 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10610 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10611 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10612 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10613 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10614 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10615 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10616 } else { 10617 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10618 } 10619 } 10620 10621 private void fillInProcMemInfo(ProcessRecord app, 10622 ActivityManager.RunningAppProcessInfo outInfo) { 10623 outInfo.pid = app.pid; 10624 outInfo.uid = app.info.uid; 10625 if (mHeavyWeightProcess == app) { 10626 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10627 } 10628 if (app.persistent) { 10629 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10630 } 10631 if (app.activities.size() > 0) { 10632 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10633 } 10634 outInfo.lastTrimLevel = app.trimMemoryLevel; 10635 int adj = app.curAdj; 10636 outInfo.importance = oomAdjToImportance(adj, outInfo); 10637 outInfo.importanceReasonCode = app.adjTypeCode; 10638 } 10639 10640 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10641 enforceNotIsolatedCaller("getRunningAppProcesses"); 10642 // Lazy instantiation of list 10643 List<ActivityManager.RunningAppProcessInfo> runList = null; 10644 final boolean allUsers = ActivityManager.checkUidPermission( 10645 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10646 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10647 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10648 synchronized (this) { 10649 // Iterate across all processes 10650 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10651 ProcessRecord app = mLruProcesses.get(i); 10652 if (!allUsers && app.userId != userId) { 10653 continue; 10654 } 10655 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10656 // Generate process state info for running application 10657 ActivityManager.RunningAppProcessInfo currApp = 10658 new ActivityManager.RunningAppProcessInfo(app.processName, 10659 app.pid, app.getPackageList()); 10660 fillInProcMemInfo(app, currApp); 10661 if (app.adjSource instanceof ProcessRecord) { 10662 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10663 currApp.importanceReasonImportance = oomAdjToImportance( 10664 app.adjSourceOom, null); 10665 } else if (app.adjSource instanceof ActivityRecord) { 10666 ActivityRecord r = (ActivityRecord)app.adjSource; 10667 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10668 } 10669 if (app.adjTarget instanceof ComponentName) { 10670 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10671 } 10672 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10673 // + " lru=" + currApp.lru); 10674 if (runList == null) { 10675 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10676 } 10677 runList.add(currApp); 10678 } 10679 } 10680 } 10681 return runList; 10682 } 10683 10684 public List<ApplicationInfo> getRunningExternalApplications() { 10685 enforceNotIsolatedCaller("getRunningExternalApplications"); 10686 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10687 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10688 if (runningApps != null && runningApps.size() > 0) { 10689 Set<String> extList = new HashSet<String>(); 10690 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10691 if (app.pkgList != null) { 10692 for (String pkg : app.pkgList) { 10693 extList.add(pkg); 10694 } 10695 } 10696 } 10697 IPackageManager pm = AppGlobals.getPackageManager(); 10698 for (String pkg : extList) { 10699 try { 10700 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10701 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10702 retList.add(info); 10703 } 10704 } catch (RemoteException e) { 10705 } 10706 } 10707 } 10708 return retList; 10709 } 10710 10711 @Override 10712 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10713 enforceNotIsolatedCaller("getMyMemoryState"); 10714 synchronized (this) { 10715 ProcessRecord proc; 10716 synchronized (mPidsSelfLocked) { 10717 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10718 } 10719 fillInProcMemInfo(proc, outInfo); 10720 } 10721 } 10722 10723 @Override 10724 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10725 if (checkCallingPermission(android.Manifest.permission.DUMP) 10726 != PackageManager.PERMISSION_GRANTED) { 10727 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10728 + Binder.getCallingPid() 10729 + ", uid=" + Binder.getCallingUid() 10730 + " without permission " 10731 + android.Manifest.permission.DUMP); 10732 return; 10733 } 10734 10735 boolean dumpAll = false; 10736 boolean dumpClient = false; 10737 String dumpPackage = null; 10738 10739 int opti = 0; 10740 while (opti < args.length) { 10741 String opt = args[opti]; 10742 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10743 break; 10744 } 10745 opti++; 10746 if ("-a".equals(opt)) { 10747 dumpAll = true; 10748 } else if ("-c".equals(opt)) { 10749 dumpClient = true; 10750 } else if ("-h".equals(opt)) { 10751 pw.println("Activity manager dump options:"); 10752 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10753 pw.println(" cmd may be one of:"); 10754 pw.println(" a[ctivities]: activity stack state"); 10755 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10756 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10757 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10758 pw.println(" o[om]: out of memory management"); 10759 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10760 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10761 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10762 pw.println(" service [COMP_SPEC]: service client-side state"); 10763 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10764 pw.println(" all: dump all activities"); 10765 pw.println(" top: dump the top activity"); 10766 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10767 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10768 pw.println(" a partial substring in a component name, a"); 10769 pw.println(" hex object identifier."); 10770 pw.println(" -a: include all available server state."); 10771 pw.println(" -c: include client state."); 10772 return; 10773 } else { 10774 pw.println("Unknown argument: " + opt + "; use -h for help"); 10775 } 10776 } 10777 10778 long origId = Binder.clearCallingIdentity(); 10779 boolean more = false; 10780 // Is the caller requesting to dump a particular piece of data? 10781 if (opti < args.length) { 10782 String cmd = args[opti]; 10783 opti++; 10784 if ("activities".equals(cmd) || "a".equals(cmd)) { 10785 synchronized (this) { 10786 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10787 } 10788 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10789 String[] newArgs; 10790 String name; 10791 if (opti >= args.length) { 10792 name = null; 10793 newArgs = EMPTY_STRING_ARRAY; 10794 } else { 10795 name = args[opti]; 10796 opti++; 10797 newArgs = new String[args.length - opti]; 10798 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10799 args.length - opti); 10800 } 10801 synchronized (this) { 10802 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10803 } 10804 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10805 String[] newArgs; 10806 String name; 10807 if (opti >= args.length) { 10808 name = null; 10809 newArgs = EMPTY_STRING_ARRAY; 10810 } else { 10811 name = args[opti]; 10812 opti++; 10813 newArgs = new String[args.length - opti]; 10814 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10815 args.length - opti); 10816 } 10817 synchronized (this) { 10818 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10819 } 10820 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10821 String[] newArgs; 10822 String name; 10823 if (opti >= args.length) { 10824 name = null; 10825 newArgs = EMPTY_STRING_ARRAY; 10826 } else { 10827 name = args[opti]; 10828 opti++; 10829 newArgs = new String[args.length - opti]; 10830 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10831 args.length - opti); 10832 } 10833 synchronized (this) { 10834 dumpProcessesLocked(fd, pw, args, opti, true, name); 10835 } 10836 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10837 synchronized (this) { 10838 dumpOomLocked(fd, pw, args, opti, true); 10839 } 10840 } else if ("provider".equals(cmd)) { 10841 String[] newArgs; 10842 String name; 10843 if (opti >= args.length) { 10844 name = null; 10845 newArgs = EMPTY_STRING_ARRAY; 10846 } else { 10847 name = args[opti]; 10848 opti++; 10849 newArgs = new String[args.length - opti]; 10850 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10851 } 10852 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10853 pw.println("No providers match: " + name); 10854 pw.println("Use -h for help."); 10855 } 10856 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10857 synchronized (this) { 10858 dumpProvidersLocked(fd, pw, args, opti, true, null); 10859 } 10860 } else if ("service".equals(cmd)) { 10861 String[] newArgs; 10862 String name; 10863 if (opti >= args.length) { 10864 name = null; 10865 newArgs = EMPTY_STRING_ARRAY; 10866 } else { 10867 name = args[opti]; 10868 opti++; 10869 newArgs = new String[args.length - opti]; 10870 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10871 args.length - opti); 10872 } 10873 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10874 pw.println("No services match: " + name); 10875 pw.println("Use -h for help."); 10876 } 10877 } else if ("package".equals(cmd)) { 10878 String[] newArgs; 10879 if (opti >= args.length) { 10880 pw.println("package: no package name specified"); 10881 pw.println("Use -h for help."); 10882 } else { 10883 dumpPackage = args[opti]; 10884 opti++; 10885 newArgs = new String[args.length - opti]; 10886 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10887 args.length - opti); 10888 args = newArgs; 10889 opti = 0; 10890 more = true; 10891 } 10892 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10893 synchronized (this) { 10894 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10895 } 10896 } else { 10897 // Dumping a single activity? 10898 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10899 pw.println("Bad activity command, or no activities match: " + cmd); 10900 pw.println("Use -h for help."); 10901 } 10902 } 10903 if (!more) { 10904 Binder.restoreCallingIdentity(origId); 10905 return; 10906 } 10907 } 10908 10909 // No piece of data specified, dump everything. 10910 synchronized (this) { 10911 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10912 pw.println(); 10913 if (dumpAll) { 10914 pw.println("-------------------------------------------------------------------------------"); 10915 } 10916 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10917 pw.println(); 10918 if (dumpAll) { 10919 pw.println("-------------------------------------------------------------------------------"); 10920 } 10921 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10922 pw.println(); 10923 if (dumpAll) { 10924 pw.println("-------------------------------------------------------------------------------"); 10925 } 10926 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10927 pw.println(); 10928 if (dumpAll) { 10929 pw.println("-------------------------------------------------------------------------------"); 10930 } 10931 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10932 pw.println(); 10933 if (dumpAll) { 10934 pw.println("-------------------------------------------------------------------------------"); 10935 } 10936 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10937 } 10938 Binder.restoreCallingIdentity(origId); 10939 } 10940 10941 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10942 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10943 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10944 10945 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10946 dumpPackage); 10947 boolean needSep = printedAnything; 10948 10949 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10950 dumpPackage, needSep, " mFocusedActivity: "); 10951 if (printed) { 10952 printedAnything = true; 10953 needSep = false; 10954 } 10955 10956 if (dumpPackage == null) { 10957 if (needSep) { 10958 pw.println(); 10959 } 10960 needSep = true; 10961 printedAnything = true; 10962 mStackSupervisor.dump(pw, " "); 10963 } 10964 10965 if (mRecentTasks.size() > 0) { 10966 boolean printedHeader = false; 10967 10968 final int N = mRecentTasks.size(); 10969 for (int i=0; i<N; i++) { 10970 TaskRecord tr = mRecentTasks.get(i); 10971 if (dumpPackage != null) { 10972 if (tr.realActivity == null || 10973 !dumpPackage.equals(tr.realActivity)) { 10974 continue; 10975 } 10976 } 10977 if (!printedHeader) { 10978 if (needSep) { 10979 pw.println(); 10980 } 10981 pw.println(" Recent tasks:"); 10982 printedHeader = true; 10983 printedAnything = true; 10984 } 10985 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10986 pw.println(tr); 10987 if (dumpAll) { 10988 mRecentTasks.get(i).dump(pw, " "); 10989 } 10990 } 10991 } 10992 10993 if (!printedAnything) { 10994 pw.println(" (nothing)"); 10995 } 10996 } 10997 10998 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10999 int opti, boolean dumpAll, String dumpPackage) { 11000 boolean needSep = false; 11001 boolean printedAnything = false; 11002 int numPers = 0; 11003 11004 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11005 11006 if (dumpAll) { 11007 final int NP = mProcessNames.getMap().size(); 11008 for (int ip=0; ip<NP; ip++) { 11009 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11010 final int NA = procs.size(); 11011 for (int ia=0; ia<NA; ia++) { 11012 ProcessRecord r = procs.valueAt(ia); 11013 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11014 continue; 11015 } 11016 if (!needSep) { 11017 pw.println(" All known processes:"); 11018 needSep = true; 11019 printedAnything = true; 11020 } 11021 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11022 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11023 pw.print(" "); pw.println(r); 11024 r.dump(pw, " "); 11025 if (r.persistent) { 11026 numPers++; 11027 } 11028 } 11029 } 11030 } 11031 11032 if (mIsolatedProcesses.size() > 0) { 11033 boolean printed = false; 11034 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11035 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11036 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11037 continue; 11038 } 11039 if (!printed) { 11040 if (needSep) { 11041 pw.println(); 11042 } 11043 pw.println(" Isolated process list (sorted by uid):"); 11044 printedAnything = true; 11045 printed = true; 11046 needSep = true; 11047 } 11048 pw.println(String.format("%sIsolated #%2d: %s", 11049 " ", i, r.toString())); 11050 } 11051 } 11052 11053 if (mLruProcesses.size() > 0) { 11054 if (needSep) { 11055 pw.println(); 11056 } 11057 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11058 pw.print(" total, non-act at "); 11059 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11060 pw.print(", non-svc at "); 11061 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11062 pw.println("):"); 11063 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11064 needSep = true; 11065 printedAnything = true; 11066 } 11067 11068 if (dumpAll || dumpPackage != null) { 11069 synchronized (mPidsSelfLocked) { 11070 boolean printed = false; 11071 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11072 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11073 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11074 continue; 11075 } 11076 if (!printed) { 11077 if (needSep) pw.println(); 11078 needSep = true; 11079 pw.println(" PID mappings:"); 11080 printed = true; 11081 printedAnything = true; 11082 } 11083 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11084 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11085 } 11086 } 11087 } 11088 11089 if (mForegroundProcesses.size() > 0) { 11090 synchronized (mPidsSelfLocked) { 11091 boolean printed = false; 11092 for (int i=0; i<mForegroundProcesses.size(); i++) { 11093 ProcessRecord r = mPidsSelfLocked.get( 11094 mForegroundProcesses.valueAt(i).pid); 11095 if (dumpPackage != null && (r == null 11096 || !r.pkgList.containsKey(dumpPackage))) { 11097 continue; 11098 } 11099 if (!printed) { 11100 if (needSep) pw.println(); 11101 needSep = true; 11102 pw.println(" Foreground Processes:"); 11103 printed = true; 11104 printedAnything = true; 11105 } 11106 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11107 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11108 } 11109 } 11110 } 11111 11112 if (mPersistentStartingProcesses.size() > 0) { 11113 if (needSep) pw.println(); 11114 needSep = true; 11115 printedAnything = true; 11116 pw.println(" Persisent processes that are starting:"); 11117 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11118 "Starting Norm", "Restarting PERS", dumpPackage); 11119 } 11120 11121 if (mRemovedProcesses.size() > 0) { 11122 if (needSep) pw.println(); 11123 needSep = true; 11124 printedAnything = true; 11125 pw.println(" Processes that are being removed:"); 11126 dumpProcessList(pw, this, mRemovedProcesses, " ", 11127 "Removed Norm", "Removed PERS", dumpPackage); 11128 } 11129 11130 if (mProcessesOnHold.size() > 0) { 11131 if (needSep) pw.println(); 11132 needSep = true; 11133 printedAnything = true; 11134 pw.println(" Processes that are on old until the system is ready:"); 11135 dumpProcessList(pw, this, mProcessesOnHold, " ", 11136 "OnHold Norm", "OnHold PERS", dumpPackage); 11137 } 11138 11139 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11140 11141 if (mProcessCrashTimes.getMap().size() > 0) { 11142 boolean printed = false; 11143 long now = SystemClock.uptimeMillis(); 11144 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11145 final int NP = pmap.size(); 11146 for (int ip=0; ip<NP; ip++) { 11147 String pname = pmap.keyAt(ip); 11148 SparseArray<Long> uids = pmap.valueAt(ip); 11149 final int N = uids.size(); 11150 for (int i=0; i<N; i++) { 11151 int puid = uids.keyAt(i); 11152 ProcessRecord r = mProcessNames.get(pname, puid); 11153 if (dumpPackage != null && (r == null 11154 || !r.pkgList.containsKey(dumpPackage))) { 11155 continue; 11156 } 11157 if (!printed) { 11158 if (needSep) pw.println(); 11159 needSep = true; 11160 pw.println(" Time since processes crashed:"); 11161 printed = true; 11162 printedAnything = true; 11163 } 11164 pw.print(" Process "); pw.print(pname); 11165 pw.print(" uid "); pw.print(puid); 11166 pw.print(": last crashed "); 11167 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11168 pw.println(" ago"); 11169 } 11170 } 11171 } 11172 11173 if (mBadProcesses.getMap().size() > 0) { 11174 boolean printed = false; 11175 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11176 final int NP = pmap.size(); 11177 for (int ip=0; ip<NP; ip++) { 11178 String pname = pmap.keyAt(ip); 11179 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11180 final int N = uids.size(); 11181 for (int i=0; i<N; i++) { 11182 int puid = uids.keyAt(i); 11183 ProcessRecord r = mProcessNames.get(pname, puid); 11184 if (dumpPackage != null && (r == null 11185 || !r.pkgList.containsKey(dumpPackage))) { 11186 continue; 11187 } 11188 if (!printed) { 11189 if (needSep) pw.println(); 11190 needSep = true; 11191 pw.println(" Bad processes:"); 11192 printedAnything = true; 11193 } 11194 BadProcessInfo info = uids.valueAt(i); 11195 pw.print(" Bad process "); pw.print(pname); 11196 pw.print(" uid "); pw.print(puid); 11197 pw.print(": crashed at time "); pw.println(info.time); 11198 if (info.shortMsg != null) { 11199 pw.print(" Short msg: "); pw.println(info.shortMsg); 11200 } 11201 if (info.longMsg != null) { 11202 pw.print(" Long msg: "); pw.println(info.longMsg); 11203 } 11204 if (info.stack != null) { 11205 pw.println(" Stack:"); 11206 int lastPos = 0; 11207 for (int pos=0; pos<info.stack.length(); pos++) { 11208 if (info.stack.charAt(pos) == '\n') { 11209 pw.print(" "); 11210 pw.write(info.stack, lastPos, pos-lastPos); 11211 pw.println(); 11212 lastPos = pos+1; 11213 } 11214 } 11215 if (lastPos < info.stack.length()) { 11216 pw.print(" "); 11217 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11218 pw.println(); 11219 } 11220 } 11221 } 11222 } 11223 } 11224 11225 if (dumpPackage == null) { 11226 pw.println(); 11227 needSep = false; 11228 pw.println(" mStartedUsers:"); 11229 for (int i=0; i<mStartedUsers.size(); i++) { 11230 UserStartedState uss = mStartedUsers.valueAt(i); 11231 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11232 pw.print(": "); uss.dump("", pw); 11233 } 11234 pw.print(" mStartedUserArray: ["); 11235 for (int i=0; i<mStartedUserArray.length; i++) { 11236 if (i > 0) pw.print(", "); 11237 pw.print(mStartedUserArray[i]); 11238 } 11239 pw.println("]"); 11240 pw.print(" mUserLru: ["); 11241 for (int i=0; i<mUserLru.size(); i++) { 11242 if (i > 0) pw.print(", "); 11243 pw.print(mUserLru.get(i)); 11244 } 11245 pw.println("]"); 11246 if (dumpAll) { 11247 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11248 } 11249 } 11250 if (mHomeProcess != null && (dumpPackage == null 11251 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11252 if (needSep) { 11253 pw.println(); 11254 needSep = false; 11255 } 11256 pw.println(" mHomeProcess: " + mHomeProcess); 11257 } 11258 if (mPreviousProcess != null && (dumpPackage == null 11259 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11260 if (needSep) { 11261 pw.println(); 11262 needSep = false; 11263 } 11264 pw.println(" mPreviousProcess: " + mPreviousProcess); 11265 } 11266 if (dumpAll) { 11267 StringBuilder sb = new StringBuilder(128); 11268 sb.append(" mPreviousProcessVisibleTime: "); 11269 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11270 pw.println(sb); 11271 } 11272 if (mHeavyWeightProcess != null && (dumpPackage == null 11273 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11274 if (needSep) { 11275 pw.println(); 11276 needSep = false; 11277 } 11278 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11279 } 11280 if (dumpPackage == null) { 11281 pw.println(" mConfiguration: " + mConfiguration); 11282 } 11283 if (dumpAll) { 11284 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11285 if (mCompatModePackages.getPackages().size() > 0) { 11286 boolean printed = false; 11287 for (Map.Entry<String, Integer> entry 11288 : mCompatModePackages.getPackages().entrySet()) { 11289 String pkg = entry.getKey(); 11290 int mode = entry.getValue(); 11291 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11292 continue; 11293 } 11294 if (!printed) { 11295 pw.println(" mScreenCompatPackages:"); 11296 printed = true; 11297 } 11298 pw.print(" "); pw.print(pkg); pw.print(": "); 11299 pw.print(mode); pw.println(); 11300 } 11301 } 11302 } 11303 if (dumpPackage == null) { 11304 if (mSleeping || mWentToSleep || mLockScreenShown) { 11305 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11306 + " mLockScreenShown " + mLockScreenShown); 11307 } 11308 if (mShuttingDown || mRunningVoice) { 11309 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11310 } 11311 } 11312 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11313 || mOrigWaitForDebugger) { 11314 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11315 || dumpPackage.equals(mOrigDebugApp)) { 11316 if (needSep) { 11317 pw.println(); 11318 needSep = false; 11319 } 11320 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11321 + " mDebugTransient=" + mDebugTransient 11322 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11323 } 11324 } 11325 if (mOpenGlTraceApp != null) { 11326 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11327 if (needSep) { 11328 pw.println(); 11329 needSep = false; 11330 } 11331 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11332 } 11333 } 11334 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11335 || mProfileFd != null) { 11336 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11337 if (needSep) { 11338 pw.println(); 11339 needSep = false; 11340 } 11341 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11342 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11343 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11344 + mAutoStopProfiler); 11345 } 11346 } 11347 if (dumpPackage == null) { 11348 if (mAlwaysFinishActivities || mController != null) { 11349 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11350 + " mController=" + mController); 11351 } 11352 if (dumpAll) { 11353 pw.println(" Total persistent processes: " + numPers); 11354 pw.println(" mProcessesReady=" + mProcessesReady 11355 + " mSystemReady=" + mSystemReady); 11356 pw.println(" mBooting=" + mBooting 11357 + " mBooted=" + mBooted 11358 + " mFactoryTest=" + mFactoryTest); 11359 pw.print(" mLastPowerCheckRealtime="); 11360 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11361 pw.println(""); 11362 pw.print(" mLastPowerCheckUptime="); 11363 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11364 pw.println(""); 11365 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11366 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11367 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11368 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11369 + " (" + mLruProcesses.size() + " total)" 11370 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11371 + " mNumServiceProcs=" + mNumServiceProcs 11372 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11373 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11374 + " mLastMemoryLevel" + mLastMemoryLevel 11375 + " mLastNumProcesses" + mLastNumProcesses); 11376 long now = SystemClock.uptimeMillis(); 11377 pw.print(" mLastIdleTime="); 11378 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11379 pw.print(" mLowRamSinceLastIdle="); 11380 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11381 pw.println(); 11382 } 11383 } 11384 11385 if (!printedAnything) { 11386 pw.println(" (nothing)"); 11387 } 11388 } 11389 11390 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11391 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11392 if (mProcessesToGc.size() > 0) { 11393 boolean printed = false; 11394 long now = SystemClock.uptimeMillis(); 11395 for (int i=0; i<mProcessesToGc.size(); i++) { 11396 ProcessRecord proc = mProcessesToGc.get(i); 11397 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11398 continue; 11399 } 11400 if (!printed) { 11401 if (needSep) pw.println(); 11402 needSep = true; 11403 pw.println(" Processes that are waiting to GC:"); 11404 printed = true; 11405 } 11406 pw.print(" Process "); pw.println(proc); 11407 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11408 pw.print(", last gced="); 11409 pw.print(now-proc.lastRequestedGc); 11410 pw.print(" ms ago, last lowMem="); 11411 pw.print(now-proc.lastLowMemory); 11412 pw.println(" ms ago"); 11413 11414 } 11415 } 11416 return needSep; 11417 } 11418 11419 void printOomLevel(PrintWriter pw, String name, int adj) { 11420 pw.print(" "); 11421 if (adj >= 0) { 11422 pw.print(' '); 11423 if (adj < 10) pw.print(' '); 11424 } else { 11425 if (adj > -10) pw.print(' '); 11426 } 11427 pw.print(adj); 11428 pw.print(": "); 11429 pw.print(name); 11430 pw.print(" ("); 11431 pw.print(mProcessList.getMemLevel(adj)/1024); 11432 pw.println(" kB)"); 11433 } 11434 11435 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11436 int opti, boolean dumpAll) { 11437 boolean needSep = false; 11438 11439 if (mLruProcesses.size() > 0) { 11440 if (needSep) pw.println(); 11441 needSep = true; 11442 pw.println(" OOM levels:"); 11443 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11444 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11445 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11446 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11447 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11448 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11449 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11450 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11451 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11452 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11453 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11454 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11455 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11456 11457 if (needSep) pw.println(); 11458 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11459 pw.print(" total, non-act at "); 11460 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11461 pw.print(", non-svc at "); 11462 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11463 pw.println("):"); 11464 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11465 needSep = true; 11466 } 11467 11468 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11469 11470 pw.println(); 11471 pw.println(" mHomeProcess: " + mHomeProcess); 11472 pw.println(" mPreviousProcess: " + mPreviousProcess); 11473 if (mHeavyWeightProcess != null) { 11474 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11475 } 11476 11477 return true; 11478 } 11479 11480 /** 11481 * There are three ways to call this: 11482 * - no provider specified: dump all the providers 11483 * - a flattened component name that matched an existing provider was specified as the 11484 * first arg: dump that one provider 11485 * - the first arg isn't the flattened component name of an existing provider: 11486 * dump all providers whose component contains the first arg as a substring 11487 */ 11488 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11489 int opti, boolean dumpAll) { 11490 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11491 } 11492 11493 static class ItemMatcher { 11494 ArrayList<ComponentName> components; 11495 ArrayList<String> strings; 11496 ArrayList<Integer> objects; 11497 boolean all; 11498 11499 ItemMatcher() { 11500 all = true; 11501 } 11502 11503 void build(String name) { 11504 ComponentName componentName = ComponentName.unflattenFromString(name); 11505 if (componentName != null) { 11506 if (components == null) { 11507 components = new ArrayList<ComponentName>(); 11508 } 11509 components.add(componentName); 11510 all = false; 11511 } else { 11512 int objectId = 0; 11513 // Not a '/' separated full component name; maybe an object ID? 11514 try { 11515 objectId = Integer.parseInt(name, 16); 11516 if (objects == null) { 11517 objects = new ArrayList<Integer>(); 11518 } 11519 objects.add(objectId); 11520 all = false; 11521 } catch (RuntimeException e) { 11522 // Not an integer; just do string match. 11523 if (strings == null) { 11524 strings = new ArrayList<String>(); 11525 } 11526 strings.add(name); 11527 all = false; 11528 } 11529 } 11530 } 11531 11532 int build(String[] args, int opti) { 11533 for (; opti<args.length; opti++) { 11534 String name = args[opti]; 11535 if ("--".equals(name)) { 11536 return opti+1; 11537 } 11538 build(name); 11539 } 11540 return opti; 11541 } 11542 11543 boolean match(Object object, ComponentName comp) { 11544 if (all) { 11545 return true; 11546 } 11547 if (components != null) { 11548 for (int i=0; i<components.size(); i++) { 11549 if (components.get(i).equals(comp)) { 11550 return true; 11551 } 11552 } 11553 } 11554 if (objects != null) { 11555 for (int i=0; i<objects.size(); i++) { 11556 if (System.identityHashCode(object) == objects.get(i)) { 11557 return true; 11558 } 11559 } 11560 } 11561 if (strings != null) { 11562 String flat = comp.flattenToString(); 11563 for (int i=0; i<strings.size(); i++) { 11564 if (flat.contains(strings.get(i))) { 11565 return true; 11566 } 11567 } 11568 } 11569 return false; 11570 } 11571 } 11572 11573 /** 11574 * There are three things that cmd can be: 11575 * - a flattened component name that matches an existing activity 11576 * - the cmd arg isn't the flattened component name of an existing activity: 11577 * dump all activity whose component contains the cmd as a substring 11578 * - A hex number of the ActivityRecord object instance. 11579 */ 11580 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11581 int opti, boolean dumpAll) { 11582 ArrayList<ActivityRecord> activities; 11583 11584 synchronized (this) { 11585 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11586 } 11587 11588 if (activities.size() <= 0) { 11589 return false; 11590 } 11591 11592 String[] newArgs = new String[args.length - opti]; 11593 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11594 11595 TaskRecord lastTask = null; 11596 boolean needSep = false; 11597 for (int i=activities.size()-1; i>=0; i--) { 11598 ActivityRecord r = activities.get(i); 11599 if (needSep) { 11600 pw.println(); 11601 } 11602 needSep = true; 11603 synchronized (this) { 11604 if (lastTask != r.task) { 11605 lastTask = r.task; 11606 pw.print("TASK "); pw.print(lastTask.affinity); 11607 pw.print(" id="); pw.println(lastTask.taskId); 11608 if (dumpAll) { 11609 lastTask.dump(pw, " "); 11610 } 11611 } 11612 } 11613 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11614 } 11615 return true; 11616 } 11617 11618 /** 11619 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11620 * there is a thread associated with the activity. 11621 */ 11622 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11623 final ActivityRecord r, String[] args, boolean dumpAll) { 11624 String innerPrefix = prefix + " "; 11625 synchronized (this) { 11626 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11627 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11628 pw.print(" pid="); 11629 if (r.app != null) pw.println(r.app.pid); 11630 else pw.println("(not running)"); 11631 if (dumpAll) { 11632 r.dump(pw, innerPrefix); 11633 } 11634 } 11635 if (r.app != null && r.app.thread != null) { 11636 // flush anything that is already in the PrintWriter since the thread is going 11637 // to write to the file descriptor directly 11638 pw.flush(); 11639 try { 11640 TransferPipe tp = new TransferPipe(); 11641 try { 11642 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11643 r.appToken, innerPrefix, args); 11644 tp.go(fd); 11645 } finally { 11646 tp.kill(); 11647 } 11648 } catch (IOException e) { 11649 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11650 } catch (RemoteException e) { 11651 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11652 } 11653 } 11654 } 11655 11656 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11657 int opti, boolean dumpAll, String dumpPackage) { 11658 boolean needSep = false; 11659 boolean onlyHistory = false; 11660 boolean printedAnything = false; 11661 11662 if ("history".equals(dumpPackage)) { 11663 if (opti < args.length && "-s".equals(args[opti])) { 11664 dumpAll = false; 11665 } 11666 onlyHistory = true; 11667 dumpPackage = null; 11668 } 11669 11670 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11671 if (!onlyHistory && dumpAll) { 11672 if (mRegisteredReceivers.size() > 0) { 11673 boolean printed = false; 11674 Iterator it = mRegisteredReceivers.values().iterator(); 11675 while (it.hasNext()) { 11676 ReceiverList r = (ReceiverList)it.next(); 11677 if (dumpPackage != null && (r.app == null || 11678 !dumpPackage.equals(r.app.info.packageName))) { 11679 continue; 11680 } 11681 if (!printed) { 11682 pw.println(" Registered Receivers:"); 11683 needSep = true; 11684 printed = true; 11685 printedAnything = true; 11686 } 11687 pw.print(" * "); pw.println(r); 11688 r.dump(pw, " "); 11689 } 11690 } 11691 11692 if (mReceiverResolver.dump(pw, needSep ? 11693 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11694 " ", dumpPackage, false)) { 11695 needSep = true; 11696 printedAnything = true; 11697 } 11698 } 11699 11700 for (BroadcastQueue q : mBroadcastQueues) { 11701 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11702 printedAnything |= needSep; 11703 } 11704 11705 needSep = true; 11706 11707 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11708 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11709 if (needSep) { 11710 pw.println(); 11711 } 11712 needSep = true; 11713 printedAnything = true; 11714 pw.print(" Sticky broadcasts for user "); 11715 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11716 StringBuilder sb = new StringBuilder(128); 11717 for (Map.Entry<String, ArrayList<Intent>> ent 11718 : mStickyBroadcasts.valueAt(user).entrySet()) { 11719 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11720 if (dumpAll) { 11721 pw.println(":"); 11722 ArrayList<Intent> intents = ent.getValue(); 11723 final int N = intents.size(); 11724 for (int i=0; i<N; i++) { 11725 sb.setLength(0); 11726 sb.append(" Intent: "); 11727 intents.get(i).toShortString(sb, false, true, false, false); 11728 pw.println(sb.toString()); 11729 Bundle bundle = intents.get(i).getExtras(); 11730 if (bundle != null) { 11731 pw.print(" "); 11732 pw.println(bundle.toString()); 11733 } 11734 } 11735 } else { 11736 pw.println(""); 11737 } 11738 } 11739 } 11740 } 11741 11742 if (!onlyHistory && dumpAll) { 11743 pw.println(); 11744 for (BroadcastQueue queue : mBroadcastQueues) { 11745 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11746 + queue.mBroadcastsScheduled); 11747 } 11748 pw.println(" mHandler:"); 11749 mHandler.dump(new PrintWriterPrinter(pw), " "); 11750 needSep = true; 11751 printedAnything = true; 11752 } 11753 11754 if (!printedAnything) { 11755 pw.println(" (nothing)"); 11756 } 11757 } 11758 11759 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11760 int opti, boolean dumpAll, String dumpPackage) { 11761 boolean needSep; 11762 boolean printedAnything = false; 11763 11764 ItemMatcher matcher = new ItemMatcher(); 11765 matcher.build(args, opti); 11766 11767 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11768 11769 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11770 printedAnything |= needSep; 11771 11772 if (mLaunchingProviders.size() > 0) { 11773 boolean printed = false; 11774 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11775 ContentProviderRecord r = mLaunchingProviders.get(i); 11776 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11777 continue; 11778 } 11779 if (!printed) { 11780 if (needSep) pw.println(); 11781 needSep = true; 11782 pw.println(" Launching content providers:"); 11783 printed = true; 11784 printedAnything = true; 11785 } 11786 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11787 pw.println(r); 11788 } 11789 } 11790 11791 if (mGrantedUriPermissions.size() > 0) { 11792 boolean printed = false; 11793 int dumpUid = -2; 11794 if (dumpPackage != null) { 11795 try { 11796 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11797 } catch (NameNotFoundException e) { 11798 dumpUid = -1; 11799 } 11800 } 11801 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11802 int uid = mGrantedUriPermissions.keyAt(i); 11803 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11804 continue; 11805 } 11806 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11807 if (!printed) { 11808 if (needSep) pw.println(); 11809 needSep = true; 11810 pw.println(" Granted Uri Permissions:"); 11811 printed = true; 11812 printedAnything = true; 11813 } 11814 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11815 for (UriPermission perm : perms.values()) { 11816 pw.print(" "); pw.println(perm); 11817 if (dumpAll) { 11818 perm.dump(pw, " "); 11819 } 11820 } 11821 } 11822 } 11823 11824 if (!printedAnything) { 11825 pw.println(" (nothing)"); 11826 } 11827 } 11828 11829 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11830 int opti, boolean dumpAll, String dumpPackage) { 11831 boolean printed = false; 11832 11833 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11834 11835 if (mIntentSenderRecords.size() > 0) { 11836 Iterator<WeakReference<PendingIntentRecord>> it 11837 = mIntentSenderRecords.values().iterator(); 11838 while (it.hasNext()) { 11839 WeakReference<PendingIntentRecord> ref = it.next(); 11840 PendingIntentRecord rec = ref != null ? ref.get(): null; 11841 if (dumpPackage != null && (rec == null 11842 || !dumpPackage.equals(rec.key.packageName))) { 11843 continue; 11844 } 11845 printed = true; 11846 if (rec != null) { 11847 pw.print(" * "); pw.println(rec); 11848 if (dumpAll) { 11849 rec.dump(pw, " "); 11850 } 11851 } else { 11852 pw.print(" * "); pw.println(ref); 11853 } 11854 } 11855 } 11856 11857 if (!printed) { 11858 pw.println(" (nothing)"); 11859 } 11860 } 11861 11862 private static final int dumpProcessList(PrintWriter pw, 11863 ActivityManagerService service, List list, 11864 String prefix, String normalLabel, String persistentLabel, 11865 String dumpPackage) { 11866 int numPers = 0; 11867 final int N = list.size()-1; 11868 for (int i=N; i>=0; i--) { 11869 ProcessRecord r = (ProcessRecord)list.get(i); 11870 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11871 continue; 11872 } 11873 pw.println(String.format("%s%s #%2d: %s", 11874 prefix, (r.persistent ? persistentLabel : normalLabel), 11875 i, r.toString())); 11876 if (r.persistent) { 11877 numPers++; 11878 } 11879 } 11880 return numPers; 11881 } 11882 11883 private static final boolean dumpProcessOomList(PrintWriter pw, 11884 ActivityManagerService service, List<ProcessRecord> origList, 11885 String prefix, String normalLabel, String persistentLabel, 11886 boolean inclDetails, String dumpPackage) { 11887 11888 ArrayList<Pair<ProcessRecord, Integer>> list 11889 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11890 for (int i=0; i<origList.size(); i++) { 11891 ProcessRecord r = origList.get(i); 11892 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11893 continue; 11894 } 11895 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11896 } 11897 11898 if (list.size() <= 0) { 11899 return false; 11900 } 11901 11902 Comparator<Pair<ProcessRecord, Integer>> comparator 11903 = new Comparator<Pair<ProcessRecord, Integer>>() { 11904 @Override 11905 public int compare(Pair<ProcessRecord, Integer> object1, 11906 Pair<ProcessRecord, Integer> object2) { 11907 if (object1.first.setAdj != object2.first.setAdj) { 11908 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11909 } 11910 if (object1.second.intValue() != object2.second.intValue()) { 11911 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11912 } 11913 return 0; 11914 } 11915 }; 11916 11917 Collections.sort(list, comparator); 11918 11919 final long curRealtime = SystemClock.elapsedRealtime(); 11920 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11921 final long curUptime = SystemClock.uptimeMillis(); 11922 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11923 11924 for (int i=list.size()-1; i>=0; i--) { 11925 ProcessRecord r = list.get(i).first; 11926 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11927 char schedGroup; 11928 switch (r.setSchedGroup) { 11929 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11930 schedGroup = 'B'; 11931 break; 11932 case Process.THREAD_GROUP_DEFAULT: 11933 schedGroup = 'F'; 11934 break; 11935 default: 11936 schedGroup = '?'; 11937 break; 11938 } 11939 char foreground; 11940 if (r.foregroundActivities) { 11941 foreground = 'A'; 11942 } else if (r.foregroundServices) { 11943 foreground = 'S'; 11944 } else { 11945 foreground = ' '; 11946 } 11947 String procState = ProcessList.makeProcStateString(r.curProcState); 11948 pw.print(prefix); 11949 pw.print(r.persistent ? persistentLabel : normalLabel); 11950 pw.print(" #"); 11951 int num = (origList.size()-1)-list.get(i).second; 11952 if (num < 10) pw.print(' '); 11953 pw.print(num); 11954 pw.print(": "); 11955 pw.print(oomAdj); 11956 pw.print(' '); 11957 pw.print(schedGroup); 11958 pw.print('/'); 11959 pw.print(foreground); 11960 pw.print('/'); 11961 pw.print(procState); 11962 pw.print(" trm:"); 11963 if (r.trimMemoryLevel < 10) pw.print(' '); 11964 pw.print(r.trimMemoryLevel); 11965 pw.print(' '); 11966 pw.print(r.toShortString()); 11967 pw.print(" ("); 11968 pw.print(r.adjType); 11969 pw.println(')'); 11970 if (r.adjSource != null || r.adjTarget != null) { 11971 pw.print(prefix); 11972 pw.print(" "); 11973 if (r.adjTarget instanceof ComponentName) { 11974 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11975 } else if (r.adjTarget != null) { 11976 pw.print(r.adjTarget.toString()); 11977 } else { 11978 pw.print("{null}"); 11979 } 11980 pw.print("<="); 11981 if (r.adjSource instanceof ProcessRecord) { 11982 pw.print("Proc{"); 11983 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11984 pw.println("}"); 11985 } else if (r.adjSource != null) { 11986 pw.println(r.adjSource.toString()); 11987 } else { 11988 pw.println("{null}"); 11989 } 11990 } 11991 if (inclDetails) { 11992 pw.print(prefix); 11993 pw.print(" "); 11994 pw.print("oom: max="); pw.print(r.maxAdj); 11995 pw.print(" curRaw="); pw.print(r.curRawAdj); 11996 pw.print(" setRaw="); pw.print(r.setRawAdj); 11997 pw.print(" cur="); pw.print(r.curAdj); 11998 pw.print(" set="); pw.println(r.setAdj); 11999 pw.print(prefix); 12000 pw.print(" "); 12001 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 12002 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 12003 pw.print(" lastPss="); pw.print(r.lastPss); 12004 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12005 pw.print(prefix); 12006 pw.print(" "); 12007 pw.print("keeping="); pw.print(r.keeping); 12008 pw.print(" cached="); pw.print(r.cached); 12009 pw.print(" empty="); pw.print(r.empty); 12010 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12011 12012 if (!r.keeping) { 12013 if (r.lastWakeTime != 0) { 12014 long wtime; 12015 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12016 synchronized (stats) { 12017 wtime = stats.getProcessWakeTime(r.info.uid, 12018 r.pid, curRealtime); 12019 } 12020 long timeUsed = wtime - r.lastWakeTime; 12021 pw.print(prefix); 12022 pw.print(" "); 12023 pw.print("keep awake over "); 12024 TimeUtils.formatDuration(realtimeSince, pw); 12025 pw.print(" used "); 12026 TimeUtils.formatDuration(timeUsed, pw); 12027 pw.print(" ("); 12028 pw.print((timeUsed*100)/realtimeSince); 12029 pw.println("%)"); 12030 } 12031 if (r.lastCpuTime != 0) { 12032 long timeUsed = r.curCpuTime - r.lastCpuTime; 12033 pw.print(prefix); 12034 pw.print(" "); 12035 pw.print("run cpu over "); 12036 TimeUtils.formatDuration(uptimeSince, pw); 12037 pw.print(" used "); 12038 TimeUtils.formatDuration(timeUsed, pw); 12039 pw.print(" ("); 12040 pw.print((timeUsed*100)/uptimeSince); 12041 pw.println("%)"); 12042 } 12043 } 12044 } 12045 } 12046 return true; 12047 } 12048 12049 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12050 ArrayList<ProcessRecord> procs; 12051 synchronized (this) { 12052 if (args != null && args.length > start 12053 && args[start].charAt(0) != '-') { 12054 procs = new ArrayList<ProcessRecord>(); 12055 int pid = -1; 12056 try { 12057 pid = Integer.parseInt(args[start]); 12058 } catch (NumberFormatException e) { 12059 } 12060 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12061 ProcessRecord proc = mLruProcesses.get(i); 12062 if (proc.pid == pid) { 12063 procs.add(proc); 12064 } else if (proc.processName.equals(args[start])) { 12065 procs.add(proc); 12066 } 12067 } 12068 if (procs.size() <= 0) { 12069 return null; 12070 } 12071 } else { 12072 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12073 } 12074 } 12075 return procs; 12076 } 12077 12078 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12079 PrintWriter pw, String[] args) { 12080 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12081 if (procs == null) { 12082 pw.println("No process found for: " + args[0]); 12083 return; 12084 } 12085 12086 long uptime = SystemClock.uptimeMillis(); 12087 long realtime = SystemClock.elapsedRealtime(); 12088 pw.println("Applications Graphics Acceleration Info:"); 12089 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12090 12091 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12092 ProcessRecord r = procs.get(i); 12093 if (r.thread != null) { 12094 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12095 pw.flush(); 12096 try { 12097 TransferPipe tp = new TransferPipe(); 12098 try { 12099 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12100 tp.go(fd); 12101 } finally { 12102 tp.kill(); 12103 } 12104 } catch (IOException e) { 12105 pw.println("Failure while dumping the app: " + r); 12106 pw.flush(); 12107 } catch (RemoteException e) { 12108 pw.println("Got a RemoteException while dumping the app " + r); 12109 pw.flush(); 12110 } 12111 } 12112 } 12113 } 12114 12115 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12116 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12117 if (procs == null) { 12118 pw.println("No process found for: " + args[0]); 12119 return; 12120 } 12121 12122 pw.println("Applications Database Info:"); 12123 12124 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12125 ProcessRecord r = procs.get(i); 12126 if (r.thread != null) { 12127 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12128 pw.flush(); 12129 try { 12130 TransferPipe tp = new TransferPipe(); 12131 try { 12132 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12133 tp.go(fd); 12134 } finally { 12135 tp.kill(); 12136 } 12137 } catch (IOException e) { 12138 pw.println("Failure while dumping the app: " + r); 12139 pw.flush(); 12140 } catch (RemoteException e) { 12141 pw.println("Got a RemoteException while dumping the app " + r); 12142 pw.flush(); 12143 } 12144 } 12145 } 12146 } 12147 12148 final static class MemItem { 12149 final boolean isProc; 12150 final String label; 12151 final String shortLabel; 12152 final long pss; 12153 final int id; 12154 final boolean hasActivities; 12155 ArrayList<MemItem> subitems; 12156 12157 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12158 boolean _hasActivities) { 12159 isProc = true; 12160 label = _label; 12161 shortLabel = _shortLabel; 12162 pss = _pss; 12163 id = _id; 12164 hasActivities = _hasActivities; 12165 } 12166 12167 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12168 isProc = false; 12169 label = _label; 12170 shortLabel = _shortLabel; 12171 pss = _pss; 12172 id = _id; 12173 hasActivities = false; 12174 } 12175 } 12176 12177 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12178 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12179 if (sort && !isCompact) { 12180 Collections.sort(items, new Comparator<MemItem>() { 12181 @Override 12182 public int compare(MemItem lhs, MemItem rhs) { 12183 if (lhs.pss < rhs.pss) { 12184 return 1; 12185 } else if (lhs.pss > rhs.pss) { 12186 return -1; 12187 } 12188 return 0; 12189 } 12190 }); 12191 } 12192 12193 for (int i=0; i<items.size(); i++) { 12194 MemItem mi = items.get(i); 12195 if (!isCompact) { 12196 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12197 } else if (mi.isProc) { 12198 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12199 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12200 pw.println(mi.hasActivities ? ",a" : ",e"); 12201 } else { 12202 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12203 pw.println(mi.pss); 12204 } 12205 if (mi.subitems != null) { 12206 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12207 true, isCompact); 12208 } 12209 } 12210 } 12211 12212 // These are in KB. 12213 static final long[] DUMP_MEM_BUCKETS = new long[] { 12214 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12215 120*1024, 160*1024, 200*1024, 12216 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12217 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12218 }; 12219 12220 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12221 boolean stackLike) { 12222 int start = label.lastIndexOf('.'); 12223 if (start >= 0) start++; 12224 else start = 0; 12225 int end = label.length(); 12226 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12227 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12228 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12229 out.append(bucket); 12230 out.append(stackLike ? "MB." : "MB "); 12231 out.append(label, start, end); 12232 return; 12233 } 12234 } 12235 out.append(memKB/1024); 12236 out.append(stackLike ? "MB." : "MB "); 12237 out.append(label, start, end); 12238 } 12239 12240 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12241 ProcessList.NATIVE_ADJ, 12242 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12243 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12244 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12245 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12246 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12247 }; 12248 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12249 "Native", 12250 "System", "Persistent", "Foreground", 12251 "Visible", "Perceptible", 12252 "Heavy Weight", "Backup", 12253 "A Services", "Home", 12254 "Previous", "B Services", "Cached" 12255 }; 12256 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12257 "native", 12258 "sys", "pers", "fore", 12259 "vis", "percept", 12260 "heavy", "backup", 12261 "servicea", "home", 12262 "prev", "serviceb", "cached" 12263 }; 12264 12265 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12266 long realtime, boolean isCheckinRequest, boolean isCompact) { 12267 if (isCheckinRequest || isCompact) { 12268 // short checkin version 12269 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12270 } else { 12271 pw.println("Applications Memory Usage (kB):"); 12272 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12273 } 12274 } 12275 12276 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12277 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12278 boolean dumpDetails = false; 12279 boolean dumpFullDetails = false; 12280 boolean dumpDalvik = false; 12281 boolean oomOnly = false; 12282 boolean isCompact = false; 12283 boolean localOnly = false; 12284 12285 int opti = 0; 12286 while (opti < args.length) { 12287 String opt = args[opti]; 12288 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12289 break; 12290 } 12291 opti++; 12292 if ("-a".equals(opt)) { 12293 dumpDetails = true; 12294 dumpFullDetails = true; 12295 dumpDalvik = true; 12296 } else if ("-d".equals(opt)) { 12297 dumpDalvik = true; 12298 } else if ("-c".equals(opt)) { 12299 isCompact = true; 12300 } else if ("--oom".equals(opt)) { 12301 oomOnly = true; 12302 } else if ("--local".equals(opt)) { 12303 localOnly = true; 12304 } else if ("-h".equals(opt)) { 12305 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12306 pw.println(" -a: include all available information for each process."); 12307 pw.println(" -d: include dalvik details when dumping process details."); 12308 pw.println(" -c: dump in a compact machine-parseable representation."); 12309 pw.println(" --oom: only show processes organized by oom adj."); 12310 pw.println(" --local: only collect details locally, don't call process."); 12311 pw.println("If [process] is specified it can be the name or "); 12312 pw.println("pid of a specific process to dump."); 12313 return; 12314 } else { 12315 pw.println("Unknown argument: " + opt + "; use -h for help"); 12316 } 12317 } 12318 12319 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12320 long uptime = SystemClock.uptimeMillis(); 12321 long realtime = SystemClock.elapsedRealtime(); 12322 final long[] tmpLong = new long[1]; 12323 12324 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12325 if (procs == null) { 12326 // No Java processes. Maybe they want to print a native process. 12327 if (args != null && args.length > opti 12328 && args[opti].charAt(0) != '-') { 12329 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12330 = new ArrayList<ProcessCpuTracker.Stats>(); 12331 updateCpuStatsNow(); 12332 int findPid = -1; 12333 try { 12334 findPid = Integer.parseInt(args[opti]); 12335 } catch (NumberFormatException e) { 12336 } 12337 synchronized (mProcessCpuThread) { 12338 final int N = mProcessCpuTracker.countStats(); 12339 for (int i=0; i<N; i++) { 12340 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12341 if (st.pid == findPid || (st.baseName != null 12342 && st.baseName.equals(args[opti]))) { 12343 nativeProcs.add(st); 12344 } 12345 } 12346 } 12347 if (nativeProcs.size() > 0) { 12348 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12349 isCompact); 12350 Debug.MemoryInfo mi = null; 12351 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12352 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12353 final int pid = r.pid; 12354 if (!isCheckinRequest && dumpDetails) { 12355 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12356 } 12357 if (mi == null) { 12358 mi = new Debug.MemoryInfo(); 12359 } 12360 if (dumpDetails || (!brief && !oomOnly)) { 12361 Debug.getMemoryInfo(pid, mi); 12362 } else { 12363 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12364 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12365 } 12366 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12367 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12368 if (isCheckinRequest) { 12369 pw.println(); 12370 } 12371 } 12372 return; 12373 } 12374 } 12375 pw.println("No process found for: " + args[opti]); 12376 return; 12377 } 12378 12379 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12380 dumpDetails = true; 12381 } 12382 12383 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12384 12385 String[] innerArgs = new String[args.length-opti]; 12386 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12387 12388 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12389 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12390 long nativePss=0, dalvikPss=0, otherPss=0; 12391 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12392 12393 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12394 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12395 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12396 12397 long totalPss = 0; 12398 long cachedPss = 0; 12399 12400 Debug.MemoryInfo mi = null; 12401 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12402 final ProcessRecord r = procs.get(i); 12403 final IApplicationThread thread; 12404 final int pid; 12405 final int oomAdj; 12406 final boolean hasActivities; 12407 synchronized (this) { 12408 thread = r.thread; 12409 pid = r.pid; 12410 oomAdj = r.getSetAdjWithServices(); 12411 hasActivities = r.activities.size() > 0; 12412 } 12413 if (thread != null) { 12414 if (!isCheckinRequest && dumpDetails) { 12415 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12416 } 12417 if (mi == null) { 12418 mi = new Debug.MemoryInfo(); 12419 } 12420 if (dumpDetails || (!brief && !oomOnly)) { 12421 Debug.getMemoryInfo(pid, mi); 12422 } else { 12423 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12424 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12425 } 12426 if (dumpDetails) { 12427 if (localOnly) { 12428 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12429 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12430 if (isCheckinRequest) { 12431 pw.println(); 12432 } 12433 } else { 12434 try { 12435 pw.flush(); 12436 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12437 dumpDalvik, innerArgs); 12438 } catch (RemoteException e) { 12439 if (!isCheckinRequest) { 12440 pw.println("Got RemoteException!"); 12441 pw.flush(); 12442 } 12443 } 12444 } 12445 } 12446 12447 final long myTotalPss = mi.getTotalPss(); 12448 final long myTotalUss = mi.getTotalUss(); 12449 12450 synchronized (this) { 12451 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12452 // Record this for posterity if the process has been stable. 12453 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12454 } 12455 } 12456 12457 if (!isCheckinRequest && mi != null) { 12458 totalPss += myTotalPss; 12459 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12460 (hasActivities ? " / activities)" : ")"), 12461 r.processName, myTotalPss, pid, hasActivities); 12462 procMems.add(pssItem); 12463 procMemsMap.put(pid, pssItem); 12464 12465 nativePss += mi.nativePss; 12466 dalvikPss += mi.dalvikPss; 12467 otherPss += mi.otherPss; 12468 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12469 long mem = mi.getOtherPss(j); 12470 miscPss[j] += mem; 12471 otherPss -= mem; 12472 } 12473 12474 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12475 cachedPss += myTotalPss; 12476 } 12477 12478 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12479 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12480 || oomIndex == (oomPss.length-1)) { 12481 oomPss[oomIndex] += myTotalPss; 12482 if (oomProcs[oomIndex] == null) { 12483 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12484 } 12485 oomProcs[oomIndex].add(pssItem); 12486 break; 12487 } 12488 } 12489 } 12490 } 12491 } 12492 12493 if (!isCheckinRequest && procs.size() > 1) { 12494 // If we are showing aggregations, also look for native processes to 12495 // include so that our aggregations are more accurate. 12496 updateCpuStatsNow(); 12497 synchronized (mProcessCpuThread) { 12498 final int N = mProcessCpuTracker.countStats(); 12499 for (int i=0; i<N; i++) { 12500 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12501 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12502 if (mi == null) { 12503 mi = new Debug.MemoryInfo(); 12504 } 12505 if (!brief && !oomOnly) { 12506 Debug.getMemoryInfo(st.pid, mi); 12507 } else { 12508 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12509 mi.nativePrivateDirty = (int)tmpLong[0]; 12510 } 12511 12512 final long myTotalPss = mi.getTotalPss(); 12513 totalPss += myTotalPss; 12514 12515 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12516 st.name, myTotalPss, st.pid, false); 12517 procMems.add(pssItem); 12518 12519 nativePss += mi.nativePss; 12520 dalvikPss += mi.dalvikPss; 12521 otherPss += mi.otherPss; 12522 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12523 long mem = mi.getOtherPss(j); 12524 miscPss[j] += mem; 12525 otherPss -= mem; 12526 } 12527 oomPss[0] += myTotalPss; 12528 if (oomProcs[0] == null) { 12529 oomProcs[0] = new ArrayList<MemItem>(); 12530 } 12531 oomProcs[0].add(pssItem); 12532 } 12533 } 12534 } 12535 12536 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12537 12538 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12539 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12540 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12541 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12542 String label = Debug.MemoryInfo.getOtherLabel(j); 12543 catMems.add(new MemItem(label, label, miscPss[j], j)); 12544 } 12545 12546 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12547 for (int j=0; j<oomPss.length; j++) { 12548 if (oomPss[j] != 0) { 12549 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12550 : DUMP_MEM_OOM_LABEL[j]; 12551 MemItem item = new MemItem(label, label, oomPss[j], 12552 DUMP_MEM_OOM_ADJ[j]); 12553 item.subitems = oomProcs[j]; 12554 oomMems.add(item); 12555 } 12556 } 12557 12558 if (!brief && !oomOnly && !isCompact) { 12559 pw.println(); 12560 pw.println("Total PSS by process:"); 12561 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12562 pw.println(); 12563 } 12564 if (!isCompact) { 12565 pw.println("Total PSS by OOM adjustment:"); 12566 } 12567 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12568 if (!brief && !oomOnly) { 12569 PrintWriter out = categoryPw != null ? categoryPw : pw; 12570 if (!isCompact) { 12571 out.println(); 12572 out.println("Total PSS by category:"); 12573 } 12574 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12575 } 12576 if (!isCompact) { 12577 pw.println(); 12578 } 12579 MemInfoReader memInfo = new MemInfoReader(); 12580 memInfo.readMemInfo(); 12581 if (!brief) { 12582 if (!isCompact) { 12583 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12584 pw.print(" kB (status "); 12585 switch (mLastMemoryLevel) { 12586 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12587 pw.println("normal)"); 12588 break; 12589 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12590 pw.println("moderate)"); 12591 break; 12592 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12593 pw.println("low)"); 12594 break; 12595 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12596 pw.println("critical)"); 12597 break; 12598 default: 12599 pw.print(mLastMemoryLevel); 12600 pw.println(")"); 12601 break; 12602 } 12603 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12604 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12605 pw.print(cachedPss); pw.print(" cached pss + "); 12606 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12607 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12608 } else { 12609 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12610 pw.print(cachedPss + memInfo.getCachedSizeKb() 12611 + memInfo.getFreeSizeKb()); pw.print(","); 12612 pw.println(totalPss - cachedPss); 12613 } 12614 } 12615 if (!isCompact) { 12616 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12617 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12618 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12619 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12620 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12621 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12622 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12623 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12624 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12625 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12626 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12627 } 12628 if (!brief) { 12629 if (memInfo.getZramTotalSizeKb() != 0) { 12630 if (!isCompact) { 12631 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12632 pw.print(" kB physical used for "); 12633 pw.print(memInfo.getSwapTotalSizeKb() 12634 - memInfo.getSwapFreeSizeKb()); 12635 pw.print(" kB in swap ("); 12636 pw.print(memInfo.getSwapTotalSizeKb()); 12637 pw.println(" kB total swap)"); 12638 } else { 12639 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12640 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12641 pw.println(memInfo.getSwapFreeSizeKb()); 12642 } 12643 } 12644 final int[] SINGLE_LONG_FORMAT = new int[] { 12645 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12646 }; 12647 long[] longOut = new long[1]; 12648 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12649 SINGLE_LONG_FORMAT, null, longOut, null); 12650 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12651 longOut[0] = 0; 12652 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12653 SINGLE_LONG_FORMAT, null, longOut, null); 12654 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12655 longOut[0] = 0; 12656 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12657 SINGLE_LONG_FORMAT, null, longOut, null); 12658 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12659 longOut[0] = 0; 12660 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12661 SINGLE_LONG_FORMAT, null, longOut, null); 12662 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12663 if (!isCompact) { 12664 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12665 pw.print(" KSM: "); pw.print(sharing); 12666 pw.print(" kB saved from shared "); 12667 pw.print(shared); pw.println(" kB"); 12668 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12669 pw.print(voltile); pw.println(" kB volatile"); 12670 } 12671 pw.print(" Tuning: "); 12672 pw.print(ActivityManager.staticGetMemoryClass()); 12673 pw.print(" (large "); 12674 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12675 pw.print("), oom "); 12676 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12677 pw.print(" kB"); 12678 pw.print(", restore limit "); 12679 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12680 pw.print(" kB"); 12681 if (ActivityManager.isLowRamDeviceStatic()) { 12682 pw.print(" (low-ram)"); 12683 } 12684 if (ActivityManager.isHighEndGfx()) { 12685 pw.print(" (high-end-gfx)"); 12686 } 12687 pw.println(); 12688 } else { 12689 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12690 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12691 pw.println(voltile); 12692 pw.print("tuning,"); 12693 pw.print(ActivityManager.staticGetMemoryClass()); 12694 pw.print(','); 12695 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12696 pw.print(','); 12697 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12698 if (ActivityManager.isLowRamDeviceStatic()) { 12699 pw.print(",low-ram"); 12700 } 12701 if (ActivityManager.isHighEndGfx()) { 12702 pw.print(",high-end-gfx"); 12703 } 12704 pw.println(); 12705 } 12706 } 12707 } 12708 } 12709 12710 /** 12711 * Searches array of arguments for the specified string 12712 * @param args array of argument strings 12713 * @param value value to search for 12714 * @return true if the value is contained in the array 12715 */ 12716 private static boolean scanArgs(String[] args, String value) { 12717 if (args != null) { 12718 for (String arg : args) { 12719 if (value.equals(arg)) { 12720 return true; 12721 } 12722 } 12723 } 12724 return false; 12725 } 12726 12727 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12728 ContentProviderRecord cpr, boolean always) { 12729 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12730 12731 if (!inLaunching || always) { 12732 synchronized (cpr) { 12733 cpr.launchingApp = null; 12734 cpr.notifyAll(); 12735 } 12736 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12737 String names[] = cpr.info.authority.split(";"); 12738 for (int j = 0; j < names.length; j++) { 12739 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12740 } 12741 } 12742 12743 for (int i=0; i<cpr.connections.size(); i++) { 12744 ContentProviderConnection conn = cpr.connections.get(i); 12745 if (conn.waiting) { 12746 // If this connection is waiting for the provider, then we don't 12747 // need to mess with its process unless we are always removing 12748 // or for some reason the provider is not currently launching. 12749 if (inLaunching && !always) { 12750 continue; 12751 } 12752 } 12753 ProcessRecord capp = conn.client; 12754 conn.dead = true; 12755 if (conn.stableCount > 0) { 12756 if (!capp.persistent && capp.thread != null 12757 && capp.pid != 0 12758 && capp.pid != MY_PID) { 12759 killUnneededProcessLocked(capp, "depends on provider " 12760 + cpr.name.flattenToShortString() 12761 + " in dying proc " + (proc != null ? proc.processName : "??")); 12762 } 12763 } else if (capp.thread != null && conn.provider.provider != null) { 12764 try { 12765 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12766 } catch (RemoteException e) { 12767 } 12768 // In the protocol here, we don't expect the client to correctly 12769 // clean up this connection, we'll just remove it. 12770 cpr.connections.remove(i); 12771 conn.client.conProviders.remove(conn); 12772 } 12773 } 12774 12775 if (inLaunching && always) { 12776 mLaunchingProviders.remove(cpr); 12777 } 12778 return inLaunching; 12779 } 12780 12781 /** 12782 * Main code for cleaning up a process when it has gone away. This is 12783 * called both as a result of the process dying, or directly when stopping 12784 * a process when running in single process mode. 12785 */ 12786 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12787 boolean restarting, boolean allowRestart, int index) { 12788 if (index >= 0) { 12789 removeLruProcessLocked(app); 12790 ProcessList.remove(app.pid); 12791 } 12792 12793 mProcessesToGc.remove(app); 12794 mPendingPssProcesses.remove(app); 12795 12796 // Dismiss any open dialogs. 12797 if (app.crashDialog != null && !app.forceCrashReport) { 12798 app.crashDialog.dismiss(); 12799 app.crashDialog = null; 12800 } 12801 if (app.anrDialog != null) { 12802 app.anrDialog.dismiss(); 12803 app.anrDialog = null; 12804 } 12805 if (app.waitDialog != null) { 12806 app.waitDialog.dismiss(); 12807 app.waitDialog = null; 12808 } 12809 12810 app.crashing = false; 12811 app.notResponding = false; 12812 12813 app.resetPackageList(mProcessStats); 12814 app.unlinkDeathRecipient(); 12815 app.makeInactive(mProcessStats); 12816 app.forcingToForeground = null; 12817 updateProcessForegroundLocked(app, false, false); 12818 app.foregroundActivities = false; 12819 app.hasShownUi = false; 12820 app.treatLikeActivity = false; 12821 app.hasAboveClient = false; 12822 app.hasClientActivities = false; 12823 12824 mServices.killServicesLocked(app, allowRestart); 12825 12826 boolean restart = false; 12827 12828 // Remove published content providers. 12829 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12830 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12831 final boolean always = app.bad || !allowRestart; 12832 if (removeDyingProviderLocked(app, cpr, always) || always) { 12833 // We left the provider in the launching list, need to 12834 // restart it. 12835 restart = true; 12836 } 12837 12838 cpr.provider = null; 12839 cpr.proc = null; 12840 } 12841 app.pubProviders.clear(); 12842 12843 // Take care of any launching providers waiting for this process. 12844 if (checkAppInLaunchingProvidersLocked(app, false)) { 12845 restart = true; 12846 } 12847 12848 // Unregister from connected content providers. 12849 if (!app.conProviders.isEmpty()) { 12850 for (int i=0; i<app.conProviders.size(); i++) { 12851 ContentProviderConnection conn = app.conProviders.get(i); 12852 conn.provider.connections.remove(conn); 12853 } 12854 app.conProviders.clear(); 12855 } 12856 12857 // At this point there may be remaining entries in mLaunchingProviders 12858 // where we were the only one waiting, so they are no longer of use. 12859 // Look for these and clean up if found. 12860 // XXX Commented out for now. Trying to figure out a way to reproduce 12861 // the actual situation to identify what is actually going on. 12862 if (false) { 12863 for (int i=0; i<mLaunchingProviders.size(); i++) { 12864 ContentProviderRecord cpr = (ContentProviderRecord) 12865 mLaunchingProviders.get(i); 12866 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12867 synchronized (cpr) { 12868 cpr.launchingApp = null; 12869 cpr.notifyAll(); 12870 } 12871 } 12872 } 12873 } 12874 12875 skipCurrentReceiverLocked(app); 12876 12877 // Unregister any receivers. 12878 for (int i=app.receivers.size()-1; i>=0; i--) { 12879 removeReceiverLocked(app.receivers.valueAt(i)); 12880 } 12881 app.receivers.clear(); 12882 12883 // If the app is undergoing backup, tell the backup manager about it 12884 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12885 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12886 + mBackupTarget.appInfo + " died during backup"); 12887 try { 12888 IBackupManager bm = IBackupManager.Stub.asInterface( 12889 ServiceManager.getService(Context.BACKUP_SERVICE)); 12890 bm.agentDisconnected(app.info.packageName); 12891 } catch (RemoteException e) { 12892 // can't happen; backup manager is local 12893 } 12894 } 12895 12896 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12897 ProcessChangeItem item = mPendingProcessChanges.get(i); 12898 if (item.pid == app.pid) { 12899 mPendingProcessChanges.remove(i); 12900 mAvailProcessChanges.add(item); 12901 } 12902 } 12903 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12904 12905 // If the caller is restarting this app, then leave it in its 12906 // current lists and let the caller take care of it. 12907 if (restarting) { 12908 return; 12909 } 12910 12911 if (!app.persistent || app.isolated) { 12912 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12913 "Removing non-persistent process during cleanup: " + app); 12914 mProcessNames.remove(app.processName, app.uid); 12915 mIsolatedProcesses.remove(app.uid); 12916 if (mHeavyWeightProcess == app) { 12917 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12918 mHeavyWeightProcess.userId, 0)); 12919 mHeavyWeightProcess = null; 12920 } 12921 } else if (!app.removed) { 12922 // This app is persistent, so we need to keep its record around. 12923 // If it is not already on the pending app list, add it there 12924 // and start a new process for it. 12925 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12926 mPersistentStartingProcesses.add(app); 12927 restart = true; 12928 } 12929 } 12930 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12931 "Clean-up removing on hold: " + app); 12932 mProcessesOnHold.remove(app); 12933 12934 if (app == mHomeProcess) { 12935 mHomeProcess = null; 12936 } 12937 if (app == mPreviousProcess) { 12938 mPreviousProcess = null; 12939 } 12940 12941 if (restart && !app.isolated) { 12942 // We have components that still need to be running in the 12943 // process, so re-launch it. 12944 mProcessNames.put(app.processName, app.uid, app); 12945 startProcessLocked(app, "restart", app.processName); 12946 } else if (app.pid > 0 && app.pid != MY_PID) { 12947 // Goodbye! 12948 boolean removed; 12949 synchronized (mPidsSelfLocked) { 12950 mPidsSelfLocked.remove(app.pid); 12951 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12952 } 12953 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12954 app.processName, app.info.uid); 12955 if (app.isolated) { 12956 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12957 } 12958 app.setPid(0); 12959 } 12960 } 12961 12962 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12963 // Look through the content providers we are waiting to have launched, 12964 // and if any run in this process then either schedule a restart of 12965 // the process or kill the client waiting for it if this process has 12966 // gone bad. 12967 int NL = mLaunchingProviders.size(); 12968 boolean restart = false; 12969 for (int i=0; i<NL; i++) { 12970 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12971 if (cpr.launchingApp == app) { 12972 if (!alwaysBad && !app.bad) { 12973 restart = true; 12974 } else { 12975 removeDyingProviderLocked(app, cpr, true); 12976 // cpr should have been removed from mLaunchingProviders 12977 NL = mLaunchingProviders.size(); 12978 i--; 12979 } 12980 } 12981 } 12982 return restart; 12983 } 12984 12985 // ========================================================= 12986 // SERVICES 12987 // ========================================================= 12988 12989 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12990 int flags) { 12991 enforceNotIsolatedCaller("getServices"); 12992 synchronized (this) { 12993 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12994 } 12995 } 12996 12997 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12998 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12999 synchronized (this) { 13000 return mServices.getRunningServiceControlPanelLocked(name); 13001 } 13002 } 13003 13004 public ComponentName startService(IApplicationThread caller, Intent service, 13005 String resolvedType, int userId) { 13006 enforceNotIsolatedCaller("startService"); 13007 // Refuse possible leaked file descriptors 13008 if (service != null && service.hasFileDescriptors() == true) { 13009 throw new IllegalArgumentException("File descriptors passed in Intent"); 13010 } 13011 13012 if (DEBUG_SERVICE) 13013 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13014 synchronized(this) { 13015 final int callingPid = Binder.getCallingPid(); 13016 final int callingUid = Binder.getCallingUid(); 13017 final long origId = Binder.clearCallingIdentity(); 13018 ComponentName res = mServices.startServiceLocked(caller, service, 13019 resolvedType, callingPid, callingUid, userId); 13020 Binder.restoreCallingIdentity(origId); 13021 return res; 13022 } 13023 } 13024 13025 ComponentName startServiceInPackage(int uid, 13026 Intent service, String resolvedType, int userId) { 13027 synchronized(this) { 13028 if (DEBUG_SERVICE) 13029 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13030 final long origId = Binder.clearCallingIdentity(); 13031 ComponentName res = mServices.startServiceLocked(null, service, 13032 resolvedType, -1, uid, userId); 13033 Binder.restoreCallingIdentity(origId); 13034 return res; 13035 } 13036 } 13037 13038 public int stopService(IApplicationThread caller, Intent service, 13039 String resolvedType, int userId) { 13040 enforceNotIsolatedCaller("stopService"); 13041 // Refuse possible leaked file descriptors 13042 if (service != null && service.hasFileDescriptors() == true) { 13043 throw new IllegalArgumentException("File descriptors passed in Intent"); 13044 } 13045 13046 synchronized(this) { 13047 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13048 } 13049 } 13050 13051 public IBinder peekService(Intent service, String resolvedType) { 13052 enforceNotIsolatedCaller("peekService"); 13053 // Refuse possible leaked file descriptors 13054 if (service != null && service.hasFileDescriptors() == true) { 13055 throw new IllegalArgumentException("File descriptors passed in Intent"); 13056 } 13057 synchronized(this) { 13058 return mServices.peekServiceLocked(service, resolvedType); 13059 } 13060 } 13061 13062 public boolean stopServiceToken(ComponentName className, IBinder token, 13063 int startId) { 13064 synchronized(this) { 13065 return mServices.stopServiceTokenLocked(className, token, startId); 13066 } 13067 } 13068 13069 public void setServiceForeground(ComponentName className, IBinder token, 13070 int id, Notification notification, boolean removeNotification) { 13071 synchronized(this) { 13072 mServices.setServiceForegroundLocked(className, token, id, notification, 13073 removeNotification); 13074 } 13075 } 13076 13077 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13078 boolean requireFull, String name, String callerPackage) { 13079 final int callingUserId = UserHandle.getUserId(callingUid); 13080 if (callingUserId != userId) { 13081 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13082 if ((requireFull || checkComponentPermission( 13083 android.Manifest.permission.INTERACT_ACROSS_USERS, 13084 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 13085 && checkComponentPermission( 13086 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 13087 callingPid, callingUid, -1, true) 13088 != PackageManager.PERMISSION_GRANTED) { 13089 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13090 // In this case, they would like to just execute as their 13091 // owner user instead of failing. 13092 userId = callingUserId; 13093 } else { 13094 StringBuilder builder = new StringBuilder(128); 13095 builder.append("Permission Denial: "); 13096 builder.append(name); 13097 if (callerPackage != null) { 13098 builder.append(" from "); 13099 builder.append(callerPackage); 13100 } 13101 builder.append(" asks to run as user "); 13102 builder.append(userId); 13103 builder.append(" but is calling from user "); 13104 builder.append(UserHandle.getUserId(callingUid)); 13105 builder.append("; this requires "); 13106 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 13107 if (!requireFull) { 13108 builder.append(" or "); 13109 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13110 } 13111 String msg = builder.toString(); 13112 Slog.w(TAG, msg); 13113 throw new SecurityException(msg); 13114 } 13115 } 13116 } 13117 if (userId == UserHandle.USER_CURRENT 13118 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13119 // Note that we may be accessing this outside of a lock... 13120 // shouldn't be a big deal, if this is being called outside 13121 // of a locked context there is intrinsically a race with 13122 // the value the caller will receive and someone else changing it. 13123 userId = mCurrentUserId; 13124 } 13125 if (!allowAll && userId < 0) { 13126 throw new IllegalArgumentException( 13127 "Call does not support special user #" + userId); 13128 } 13129 } 13130 return userId; 13131 } 13132 13133 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13134 String className, int flags) { 13135 boolean result = false; 13136 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13137 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 13138 if (ActivityManager.checkUidPermission( 13139 android.Manifest.permission.INTERACT_ACROSS_USERS, 13140 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13141 ComponentName comp = new ComponentName(aInfo.packageName, className); 13142 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13143 + " requests FLAG_SINGLE_USER, but app does not hold " 13144 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13145 Slog.w(TAG, msg); 13146 throw new SecurityException(msg); 13147 } 13148 result = true; 13149 } 13150 } else if (componentProcessName == aInfo.packageName) { 13151 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13152 } else if ("system".equals(componentProcessName)) { 13153 result = true; 13154 } 13155 if (DEBUG_MU) { 13156 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13157 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13158 } 13159 return result; 13160 } 13161 13162 public int bindService(IApplicationThread caller, IBinder token, 13163 Intent service, String resolvedType, 13164 IServiceConnection connection, int flags, int userId) { 13165 enforceNotIsolatedCaller("bindService"); 13166 // Refuse possible leaked file descriptors 13167 if (service != null && service.hasFileDescriptors() == true) { 13168 throw new IllegalArgumentException("File descriptors passed in Intent"); 13169 } 13170 13171 synchronized(this) { 13172 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13173 connection, flags, userId); 13174 } 13175 } 13176 13177 public boolean unbindService(IServiceConnection connection) { 13178 synchronized (this) { 13179 return mServices.unbindServiceLocked(connection); 13180 } 13181 } 13182 13183 public void publishService(IBinder token, Intent intent, IBinder service) { 13184 // Refuse possible leaked file descriptors 13185 if (intent != null && intent.hasFileDescriptors() == true) { 13186 throw new IllegalArgumentException("File descriptors passed in Intent"); 13187 } 13188 13189 synchronized(this) { 13190 if (!(token instanceof ServiceRecord)) { 13191 throw new IllegalArgumentException("Invalid service token"); 13192 } 13193 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13194 } 13195 } 13196 13197 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13198 // Refuse possible leaked file descriptors 13199 if (intent != null && intent.hasFileDescriptors() == true) { 13200 throw new IllegalArgumentException("File descriptors passed in Intent"); 13201 } 13202 13203 synchronized(this) { 13204 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13205 } 13206 } 13207 13208 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13209 synchronized(this) { 13210 if (!(token instanceof ServiceRecord)) { 13211 throw new IllegalArgumentException("Invalid service token"); 13212 } 13213 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13214 } 13215 } 13216 13217 // ========================================================= 13218 // BACKUP AND RESTORE 13219 // ========================================================= 13220 13221 // Cause the target app to be launched if necessary and its backup agent 13222 // instantiated. The backup agent will invoke backupAgentCreated() on the 13223 // activity manager to announce its creation. 13224 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13225 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13226 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13227 13228 synchronized(this) { 13229 // !!! TODO: currently no check here that we're already bound 13230 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13231 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13232 synchronized (stats) { 13233 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13234 } 13235 13236 // Backup agent is now in use, its package can't be stopped. 13237 try { 13238 AppGlobals.getPackageManager().setPackageStoppedState( 13239 app.packageName, false, UserHandle.getUserId(app.uid)); 13240 } catch (RemoteException e) { 13241 } catch (IllegalArgumentException e) { 13242 Slog.w(TAG, "Failed trying to unstop package " 13243 + app.packageName + ": " + e); 13244 } 13245 13246 BackupRecord r = new BackupRecord(ss, app, backupMode); 13247 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13248 ? new ComponentName(app.packageName, app.backupAgentName) 13249 : new ComponentName("android", "FullBackupAgent"); 13250 // startProcessLocked() returns existing proc's record if it's already running 13251 ProcessRecord proc = startProcessLocked(app.processName, app, 13252 false, 0, "backup", hostingName, false, false, false); 13253 if (proc == null) { 13254 Slog.e(TAG, "Unable to start backup agent process " + r); 13255 return false; 13256 } 13257 13258 r.app = proc; 13259 mBackupTarget = r; 13260 mBackupAppName = app.packageName; 13261 13262 // Try not to kill the process during backup 13263 updateOomAdjLocked(proc); 13264 13265 // If the process is already attached, schedule the creation of the backup agent now. 13266 // If it is not yet live, this will be done when it attaches to the framework. 13267 if (proc.thread != null) { 13268 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13269 try { 13270 proc.thread.scheduleCreateBackupAgent(app, 13271 compatibilityInfoForPackageLocked(app), backupMode); 13272 } catch (RemoteException e) { 13273 // Will time out on the backup manager side 13274 } 13275 } else { 13276 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13277 } 13278 // Invariants: at this point, the target app process exists and the application 13279 // is either already running or in the process of coming up. mBackupTarget and 13280 // mBackupAppName describe the app, so that when it binds back to the AM we 13281 // know that it's scheduled for a backup-agent operation. 13282 } 13283 13284 return true; 13285 } 13286 13287 @Override 13288 public void clearPendingBackup() { 13289 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13290 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13291 13292 synchronized (this) { 13293 mBackupTarget = null; 13294 mBackupAppName = null; 13295 } 13296 } 13297 13298 // A backup agent has just come up 13299 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13300 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13301 + " = " + agent); 13302 13303 synchronized(this) { 13304 if (!agentPackageName.equals(mBackupAppName)) { 13305 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13306 return; 13307 } 13308 } 13309 13310 long oldIdent = Binder.clearCallingIdentity(); 13311 try { 13312 IBackupManager bm = IBackupManager.Stub.asInterface( 13313 ServiceManager.getService(Context.BACKUP_SERVICE)); 13314 bm.agentConnected(agentPackageName, agent); 13315 } catch (RemoteException e) { 13316 // can't happen; the backup manager service is local 13317 } catch (Exception e) { 13318 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13319 e.printStackTrace(); 13320 } finally { 13321 Binder.restoreCallingIdentity(oldIdent); 13322 } 13323 } 13324 13325 // done with this agent 13326 public void unbindBackupAgent(ApplicationInfo appInfo) { 13327 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13328 if (appInfo == null) { 13329 Slog.w(TAG, "unbind backup agent for null app"); 13330 return; 13331 } 13332 13333 synchronized(this) { 13334 try { 13335 if (mBackupAppName == null) { 13336 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13337 return; 13338 } 13339 13340 if (!mBackupAppName.equals(appInfo.packageName)) { 13341 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13342 return; 13343 } 13344 13345 // Not backing this app up any more; reset its OOM adjustment 13346 final ProcessRecord proc = mBackupTarget.app; 13347 updateOomAdjLocked(proc); 13348 13349 // If the app crashed during backup, 'thread' will be null here 13350 if (proc.thread != null) { 13351 try { 13352 proc.thread.scheduleDestroyBackupAgent(appInfo, 13353 compatibilityInfoForPackageLocked(appInfo)); 13354 } catch (Exception e) { 13355 Slog.e(TAG, "Exception when unbinding backup agent:"); 13356 e.printStackTrace(); 13357 } 13358 } 13359 } finally { 13360 mBackupTarget = null; 13361 mBackupAppName = null; 13362 } 13363 } 13364 } 13365 // ========================================================= 13366 // BROADCASTS 13367 // ========================================================= 13368 13369 private final List getStickiesLocked(String action, IntentFilter filter, 13370 List cur, int userId) { 13371 final ContentResolver resolver = mContext.getContentResolver(); 13372 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13373 if (stickies == null) { 13374 return cur; 13375 } 13376 final ArrayList<Intent> list = stickies.get(action); 13377 if (list == null) { 13378 return cur; 13379 } 13380 int N = list.size(); 13381 for (int i=0; i<N; i++) { 13382 Intent intent = list.get(i); 13383 if (filter.match(resolver, intent, true, TAG) >= 0) { 13384 if (cur == null) { 13385 cur = new ArrayList<Intent>(); 13386 } 13387 cur.add(intent); 13388 } 13389 } 13390 return cur; 13391 } 13392 13393 boolean isPendingBroadcastProcessLocked(int pid) { 13394 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13395 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13396 } 13397 13398 void skipPendingBroadcastLocked(int pid) { 13399 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13400 for (BroadcastQueue queue : mBroadcastQueues) { 13401 queue.skipPendingBroadcastLocked(pid); 13402 } 13403 } 13404 13405 // The app just attached; send any pending broadcasts that it should receive 13406 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13407 boolean didSomething = false; 13408 for (BroadcastQueue queue : mBroadcastQueues) { 13409 didSomething |= queue.sendPendingBroadcastsLocked(app); 13410 } 13411 return didSomething; 13412 } 13413 13414 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13415 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13416 enforceNotIsolatedCaller("registerReceiver"); 13417 int callingUid; 13418 int callingPid; 13419 synchronized(this) { 13420 ProcessRecord callerApp = null; 13421 if (caller != null) { 13422 callerApp = getRecordForAppLocked(caller); 13423 if (callerApp == null) { 13424 throw new SecurityException( 13425 "Unable to find app for caller " + caller 13426 + " (pid=" + Binder.getCallingPid() 13427 + ") when registering receiver " + receiver); 13428 } 13429 if (callerApp.info.uid != Process.SYSTEM_UID && 13430 !callerApp.pkgList.containsKey(callerPackage) && 13431 !"android".equals(callerPackage)) { 13432 throw new SecurityException("Given caller package " + callerPackage 13433 + " is not running in process " + callerApp); 13434 } 13435 callingUid = callerApp.info.uid; 13436 callingPid = callerApp.pid; 13437 } else { 13438 callerPackage = null; 13439 callingUid = Binder.getCallingUid(); 13440 callingPid = Binder.getCallingPid(); 13441 } 13442 13443 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13444 true, true, "registerReceiver", callerPackage); 13445 13446 List allSticky = null; 13447 13448 // Look for any matching sticky broadcasts... 13449 Iterator actions = filter.actionsIterator(); 13450 if (actions != null) { 13451 while (actions.hasNext()) { 13452 String action = (String)actions.next(); 13453 allSticky = getStickiesLocked(action, filter, allSticky, 13454 UserHandle.USER_ALL); 13455 allSticky = getStickiesLocked(action, filter, allSticky, 13456 UserHandle.getUserId(callingUid)); 13457 } 13458 } else { 13459 allSticky = getStickiesLocked(null, filter, allSticky, 13460 UserHandle.USER_ALL); 13461 allSticky = getStickiesLocked(null, filter, allSticky, 13462 UserHandle.getUserId(callingUid)); 13463 } 13464 13465 // The first sticky in the list is returned directly back to 13466 // the client. 13467 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13468 13469 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13470 + ": " + sticky); 13471 13472 if (receiver == null) { 13473 return sticky; 13474 } 13475 13476 ReceiverList rl 13477 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13478 if (rl == null) { 13479 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13480 userId, receiver); 13481 if (rl.app != null) { 13482 rl.app.receivers.add(rl); 13483 } else { 13484 try { 13485 receiver.asBinder().linkToDeath(rl, 0); 13486 } catch (RemoteException e) { 13487 return sticky; 13488 } 13489 rl.linkedToDeath = true; 13490 } 13491 mRegisteredReceivers.put(receiver.asBinder(), rl); 13492 } else if (rl.uid != callingUid) { 13493 throw new IllegalArgumentException( 13494 "Receiver requested to register for uid " + callingUid 13495 + " was previously registered for uid " + rl.uid); 13496 } else if (rl.pid != callingPid) { 13497 throw new IllegalArgumentException( 13498 "Receiver requested to register for pid " + callingPid 13499 + " was previously registered for pid " + rl.pid); 13500 } else if (rl.userId != userId) { 13501 throw new IllegalArgumentException( 13502 "Receiver requested to register for user " + userId 13503 + " was previously registered for user " + rl.userId); 13504 } 13505 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13506 permission, callingUid, userId); 13507 rl.add(bf); 13508 if (!bf.debugCheck()) { 13509 Slog.w(TAG, "==> For Dynamic broadast"); 13510 } 13511 mReceiverResolver.addFilter(bf); 13512 13513 // Enqueue broadcasts for all existing stickies that match 13514 // this filter. 13515 if (allSticky != null) { 13516 ArrayList receivers = new ArrayList(); 13517 receivers.add(bf); 13518 13519 int N = allSticky.size(); 13520 for (int i=0; i<N; i++) { 13521 Intent intent = (Intent)allSticky.get(i); 13522 BroadcastQueue queue = broadcastQueueForIntent(intent); 13523 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13524 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13525 null, null, false, true, true, -1); 13526 queue.enqueueParallelBroadcastLocked(r); 13527 queue.scheduleBroadcastsLocked(); 13528 } 13529 } 13530 13531 return sticky; 13532 } 13533 } 13534 13535 public void unregisterReceiver(IIntentReceiver receiver) { 13536 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13537 13538 final long origId = Binder.clearCallingIdentity(); 13539 try { 13540 boolean doTrim = false; 13541 13542 synchronized(this) { 13543 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13544 if (rl != null) { 13545 if (rl.curBroadcast != null) { 13546 BroadcastRecord r = rl.curBroadcast; 13547 final boolean doNext = finishReceiverLocked( 13548 receiver.asBinder(), r.resultCode, r.resultData, 13549 r.resultExtras, r.resultAbort); 13550 if (doNext) { 13551 doTrim = true; 13552 r.queue.processNextBroadcast(false); 13553 } 13554 } 13555 13556 if (rl.app != null) { 13557 rl.app.receivers.remove(rl); 13558 } 13559 removeReceiverLocked(rl); 13560 if (rl.linkedToDeath) { 13561 rl.linkedToDeath = false; 13562 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13563 } 13564 } 13565 } 13566 13567 // If we actually concluded any broadcasts, we might now be able 13568 // to trim the recipients' apps from our working set 13569 if (doTrim) { 13570 trimApplications(); 13571 return; 13572 } 13573 13574 } finally { 13575 Binder.restoreCallingIdentity(origId); 13576 } 13577 } 13578 13579 void removeReceiverLocked(ReceiverList rl) { 13580 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13581 int N = rl.size(); 13582 for (int i=0; i<N; i++) { 13583 mReceiverResolver.removeFilter(rl.get(i)); 13584 } 13585 } 13586 13587 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13588 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13589 ProcessRecord r = mLruProcesses.get(i); 13590 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13591 try { 13592 r.thread.dispatchPackageBroadcast(cmd, packages); 13593 } catch (RemoteException ex) { 13594 } 13595 } 13596 } 13597 } 13598 13599 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13600 int[] users) { 13601 List<ResolveInfo> receivers = null; 13602 try { 13603 HashSet<ComponentName> singleUserReceivers = null; 13604 boolean scannedFirstReceivers = false; 13605 for (int user : users) { 13606 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13607 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13608 if (user != 0 && newReceivers != null) { 13609 // If this is not the primary user, we need to check for 13610 // any receivers that should be filtered out. 13611 for (int i=0; i<newReceivers.size(); i++) { 13612 ResolveInfo ri = newReceivers.get(i); 13613 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13614 newReceivers.remove(i); 13615 i--; 13616 } 13617 } 13618 } 13619 if (newReceivers != null && newReceivers.size() == 0) { 13620 newReceivers = null; 13621 } 13622 if (receivers == null) { 13623 receivers = newReceivers; 13624 } else if (newReceivers != null) { 13625 // We need to concatenate the additional receivers 13626 // found with what we have do far. This would be easy, 13627 // but we also need to de-dup any receivers that are 13628 // singleUser. 13629 if (!scannedFirstReceivers) { 13630 // Collect any single user receivers we had already retrieved. 13631 scannedFirstReceivers = true; 13632 for (int i=0; i<receivers.size(); i++) { 13633 ResolveInfo ri = receivers.get(i); 13634 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13635 ComponentName cn = new ComponentName( 13636 ri.activityInfo.packageName, ri.activityInfo.name); 13637 if (singleUserReceivers == null) { 13638 singleUserReceivers = new HashSet<ComponentName>(); 13639 } 13640 singleUserReceivers.add(cn); 13641 } 13642 } 13643 } 13644 // Add the new results to the existing results, tracking 13645 // and de-dupping single user receivers. 13646 for (int i=0; i<newReceivers.size(); i++) { 13647 ResolveInfo ri = newReceivers.get(i); 13648 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13649 ComponentName cn = new ComponentName( 13650 ri.activityInfo.packageName, ri.activityInfo.name); 13651 if (singleUserReceivers == null) { 13652 singleUserReceivers = new HashSet<ComponentName>(); 13653 } 13654 if (!singleUserReceivers.contains(cn)) { 13655 singleUserReceivers.add(cn); 13656 receivers.add(ri); 13657 } 13658 } else { 13659 receivers.add(ri); 13660 } 13661 } 13662 } 13663 } 13664 } catch (RemoteException ex) { 13665 // pm is in same process, this will never happen. 13666 } 13667 return receivers; 13668 } 13669 13670 private final int broadcastIntentLocked(ProcessRecord callerApp, 13671 String callerPackage, Intent intent, String resolvedType, 13672 IIntentReceiver resultTo, int resultCode, String resultData, 13673 Bundle map, String requiredPermission, int appOp, 13674 boolean ordered, boolean sticky, int callingPid, int callingUid, 13675 int userId) { 13676 intent = new Intent(intent); 13677 13678 // By default broadcasts do not go to stopped apps. 13679 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13680 13681 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13682 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13683 + " ordered=" + ordered + " userid=" + userId); 13684 if ((resultTo != null) && !ordered) { 13685 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13686 } 13687 13688 userId = handleIncomingUser(callingPid, callingUid, userId, 13689 true, false, "broadcast", callerPackage); 13690 13691 // Make sure that the user who is receiving this broadcast is started. 13692 // If not, we will just skip it. 13693 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13694 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13695 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13696 Slog.w(TAG, "Skipping broadcast of " + intent 13697 + ": user " + userId + " is stopped"); 13698 return ActivityManager.BROADCAST_SUCCESS; 13699 } 13700 } 13701 13702 /* 13703 * Prevent non-system code (defined here to be non-persistent 13704 * processes) from sending protected broadcasts. 13705 */ 13706 int callingAppId = UserHandle.getAppId(callingUid); 13707 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13708 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13709 callingUid == 0) { 13710 // Always okay. 13711 } else if (callerApp == null || !callerApp.persistent) { 13712 try { 13713 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13714 intent.getAction())) { 13715 String msg = "Permission Denial: not allowed to send broadcast " 13716 + intent.getAction() + " from pid=" 13717 + callingPid + ", uid=" + callingUid; 13718 Slog.w(TAG, msg); 13719 throw new SecurityException(msg); 13720 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13721 // Special case for compatibility: we don't want apps to send this, 13722 // but historically it has not been protected and apps may be using it 13723 // to poke their own app widget. So, instead of making it protected, 13724 // just limit it to the caller. 13725 if (callerApp == null) { 13726 String msg = "Permission Denial: not allowed to send broadcast " 13727 + intent.getAction() + " from unknown caller."; 13728 Slog.w(TAG, msg); 13729 throw new SecurityException(msg); 13730 } else if (intent.getComponent() != null) { 13731 // They are good enough to send to an explicit component... verify 13732 // it is being sent to the calling app. 13733 if (!intent.getComponent().getPackageName().equals( 13734 callerApp.info.packageName)) { 13735 String msg = "Permission Denial: not allowed to send broadcast " 13736 + intent.getAction() + " to " 13737 + intent.getComponent().getPackageName() + " from " 13738 + callerApp.info.packageName; 13739 Slog.w(TAG, msg); 13740 throw new SecurityException(msg); 13741 } 13742 } else { 13743 // Limit broadcast to their own package. 13744 intent.setPackage(callerApp.info.packageName); 13745 } 13746 } 13747 } catch (RemoteException e) { 13748 Slog.w(TAG, "Remote exception", e); 13749 return ActivityManager.BROADCAST_SUCCESS; 13750 } 13751 } 13752 13753 // Handle special intents: if this broadcast is from the package 13754 // manager about a package being removed, we need to remove all of 13755 // its activities from the history stack. 13756 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13757 intent.getAction()); 13758 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13759 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13760 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13761 || uidRemoved) { 13762 if (checkComponentPermission( 13763 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13764 callingPid, callingUid, -1, true) 13765 == PackageManager.PERMISSION_GRANTED) { 13766 if (uidRemoved) { 13767 final Bundle intentExtras = intent.getExtras(); 13768 final int uid = intentExtras != null 13769 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13770 if (uid >= 0) { 13771 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13772 synchronized (bs) { 13773 bs.removeUidStatsLocked(uid); 13774 } 13775 mAppOpsService.uidRemoved(uid); 13776 } 13777 } else { 13778 // If resources are unavailable just force stop all 13779 // those packages and flush the attribute cache as well. 13780 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13781 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13782 if (list != null && (list.length > 0)) { 13783 for (String pkg : list) { 13784 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13785 "storage unmount"); 13786 } 13787 sendPackageBroadcastLocked( 13788 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13789 } 13790 } else { 13791 Uri data = intent.getData(); 13792 String ssp; 13793 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13794 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13795 intent.getAction()); 13796 boolean fullUninstall = removed && 13797 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13798 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13799 forceStopPackageLocked(ssp, UserHandle.getAppId( 13800 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13801 false, fullUninstall, userId, 13802 removed ? "pkg removed" : "pkg changed"); 13803 } 13804 if (removed) { 13805 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13806 new String[] {ssp}, userId); 13807 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13808 mAppOpsService.packageRemoved( 13809 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13810 13811 // Remove all permissions granted from/to this package 13812 removeUriPermissionsForPackageLocked(ssp, userId, true); 13813 } 13814 } 13815 } 13816 } 13817 } 13818 } else { 13819 String msg = "Permission Denial: " + intent.getAction() 13820 + " broadcast from " + callerPackage + " (pid=" + callingPid 13821 + ", uid=" + callingUid + ")" 13822 + " requires " 13823 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13824 Slog.w(TAG, msg); 13825 throw new SecurityException(msg); 13826 } 13827 13828 // Special case for adding a package: by default turn on compatibility 13829 // mode. 13830 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13831 Uri data = intent.getData(); 13832 String ssp; 13833 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13834 mCompatModePackages.handlePackageAddedLocked(ssp, 13835 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13836 } 13837 } 13838 13839 /* 13840 * If this is the time zone changed action, queue up a message that will reset the timezone 13841 * of all currently running processes. This message will get queued up before the broadcast 13842 * happens. 13843 */ 13844 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13845 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13846 } 13847 13848 /* 13849 * If the user set the time, let all running processes know. 13850 */ 13851 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13852 final int is24Hour = intent.getBooleanExtra( 13853 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13854 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13855 } 13856 13857 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13858 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13859 } 13860 13861 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13862 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13863 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13864 } 13865 13866 // Add to the sticky list if requested. 13867 if (sticky) { 13868 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13869 callingPid, callingUid) 13870 != PackageManager.PERMISSION_GRANTED) { 13871 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13872 + callingPid + ", uid=" + callingUid 13873 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13874 Slog.w(TAG, msg); 13875 throw new SecurityException(msg); 13876 } 13877 if (requiredPermission != null) { 13878 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13879 + " and enforce permission " + requiredPermission); 13880 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13881 } 13882 if (intent.getComponent() != null) { 13883 throw new SecurityException( 13884 "Sticky broadcasts can't target a specific component"); 13885 } 13886 // We use userId directly here, since the "all" target is maintained 13887 // as a separate set of sticky broadcasts. 13888 if (userId != UserHandle.USER_ALL) { 13889 // But first, if this is not a broadcast to all users, then 13890 // make sure it doesn't conflict with an existing broadcast to 13891 // all users. 13892 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13893 UserHandle.USER_ALL); 13894 if (stickies != null) { 13895 ArrayList<Intent> list = stickies.get(intent.getAction()); 13896 if (list != null) { 13897 int N = list.size(); 13898 int i; 13899 for (i=0; i<N; i++) { 13900 if (intent.filterEquals(list.get(i))) { 13901 throw new IllegalArgumentException( 13902 "Sticky broadcast " + intent + " for user " 13903 + userId + " conflicts with existing global broadcast"); 13904 } 13905 } 13906 } 13907 } 13908 } 13909 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13910 if (stickies == null) { 13911 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13912 mStickyBroadcasts.put(userId, stickies); 13913 } 13914 ArrayList<Intent> list = stickies.get(intent.getAction()); 13915 if (list == null) { 13916 list = new ArrayList<Intent>(); 13917 stickies.put(intent.getAction(), list); 13918 } 13919 int N = list.size(); 13920 int i; 13921 for (i=0; i<N; i++) { 13922 if (intent.filterEquals(list.get(i))) { 13923 // This sticky already exists, replace it. 13924 list.set(i, new Intent(intent)); 13925 break; 13926 } 13927 } 13928 if (i >= N) { 13929 list.add(new Intent(intent)); 13930 } 13931 } 13932 13933 int[] users; 13934 if (userId == UserHandle.USER_ALL) { 13935 // Caller wants broadcast to go to all started users. 13936 users = mStartedUserArray; 13937 } else { 13938 // Caller wants broadcast to go to one specific user. 13939 users = new int[] {userId}; 13940 } 13941 13942 // Figure out who all will receive this broadcast. 13943 List receivers = null; 13944 List<BroadcastFilter> registeredReceivers = null; 13945 // Need to resolve the intent to interested receivers... 13946 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13947 == 0) { 13948 receivers = collectReceiverComponents(intent, resolvedType, users); 13949 } 13950 if (intent.getComponent() == null) { 13951 registeredReceivers = mReceiverResolver.queryIntent(intent, 13952 resolvedType, false, userId); 13953 } 13954 13955 final boolean replacePending = 13956 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13957 13958 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13959 + " replacePending=" + replacePending); 13960 13961 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13962 if (!ordered && NR > 0) { 13963 // If we are not serializing this broadcast, then send the 13964 // registered receivers separately so they don't wait for the 13965 // components to be launched. 13966 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13967 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13968 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13969 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13970 ordered, sticky, false, userId); 13971 if (DEBUG_BROADCAST) Slog.v( 13972 TAG, "Enqueueing parallel broadcast " + r); 13973 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13974 if (!replaced) { 13975 queue.enqueueParallelBroadcastLocked(r); 13976 queue.scheduleBroadcastsLocked(); 13977 } 13978 registeredReceivers = null; 13979 NR = 0; 13980 } 13981 13982 // Merge into one list. 13983 int ir = 0; 13984 if (receivers != null) { 13985 // A special case for PACKAGE_ADDED: do not allow the package 13986 // being added to see this broadcast. This prevents them from 13987 // using this as a back door to get run as soon as they are 13988 // installed. Maybe in the future we want to have a special install 13989 // broadcast or such for apps, but we'd like to deliberately make 13990 // this decision. 13991 String skipPackages[] = null; 13992 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13993 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13994 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13995 Uri data = intent.getData(); 13996 if (data != null) { 13997 String pkgName = data.getSchemeSpecificPart(); 13998 if (pkgName != null) { 13999 skipPackages = new String[] { pkgName }; 14000 } 14001 } 14002 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 14003 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14004 } 14005 if (skipPackages != null && (skipPackages.length > 0)) { 14006 for (String skipPackage : skipPackages) { 14007 if (skipPackage != null) { 14008 int NT = receivers.size(); 14009 for (int it=0; it<NT; it++) { 14010 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14011 if (curt.activityInfo.packageName.equals(skipPackage)) { 14012 receivers.remove(it); 14013 it--; 14014 NT--; 14015 } 14016 } 14017 } 14018 } 14019 } 14020 14021 int NT = receivers != null ? receivers.size() : 0; 14022 int it = 0; 14023 ResolveInfo curt = null; 14024 BroadcastFilter curr = null; 14025 while (it < NT && ir < NR) { 14026 if (curt == null) { 14027 curt = (ResolveInfo)receivers.get(it); 14028 } 14029 if (curr == null) { 14030 curr = registeredReceivers.get(ir); 14031 } 14032 if (curr.getPriority() >= curt.priority) { 14033 // Insert this broadcast record into the final list. 14034 receivers.add(it, curr); 14035 ir++; 14036 curr = null; 14037 it++; 14038 NT++; 14039 } else { 14040 // Skip to the next ResolveInfo in the final list. 14041 it++; 14042 curt = null; 14043 } 14044 } 14045 } 14046 while (ir < NR) { 14047 if (receivers == null) { 14048 receivers = new ArrayList(); 14049 } 14050 receivers.add(registeredReceivers.get(ir)); 14051 ir++; 14052 } 14053 14054 if ((receivers != null && receivers.size() > 0) 14055 || resultTo != null) { 14056 BroadcastQueue queue = broadcastQueueForIntent(intent); 14057 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14058 callerPackage, callingPid, callingUid, resolvedType, 14059 requiredPermission, appOp, receivers, resultTo, resultCode, 14060 resultData, map, ordered, sticky, false, userId); 14061 if (DEBUG_BROADCAST) Slog.v( 14062 TAG, "Enqueueing ordered broadcast " + r 14063 + ": prev had " + queue.mOrderedBroadcasts.size()); 14064 if (DEBUG_BROADCAST) { 14065 int seq = r.intent.getIntExtra("seq", -1); 14066 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14067 } 14068 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14069 if (!replaced) { 14070 queue.enqueueOrderedBroadcastLocked(r); 14071 queue.scheduleBroadcastsLocked(); 14072 } 14073 } 14074 14075 return ActivityManager.BROADCAST_SUCCESS; 14076 } 14077 14078 final Intent verifyBroadcastLocked(Intent intent) { 14079 // Refuse possible leaked file descriptors 14080 if (intent != null && intent.hasFileDescriptors() == true) { 14081 throw new IllegalArgumentException("File descriptors passed in Intent"); 14082 } 14083 14084 int flags = intent.getFlags(); 14085 14086 if (!mProcessesReady) { 14087 // if the caller really truly claims to know what they're doing, go 14088 // ahead and allow the broadcast without launching any receivers 14089 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14090 intent = new Intent(intent); 14091 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14092 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14093 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14094 + " before boot completion"); 14095 throw new IllegalStateException("Cannot broadcast before boot completed"); 14096 } 14097 } 14098 14099 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14100 throw new IllegalArgumentException( 14101 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14102 } 14103 14104 return intent; 14105 } 14106 14107 public final int broadcastIntent(IApplicationThread caller, 14108 Intent intent, String resolvedType, IIntentReceiver resultTo, 14109 int resultCode, String resultData, Bundle map, 14110 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14111 enforceNotIsolatedCaller("broadcastIntent"); 14112 synchronized(this) { 14113 intent = verifyBroadcastLocked(intent); 14114 14115 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14116 final int callingPid = Binder.getCallingPid(); 14117 final int callingUid = Binder.getCallingUid(); 14118 final long origId = Binder.clearCallingIdentity(); 14119 int res = broadcastIntentLocked(callerApp, 14120 callerApp != null ? callerApp.info.packageName : null, 14121 intent, resolvedType, resultTo, 14122 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14123 callingPid, callingUid, userId); 14124 Binder.restoreCallingIdentity(origId); 14125 return res; 14126 } 14127 } 14128 14129 int broadcastIntentInPackage(String packageName, int uid, 14130 Intent intent, String resolvedType, IIntentReceiver resultTo, 14131 int resultCode, String resultData, Bundle map, 14132 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14133 synchronized(this) { 14134 intent = verifyBroadcastLocked(intent); 14135 14136 final long origId = Binder.clearCallingIdentity(); 14137 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14138 resultTo, resultCode, resultData, map, requiredPermission, 14139 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14140 Binder.restoreCallingIdentity(origId); 14141 return res; 14142 } 14143 } 14144 14145 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14146 // Refuse possible leaked file descriptors 14147 if (intent != null && intent.hasFileDescriptors() == true) { 14148 throw new IllegalArgumentException("File descriptors passed in Intent"); 14149 } 14150 14151 userId = handleIncomingUser(Binder.getCallingPid(), 14152 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14153 14154 synchronized(this) { 14155 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14156 != PackageManager.PERMISSION_GRANTED) { 14157 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14158 + Binder.getCallingPid() 14159 + ", uid=" + Binder.getCallingUid() 14160 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14161 Slog.w(TAG, msg); 14162 throw new SecurityException(msg); 14163 } 14164 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14165 if (stickies != null) { 14166 ArrayList<Intent> list = stickies.get(intent.getAction()); 14167 if (list != null) { 14168 int N = list.size(); 14169 int i; 14170 for (i=0; i<N; i++) { 14171 if (intent.filterEquals(list.get(i))) { 14172 list.remove(i); 14173 break; 14174 } 14175 } 14176 if (list.size() <= 0) { 14177 stickies.remove(intent.getAction()); 14178 } 14179 } 14180 if (stickies.size() <= 0) { 14181 mStickyBroadcasts.remove(userId); 14182 } 14183 } 14184 } 14185 } 14186 14187 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14188 String resultData, Bundle resultExtras, boolean resultAbort) { 14189 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14190 if (r == null) { 14191 Slog.w(TAG, "finishReceiver called but not found on queue"); 14192 return false; 14193 } 14194 14195 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14196 } 14197 14198 void backgroundServicesFinishedLocked(int userId) { 14199 for (BroadcastQueue queue : mBroadcastQueues) { 14200 queue.backgroundServicesFinishedLocked(userId); 14201 } 14202 } 14203 14204 public void finishReceiver(IBinder who, int resultCode, String resultData, 14205 Bundle resultExtras, boolean resultAbort) { 14206 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14207 14208 // Refuse possible leaked file descriptors 14209 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14210 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14211 } 14212 14213 final long origId = Binder.clearCallingIdentity(); 14214 try { 14215 boolean doNext = false; 14216 BroadcastRecord r; 14217 14218 synchronized(this) { 14219 r = broadcastRecordForReceiverLocked(who); 14220 if (r != null) { 14221 doNext = r.queue.finishReceiverLocked(r, resultCode, 14222 resultData, resultExtras, resultAbort, true); 14223 } 14224 } 14225 14226 if (doNext) { 14227 r.queue.processNextBroadcast(false); 14228 } 14229 trimApplications(); 14230 } finally { 14231 Binder.restoreCallingIdentity(origId); 14232 } 14233 } 14234 14235 // ========================================================= 14236 // INSTRUMENTATION 14237 // ========================================================= 14238 14239 public boolean startInstrumentation(ComponentName className, 14240 String profileFile, int flags, Bundle arguments, 14241 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14242 int userId) { 14243 enforceNotIsolatedCaller("startInstrumentation"); 14244 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14245 userId, false, true, "startInstrumentation", null); 14246 // Refuse possible leaked file descriptors 14247 if (arguments != null && arguments.hasFileDescriptors()) { 14248 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14249 } 14250 14251 synchronized(this) { 14252 InstrumentationInfo ii = null; 14253 ApplicationInfo ai = null; 14254 try { 14255 ii = mContext.getPackageManager().getInstrumentationInfo( 14256 className, STOCK_PM_FLAGS); 14257 ai = AppGlobals.getPackageManager().getApplicationInfo( 14258 ii.targetPackage, STOCK_PM_FLAGS, userId); 14259 } catch (PackageManager.NameNotFoundException e) { 14260 } catch (RemoteException e) { 14261 } 14262 if (ii == null) { 14263 reportStartInstrumentationFailure(watcher, className, 14264 "Unable to find instrumentation info for: " + className); 14265 return false; 14266 } 14267 if (ai == null) { 14268 reportStartInstrumentationFailure(watcher, className, 14269 "Unable to find instrumentation target package: " + ii.targetPackage); 14270 return false; 14271 } 14272 14273 int match = mContext.getPackageManager().checkSignatures( 14274 ii.targetPackage, ii.packageName); 14275 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14276 String msg = "Permission Denial: starting instrumentation " 14277 + className + " from pid=" 14278 + Binder.getCallingPid() 14279 + ", uid=" + Binder.getCallingPid() 14280 + " not allowed because package " + ii.packageName 14281 + " does not have a signature matching the target " 14282 + ii.targetPackage; 14283 reportStartInstrumentationFailure(watcher, className, msg); 14284 throw new SecurityException(msg); 14285 } 14286 14287 final long origId = Binder.clearCallingIdentity(); 14288 // Instrumentation can kill and relaunch even persistent processes 14289 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14290 "start instr"); 14291 ProcessRecord app = addAppLocked(ai, false); 14292 app.instrumentationClass = className; 14293 app.instrumentationInfo = ai; 14294 app.instrumentationProfileFile = profileFile; 14295 app.instrumentationArguments = arguments; 14296 app.instrumentationWatcher = watcher; 14297 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14298 app.instrumentationResultClass = className; 14299 Binder.restoreCallingIdentity(origId); 14300 } 14301 14302 return true; 14303 } 14304 14305 /** 14306 * Report errors that occur while attempting to start Instrumentation. Always writes the 14307 * error to the logs, but if somebody is watching, send the report there too. This enables 14308 * the "am" command to report errors with more information. 14309 * 14310 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14311 * @param cn The component name of the instrumentation. 14312 * @param report The error report. 14313 */ 14314 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14315 ComponentName cn, String report) { 14316 Slog.w(TAG, report); 14317 try { 14318 if (watcher != null) { 14319 Bundle results = new Bundle(); 14320 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14321 results.putString("Error", report); 14322 watcher.instrumentationStatus(cn, -1, results); 14323 } 14324 } catch (RemoteException e) { 14325 Slog.w(TAG, e); 14326 } 14327 } 14328 14329 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14330 if (app.instrumentationWatcher != null) { 14331 try { 14332 // NOTE: IInstrumentationWatcher *must* be oneway here 14333 app.instrumentationWatcher.instrumentationFinished( 14334 app.instrumentationClass, 14335 resultCode, 14336 results); 14337 } catch (RemoteException e) { 14338 } 14339 } 14340 if (app.instrumentationUiAutomationConnection != null) { 14341 try { 14342 app.instrumentationUiAutomationConnection.shutdown(); 14343 } catch (RemoteException re) { 14344 /* ignore */ 14345 } 14346 // Only a UiAutomation can set this flag and now that 14347 // it is finished we make sure it is reset to its default. 14348 mUserIsMonkey = false; 14349 } 14350 app.instrumentationWatcher = null; 14351 app.instrumentationUiAutomationConnection = null; 14352 app.instrumentationClass = null; 14353 app.instrumentationInfo = null; 14354 app.instrumentationProfileFile = null; 14355 app.instrumentationArguments = null; 14356 14357 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14358 "finished inst"); 14359 } 14360 14361 public void finishInstrumentation(IApplicationThread target, 14362 int resultCode, Bundle results) { 14363 int userId = UserHandle.getCallingUserId(); 14364 // Refuse possible leaked file descriptors 14365 if (results != null && results.hasFileDescriptors()) { 14366 throw new IllegalArgumentException("File descriptors passed in Intent"); 14367 } 14368 14369 synchronized(this) { 14370 ProcessRecord app = getRecordForAppLocked(target); 14371 if (app == null) { 14372 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14373 return; 14374 } 14375 final long origId = Binder.clearCallingIdentity(); 14376 finishInstrumentationLocked(app, resultCode, results); 14377 Binder.restoreCallingIdentity(origId); 14378 } 14379 } 14380 14381 // ========================================================= 14382 // CONFIGURATION 14383 // ========================================================= 14384 14385 public ConfigurationInfo getDeviceConfigurationInfo() { 14386 ConfigurationInfo config = new ConfigurationInfo(); 14387 synchronized (this) { 14388 config.reqTouchScreen = mConfiguration.touchscreen; 14389 config.reqKeyboardType = mConfiguration.keyboard; 14390 config.reqNavigation = mConfiguration.navigation; 14391 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14392 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14393 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14394 } 14395 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14396 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14397 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14398 } 14399 config.reqGlEsVersion = GL_ES_VERSION; 14400 } 14401 return config; 14402 } 14403 14404 ActivityStack getFocusedStack() { 14405 return mStackSupervisor.getFocusedStack(); 14406 } 14407 14408 public Configuration getConfiguration() { 14409 Configuration ci; 14410 synchronized(this) { 14411 ci = new Configuration(mConfiguration); 14412 } 14413 return ci; 14414 } 14415 14416 public void updatePersistentConfiguration(Configuration values) { 14417 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14418 "updateConfiguration()"); 14419 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14420 "updateConfiguration()"); 14421 if (values == null) { 14422 throw new NullPointerException("Configuration must not be null"); 14423 } 14424 14425 synchronized(this) { 14426 final long origId = Binder.clearCallingIdentity(); 14427 updateConfigurationLocked(values, null, true, false); 14428 Binder.restoreCallingIdentity(origId); 14429 } 14430 } 14431 14432 public void updateConfiguration(Configuration values) { 14433 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14434 "updateConfiguration()"); 14435 14436 synchronized(this) { 14437 if (values == null && mWindowManager != null) { 14438 // sentinel: fetch the current configuration from the window manager 14439 values = mWindowManager.computeNewConfiguration(); 14440 } 14441 14442 if (mWindowManager != null) { 14443 mProcessList.applyDisplaySize(mWindowManager); 14444 } 14445 14446 final long origId = Binder.clearCallingIdentity(); 14447 if (values != null) { 14448 Settings.System.clearConfiguration(values); 14449 } 14450 updateConfigurationLocked(values, null, false, false); 14451 Binder.restoreCallingIdentity(origId); 14452 } 14453 } 14454 14455 /** 14456 * Do either or both things: (1) change the current configuration, and (2) 14457 * make sure the given activity is running with the (now) current 14458 * configuration. Returns true if the activity has been left running, or 14459 * false if <var>starting</var> is being destroyed to match the new 14460 * configuration. 14461 * @param persistent TODO 14462 */ 14463 boolean updateConfigurationLocked(Configuration values, 14464 ActivityRecord starting, boolean persistent, boolean initLocale) { 14465 int changes = 0; 14466 14467 if (values != null) { 14468 Configuration newConfig = new Configuration(mConfiguration); 14469 changes = newConfig.updateFrom(values); 14470 if (changes != 0) { 14471 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14472 Slog.i(TAG, "Updating configuration to: " + values); 14473 } 14474 14475 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14476 14477 if (values.locale != null && !initLocale) { 14478 saveLocaleLocked(values.locale, 14479 !values.locale.equals(mConfiguration.locale), 14480 values.userSetLocale); 14481 } 14482 14483 mConfigurationSeq++; 14484 if (mConfigurationSeq <= 0) { 14485 mConfigurationSeq = 1; 14486 } 14487 newConfig.seq = mConfigurationSeq; 14488 mConfiguration = newConfig; 14489 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14490 14491 final Configuration configCopy = new Configuration(mConfiguration); 14492 14493 // TODO: If our config changes, should we auto dismiss any currently 14494 // showing dialogs? 14495 mShowDialogs = shouldShowDialogs(newConfig); 14496 14497 AttributeCache ac = AttributeCache.instance(); 14498 if (ac != null) { 14499 ac.updateConfiguration(configCopy); 14500 } 14501 14502 // Make sure all resources in our process are updated 14503 // right now, so that anyone who is going to retrieve 14504 // resource values after we return will be sure to get 14505 // the new ones. This is especially important during 14506 // boot, where the first config change needs to guarantee 14507 // all resources have that config before following boot 14508 // code is executed. 14509 mSystemThread.applyConfigurationToResources(configCopy); 14510 14511 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14512 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14513 msg.obj = new Configuration(configCopy); 14514 mHandler.sendMessage(msg); 14515 } 14516 14517 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14518 ProcessRecord app = mLruProcesses.get(i); 14519 try { 14520 if (app.thread != null) { 14521 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14522 + app.processName + " new config " + mConfiguration); 14523 app.thread.scheduleConfigurationChanged(configCopy); 14524 } 14525 } catch (Exception e) { 14526 } 14527 } 14528 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14529 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14530 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14531 | Intent.FLAG_RECEIVER_FOREGROUND); 14532 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14533 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14534 Process.SYSTEM_UID, UserHandle.USER_ALL); 14535 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14536 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14537 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14538 broadcastIntentLocked(null, null, intent, 14539 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14540 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14541 } 14542 } 14543 } 14544 14545 boolean kept = true; 14546 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14547 // mainStack is null during startup. 14548 if (mainStack != null) { 14549 if (changes != 0 && starting == null) { 14550 // If the configuration changed, and the caller is not already 14551 // in the process of starting an activity, then find the top 14552 // activity to check if its configuration needs to change. 14553 starting = mainStack.topRunningActivityLocked(null); 14554 } 14555 14556 if (starting != null) { 14557 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14558 // And we need to make sure at this point that all other activities 14559 // are made visible with the correct configuration. 14560 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14561 } 14562 } 14563 14564 if (values != null && mWindowManager != null) { 14565 mWindowManager.setNewConfiguration(mConfiguration); 14566 } 14567 14568 return kept; 14569 } 14570 14571 /** 14572 * Decide based on the configuration whether we should shouw the ANR, 14573 * crash, etc dialogs. The idea is that if there is no affordnace to 14574 * press the on-screen buttons, we shouldn't show the dialog. 14575 * 14576 * A thought: SystemUI might also want to get told about this, the Power 14577 * dialog / global actions also might want different behaviors. 14578 */ 14579 private static final boolean shouldShowDialogs(Configuration config) { 14580 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14581 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14582 } 14583 14584 /** 14585 * Save the locale. You must be inside a synchronized (this) block. 14586 */ 14587 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14588 if(isDiff) { 14589 SystemProperties.set("user.language", l.getLanguage()); 14590 SystemProperties.set("user.region", l.getCountry()); 14591 } 14592 14593 if(isPersist) { 14594 SystemProperties.set("persist.sys.language", l.getLanguage()); 14595 SystemProperties.set("persist.sys.country", l.getCountry()); 14596 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14597 } 14598 } 14599 14600 @Override 14601 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14602 ActivityRecord srec = ActivityRecord.forToken(token); 14603 return srec != null && srec.task.affinity != null && 14604 srec.task.affinity.equals(destAffinity); 14605 } 14606 14607 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14608 Intent resultData) { 14609 14610 synchronized (this) { 14611 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14612 if (stack != null) { 14613 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14614 } 14615 return false; 14616 } 14617 } 14618 14619 public int getLaunchedFromUid(IBinder activityToken) { 14620 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14621 if (srec == null) { 14622 return -1; 14623 } 14624 return srec.launchedFromUid; 14625 } 14626 14627 public String getLaunchedFromPackage(IBinder activityToken) { 14628 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14629 if (srec == null) { 14630 return null; 14631 } 14632 return srec.launchedFromPackage; 14633 } 14634 14635 // ========================================================= 14636 // LIFETIME MANAGEMENT 14637 // ========================================================= 14638 14639 // Returns which broadcast queue the app is the current [or imminent] receiver 14640 // on, or 'null' if the app is not an active broadcast recipient. 14641 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14642 BroadcastRecord r = app.curReceiver; 14643 if (r != null) { 14644 return r.queue; 14645 } 14646 14647 // It's not the current receiver, but it might be starting up to become one 14648 synchronized (this) { 14649 for (BroadcastQueue queue : mBroadcastQueues) { 14650 r = queue.mPendingBroadcast; 14651 if (r != null && r.curApp == app) { 14652 // found it; report which queue it's in 14653 return queue; 14654 } 14655 } 14656 } 14657 14658 return null; 14659 } 14660 14661 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14662 boolean doingAll, long now) { 14663 if (mAdjSeq == app.adjSeq) { 14664 // This adjustment has already been computed. 14665 return app.curRawAdj; 14666 } 14667 14668 if (app.thread == null) { 14669 app.adjSeq = mAdjSeq; 14670 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14671 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14672 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14673 } 14674 14675 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14676 app.adjSource = null; 14677 app.adjTarget = null; 14678 app.empty = false; 14679 app.cached = false; 14680 14681 final int activitiesSize = app.activities.size(); 14682 14683 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14684 // The max adjustment doesn't allow this app to be anything 14685 // below foreground, so it is not worth doing work for it. 14686 app.adjType = "fixed"; 14687 app.adjSeq = mAdjSeq; 14688 app.curRawAdj = app.maxAdj; 14689 app.foregroundActivities = false; 14690 app.keeping = true; 14691 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14692 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14693 // System process can do UI, and when they do we want to have 14694 // them trim their memory after the user leaves the UI. To 14695 // facilitate this, here we need to determine whether or not it 14696 // is currently showing UI. 14697 app.systemNoUi = true; 14698 if (app == TOP_APP) { 14699 app.systemNoUi = false; 14700 } else if (activitiesSize > 0) { 14701 for (int j = 0; j < activitiesSize; j++) { 14702 final ActivityRecord r = app.activities.get(j); 14703 if (r.visible) { 14704 app.systemNoUi = false; 14705 } 14706 } 14707 } 14708 if (!app.systemNoUi) { 14709 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14710 } 14711 return (app.curAdj=app.maxAdj); 14712 } 14713 14714 app.keeping = false; 14715 app.systemNoUi = false; 14716 14717 // Determine the importance of the process, starting with most 14718 // important to least, and assign an appropriate OOM adjustment. 14719 int adj; 14720 int schedGroup; 14721 int procState; 14722 boolean foregroundActivities = false; 14723 boolean interesting = false; 14724 BroadcastQueue queue; 14725 if (app == TOP_APP) { 14726 // The last app on the list is the foreground app. 14727 adj = ProcessList.FOREGROUND_APP_ADJ; 14728 schedGroup = Process.THREAD_GROUP_DEFAULT; 14729 app.adjType = "top-activity"; 14730 foregroundActivities = true; 14731 interesting = true; 14732 procState = ActivityManager.PROCESS_STATE_TOP; 14733 } else if (app.instrumentationClass != null) { 14734 // Don't want to kill running instrumentation. 14735 adj = ProcessList.FOREGROUND_APP_ADJ; 14736 schedGroup = Process.THREAD_GROUP_DEFAULT; 14737 app.adjType = "instrumentation"; 14738 interesting = true; 14739 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14740 } else if ((queue = isReceivingBroadcast(app)) != null) { 14741 // An app that is currently receiving a broadcast also 14742 // counts as being in the foreground for OOM killer purposes. 14743 // It's placed in a sched group based on the nature of the 14744 // broadcast as reflected by which queue it's active in. 14745 adj = ProcessList.FOREGROUND_APP_ADJ; 14746 schedGroup = (queue == mFgBroadcastQueue) 14747 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14748 app.adjType = "broadcast"; 14749 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14750 } else if (app.executingServices.size() > 0) { 14751 // An app that is currently executing a service callback also 14752 // counts as being in the foreground. 14753 adj = ProcessList.FOREGROUND_APP_ADJ; 14754 schedGroup = app.execServicesFg ? 14755 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14756 app.adjType = "exec-service"; 14757 procState = ActivityManager.PROCESS_STATE_SERVICE; 14758 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14759 } else { 14760 // As far as we know the process is empty. We may change our mind later. 14761 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14762 // At this point we don't actually know the adjustment. Use the cached adj 14763 // value that the caller wants us to. 14764 adj = cachedAdj; 14765 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14766 app.cached = true; 14767 app.empty = true; 14768 app.adjType = "cch-empty"; 14769 } 14770 14771 // Examine all activities if not already foreground. 14772 if (!foregroundActivities && activitiesSize > 0) { 14773 for (int j = 0; j < activitiesSize; j++) { 14774 final ActivityRecord r = app.activities.get(j); 14775 if (r.app != app) { 14776 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14777 + app + "?!?"); 14778 continue; 14779 } 14780 if (r.visible) { 14781 // App has a visible activity; only upgrade adjustment. 14782 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14783 adj = ProcessList.VISIBLE_APP_ADJ; 14784 app.adjType = "visible"; 14785 } 14786 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14787 procState = ActivityManager.PROCESS_STATE_TOP; 14788 } 14789 schedGroup = Process.THREAD_GROUP_DEFAULT; 14790 app.cached = false; 14791 app.empty = false; 14792 foregroundActivities = true; 14793 break; 14794 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14795 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14796 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14797 app.adjType = "pausing"; 14798 } 14799 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14800 procState = ActivityManager.PROCESS_STATE_TOP; 14801 } 14802 schedGroup = Process.THREAD_GROUP_DEFAULT; 14803 app.cached = false; 14804 app.empty = false; 14805 foregroundActivities = true; 14806 } else if (r.state == ActivityState.STOPPING) { 14807 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14808 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14809 app.adjType = "stopping"; 14810 } 14811 // For the process state, we will at this point consider the 14812 // process to be cached. It will be cached either as an activity 14813 // or empty depending on whether the activity is finishing. We do 14814 // this so that we can treat the process as cached for purposes of 14815 // memory trimming (determing current memory level, trim command to 14816 // send to process) since there can be an arbitrary number of stopping 14817 // processes and they should soon all go into the cached state. 14818 if (!r.finishing) { 14819 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14820 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14821 } 14822 } 14823 app.cached = false; 14824 app.empty = false; 14825 foregroundActivities = true; 14826 } else { 14827 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14828 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14829 app.adjType = "cch-act"; 14830 } 14831 } 14832 } 14833 } 14834 14835 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14836 if (app.foregroundServices) { 14837 // The user is aware of this app, so make it visible. 14838 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14839 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14840 app.cached = false; 14841 app.adjType = "fg-service"; 14842 schedGroup = Process.THREAD_GROUP_DEFAULT; 14843 } else if (app.forcingToForeground != null) { 14844 // The user is aware of this app, so make it visible. 14845 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14846 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14847 app.cached = false; 14848 app.adjType = "force-fg"; 14849 app.adjSource = app.forcingToForeground; 14850 schedGroup = Process.THREAD_GROUP_DEFAULT; 14851 } 14852 } 14853 14854 if (app.foregroundServices) { 14855 interesting = true; 14856 } 14857 14858 if (app == mHeavyWeightProcess) { 14859 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14860 // We don't want to kill the current heavy-weight process. 14861 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14862 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14863 app.cached = false; 14864 app.adjType = "heavy"; 14865 } 14866 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14867 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14868 } 14869 } 14870 14871 if (app == mHomeProcess) { 14872 if (adj > ProcessList.HOME_APP_ADJ) { 14873 // This process is hosting what we currently consider to be the 14874 // home app, so we don't want to let it go into the background. 14875 adj = ProcessList.HOME_APP_ADJ; 14876 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14877 app.cached = false; 14878 app.adjType = "home"; 14879 } 14880 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14881 procState = ActivityManager.PROCESS_STATE_HOME; 14882 } 14883 } 14884 14885 if (app == mPreviousProcess && app.activities.size() > 0) { 14886 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14887 // This was the previous process that showed UI to the user. 14888 // We want to try to keep it around more aggressively, to give 14889 // a good experience around switching between two apps. 14890 adj = ProcessList.PREVIOUS_APP_ADJ; 14891 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14892 app.cached = false; 14893 app.adjType = "previous"; 14894 } 14895 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14896 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14897 } 14898 } 14899 14900 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14901 + " reason=" + app.adjType); 14902 14903 // By default, we use the computed adjustment. It may be changed if 14904 // there are applications dependent on our services or providers, but 14905 // this gives us a baseline and makes sure we don't get into an 14906 // infinite recursion. 14907 app.adjSeq = mAdjSeq; 14908 app.curRawAdj = adj; 14909 app.hasStartedServices = false; 14910 14911 if (mBackupTarget != null && app == mBackupTarget.app) { 14912 // If possible we want to avoid killing apps while they're being backed up 14913 if (adj > ProcessList.BACKUP_APP_ADJ) { 14914 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14915 adj = ProcessList.BACKUP_APP_ADJ; 14916 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14917 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14918 } 14919 app.adjType = "backup"; 14920 app.cached = false; 14921 } 14922 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14923 procState = ActivityManager.PROCESS_STATE_BACKUP; 14924 } 14925 } 14926 14927 boolean mayBeTop = false; 14928 14929 for (int is = app.services.size()-1; 14930 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14931 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14932 || procState > ActivityManager.PROCESS_STATE_TOP); 14933 is--) { 14934 ServiceRecord s = app.services.valueAt(is); 14935 if (s.startRequested) { 14936 app.hasStartedServices = true; 14937 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14938 procState = ActivityManager.PROCESS_STATE_SERVICE; 14939 } 14940 if (app.hasShownUi && app != mHomeProcess) { 14941 // If this process has shown some UI, let it immediately 14942 // go to the LRU list because it may be pretty heavy with 14943 // UI stuff. We'll tag it with a label just to help 14944 // debug and understand what is going on. 14945 if (adj > ProcessList.SERVICE_ADJ) { 14946 app.adjType = "cch-started-ui-services"; 14947 } 14948 } else { 14949 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14950 // This service has seen some activity within 14951 // recent memory, so we will keep its process ahead 14952 // of the background processes. 14953 if (adj > ProcessList.SERVICE_ADJ) { 14954 adj = ProcessList.SERVICE_ADJ; 14955 app.adjType = "started-services"; 14956 app.cached = false; 14957 } 14958 } 14959 // If we have let the service slide into the background 14960 // state, still have some text describing what it is doing 14961 // even though the service no longer has an impact. 14962 if (adj > ProcessList.SERVICE_ADJ) { 14963 app.adjType = "cch-started-services"; 14964 } 14965 } 14966 // Don't kill this process because it is doing work; it 14967 // has said it is doing work. 14968 app.keeping = true; 14969 } 14970 for (int conni = s.connections.size()-1; 14971 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14972 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14973 || procState > ActivityManager.PROCESS_STATE_TOP); 14974 conni--) { 14975 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14976 for (int i = 0; 14977 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14978 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14979 || procState > ActivityManager.PROCESS_STATE_TOP); 14980 i++) { 14981 // XXX should compute this based on the max of 14982 // all connected clients. 14983 ConnectionRecord cr = clist.get(i); 14984 if (cr.binding.client == app) { 14985 // Binding to ourself is not interesting. 14986 continue; 14987 } 14988 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14989 ProcessRecord client = cr.binding.client; 14990 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14991 TOP_APP, doingAll, now); 14992 int clientProcState = client.curProcState; 14993 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14994 // If the other app is cached for any reason, for purposes here 14995 // we are going to consider it empty. The specific cached state 14996 // doesn't propagate except under certain conditions. 14997 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14998 } 14999 String adjType = null; 15000 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 15001 // Not doing bind OOM management, so treat 15002 // this guy more like a started service. 15003 if (app.hasShownUi && app != mHomeProcess) { 15004 // If this process has shown some UI, let it immediately 15005 // go to the LRU list because it may be pretty heavy with 15006 // UI stuff. We'll tag it with a label just to help 15007 // debug and understand what is going on. 15008 if (adj > clientAdj) { 15009 adjType = "cch-bound-ui-services"; 15010 } 15011 app.cached = false; 15012 clientAdj = adj; 15013 clientProcState = procState; 15014 } else { 15015 if (now >= (s.lastActivity 15016 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15017 // This service has not seen activity within 15018 // recent memory, so allow it to drop to the 15019 // LRU list if there is no other reason to keep 15020 // it around. We'll also tag it with a label just 15021 // to help debug and undertand what is going on. 15022 if (adj > clientAdj) { 15023 adjType = "cch-bound-services"; 15024 } 15025 clientAdj = adj; 15026 } 15027 } 15028 } 15029 if (adj > clientAdj) { 15030 // If this process has recently shown UI, and 15031 // the process that is binding to it is less 15032 // important than being visible, then we don't 15033 // care about the binding as much as we care 15034 // about letting this process get into the LRU 15035 // list to be killed and restarted if needed for 15036 // memory. 15037 if (app.hasShownUi && app != mHomeProcess 15038 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15039 adjType = "cch-bound-ui-services"; 15040 } else { 15041 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15042 |Context.BIND_IMPORTANT)) != 0) { 15043 adj = clientAdj; 15044 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15045 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15046 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15047 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15048 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15049 adj = clientAdj; 15050 } else { 15051 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15052 adj = ProcessList.VISIBLE_APP_ADJ; 15053 } 15054 } 15055 if (!client.cached) { 15056 app.cached = false; 15057 } 15058 if (client.keeping) { 15059 app.keeping = true; 15060 } 15061 adjType = "service"; 15062 } 15063 } 15064 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15065 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15066 schedGroup = Process.THREAD_GROUP_DEFAULT; 15067 } 15068 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15069 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15070 // Special handling of clients who are in the top state. 15071 // We *may* want to consider this process to be in the 15072 // top state as well, but only if there is not another 15073 // reason for it to be running. Being on the top is a 15074 // special state, meaning you are specifically running 15075 // for the current top app. If the process is already 15076 // running in the background for some other reason, it 15077 // is more important to continue considering it to be 15078 // in the background state. 15079 mayBeTop = true; 15080 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15081 } else { 15082 // Special handling for above-top states (persistent 15083 // processes). These should not bring the current process 15084 // into the top state, since they are not on top. Instead 15085 // give them the best state after that. 15086 clientProcState = 15087 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15088 } 15089 } 15090 } else { 15091 if (clientProcState < 15092 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15093 clientProcState = 15094 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15095 } 15096 } 15097 if (procState > clientProcState) { 15098 procState = clientProcState; 15099 } 15100 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15101 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15102 app.pendingUiClean = true; 15103 } 15104 if (adjType != null) { 15105 app.adjType = adjType; 15106 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15107 .REASON_SERVICE_IN_USE; 15108 app.adjSource = cr.binding.client; 15109 app.adjSourceOom = clientAdj; 15110 app.adjTarget = s.name; 15111 } 15112 } 15113 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15114 app.treatLikeActivity = true; 15115 } 15116 final ActivityRecord a = cr.activity; 15117 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15118 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15119 (a.visible || a.state == ActivityState.RESUMED 15120 || a.state == ActivityState.PAUSING)) { 15121 adj = ProcessList.FOREGROUND_APP_ADJ; 15122 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15123 schedGroup = Process.THREAD_GROUP_DEFAULT; 15124 } 15125 app.cached = false; 15126 app.adjType = "service"; 15127 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15128 .REASON_SERVICE_IN_USE; 15129 app.adjSource = a; 15130 app.adjSourceOom = adj; 15131 app.adjTarget = s.name; 15132 } 15133 } 15134 } 15135 } 15136 } 15137 15138 for (int provi = app.pubProviders.size()-1; 15139 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15140 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15141 || procState > ActivityManager.PROCESS_STATE_TOP); 15142 provi--) { 15143 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15144 for (int i = cpr.connections.size()-1; 15145 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15146 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15147 || procState > ActivityManager.PROCESS_STATE_TOP); 15148 i--) { 15149 ContentProviderConnection conn = cpr.connections.get(i); 15150 ProcessRecord client = conn.client; 15151 if (client == app) { 15152 // Being our own client is not interesting. 15153 continue; 15154 } 15155 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15156 int clientProcState = client.curProcState; 15157 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15158 // If the other app is cached for any reason, for purposes here 15159 // we are going to consider it empty. 15160 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15161 } 15162 if (adj > clientAdj) { 15163 if (app.hasShownUi && app != mHomeProcess 15164 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15165 app.adjType = "cch-ui-provider"; 15166 } else { 15167 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15168 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15169 app.adjType = "provider"; 15170 } 15171 app.cached &= client.cached; 15172 app.keeping |= client.keeping; 15173 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15174 .REASON_PROVIDER_IN_USE; 15175 app.adjSource = client; 15176 app.adjSourceOom = clientAdj; 15177 app.adjTarget = cpr.name; 15178 } 15179 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15180 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15181 // Special handling of clients who are in the top state. 15182 // We *may* want to consider this process to be in the 15183 // top state as well, but only if there is not another 15184 // reason for it to be running. Being on the top is a 15185 // special state, meaning you are specifically running 15186 // for the current top app. If the process is already 15187 // running in the background for some other reason, it 15188 // is more important to continue considering it to be 15189 // in the background state. 15190 mayBeTop = true; 15191 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15192 } else { 15193 // Special handling for above-top states (persistent 15194 // processes). These should not bring the current process 15195 // into the top state, since they are not on top. Instead 15196 // give them the best state after that. 15197 clientProcState = 15198 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15199 } 15200 } 15201 if (procState > clientProcState) { 15202 procState = clientProcState; 15203 } 15204 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15205 schedGroup = Process.THREAD_GROUP_DEFAULT; 15206 } 15207 } 15208 // If the provider has external (non-framework) process 15209 // dependencies, ensure that its adjustment is at least 15210 // FOREGROUND_APP_ADJ. 15211 if (cpr.hasExternalProcessHandles()) { 15212 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15213 adj = ProcessList.FOREGROUND_APP_ADJ; 15214 schedGroup = Process.THREAD_GROUP_DEFAULT; 15215 app.cached = false; 15216 app.keeping = true; 15217 app.adjType = "provider"; 15218 app.adjTarget = cpr.name; 15219 } 15220 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15221 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15222 } 15223 } 15224 } 15225 15226 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15227 // A client of one of our services or providers is in the top state. We 15228 // *may* want to be in the top state, but not if we are already running in 15229 // the background for some other reason. For the decision here, we are going 15230 // to pick out a few specific states that we want to remain in when a client 15231 // is top (states that tend to be longer-term) and otherwise allow it to go 15232 // to the top state. 15233 switch (procState) { 15234 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15235 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15236 case ActivityManager.PROCESS_STATE_SERVICE: 15237 // These all are longer-term states, so pull them up to the top 15238 // of the background states, but not all the way to the top state. 15239 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15240 break; 15241 default: 15242 // Otherwise, top is a better choice, so take it. 15243 procState = ActivityManager.PROCESS_STATE_TOP; 15244 break; 15245 } 15246 } 15247 15248 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15249 if (app.hasClientActivities) { 15250 // This is a cached process, but with client activities. Mark it so. 15251 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15252 app.adjType = "cch-client-act"; 15253 } else if (app.treatLikeActivity) { 15254 // This is a cached process, but somebody wants us to treat it like it has 15255 // an activity, okay! 15256 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15257 app.adjType = "cch-as-act"; 15258 } 15259 } 15260 15261 if (adj == ProcessList.SERVICE_ADJ) { 15262 if (doingAll) { 15263 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15264 mNewNumServiceProcs++; 15265 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15266 if (!app.serviceb) { 15267 // This service isn't far enough down on the LRU list to 15268 // normally be a B service, but if we are low on RAM and it 15269 // is large we want to force it down since we would prefer to 15270 // keep launcher over it. 15271 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15272 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15273 app.serviceHighRam = true; 15274 app.serviceb = true; 15275 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15276 } else { 15277 mNewNumAServiceProcs++; 15278 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15279 } 15280 } else { 15281 app.serviceHighRam = false; 15282 } 15283 } 15284 if (app.serviceb) { 15285 adj = ProcessList.SERVICE_B_ADJ; 15286 } 15287 } 15288 15289 app.curRawAdj = adj; 15290 15291 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15292 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15293 if (adj > app.maxAdj) { 15294 adj = app.maxAdj; 15295 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15296 schedGroup = Process.THREAD_GROUP_DEFAULT; 15297 } 15298 } 15299 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15300 app.keeping = true; 15301 } 15302 15303 // Do final modification to adj. Everything we do between here and applying 15304 // the final setAdj must be done in this function, because we will also use 15305 // it when computing the final cached adj later. Note that we don't need to 15306 // worry about this for max adj above, since max adj will always be used to 15307 // keep it out of the cached vaues. 15308 adj = app.modifyRawOomAdj(adj); 15309 15310 app.curProcState = procState; 15311 15312 int importance = app.memImportance; 15313 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 15314 app.curAdj = adj; 15315 app.curSchedGroup = schedGroup; 15316 if (!interesting) { 15317 // For this reporting, if there is not something explicitly 15318 // interesting in this process then we will push it to the 15319 // background importance. 15320 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15321 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 15322 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15323 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 15324 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15325 } else if (adj >= ProcessList.HOME_APP_ADJ) { 15326 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15327 } else if (adj >= ProcessList.SERVICE_ADJ) { 15328 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15329 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15330 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 15331 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 15332 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 15333 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 15334 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 15335 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 15336 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 15337 } else { 15338 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 15339 } 15340 } 15341 15342 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 15343 if (foregroundActivities != app.foregroundActivities) { 15344 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15345 } 15346 if (changes != 0) { 15347 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15348 app.memImportance = importance; 15349 app.foregroundActivities = foregroundActivities; 15350 int i = mPendingProcessChanges.size()-1; 15351 ProcessChangeItem item = null; 15352 while (i >= 0) { 15353 item = mPendingProcessChanges.get(i); 15354 if (item.pid == app.pid) { 15355 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15356 break; 15357 } 15358 i--; 15359 } 15360 if (i < 0) { 15361 // No existing item in pending changes; need a new one. 15362 final int NA = mAvailProcessChanges.size(); 15363 if (NA > 0) { 15364 item = mAvailProcessChanges.remove(NA-1); 15365 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15366 } else { 15367 item = new ProcessChangeItem(); 15368 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15369 } 15370 item.changes = 0; 15371 item.pid = app.pid; 15372 item.uid = app.info.uid; 15373 if (mPendingProcessChanges.size() == 0) { 15374 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15375 "*** Enqueueing dispatch processes changed!"); 15376 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15377 } 15378 mPendingProcessChanges.add(item); 15379 } 15380 item.changes |= changes; 15381 item.importance = importance; 15382 item.foregroundActivities = foregroundActivities; 15383 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15384 + Integer.toHexString(System.identityHashCode(item)) 15385 + " " + app.toShortString() + ": changes=" + item.changes 15386 + " importance=" + item.importance 15387 + " foreground=" + item.foregroundActivities 15388 + " type=" + app.adjType + " source=" + app.adjSource 15389 + " target=" + app.adjTarget); 15390 } 15391 15392 return app.curRawAdj; 15393 } 15394 15395 /** 15396 * Schedule PSS collection of a process. 15397 */ 15398 void requestPssLocked(ProcessRecord proc, int procState) { 15399 if (mPendingPssProcesses.contains(proc)) { 15400 return; 15401 } 15402 if (mPendingPssProcesses.size() == 0) { 15403 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15404 } 15405 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15406 proc.pssProcState = procState; 15407 mPendingPssProcesses.add(proc); 15408 } 15409 15410 /** 15411 * Schedule PSS collection of all processes. 15412 */ 15413 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15414 if (!always) { 15415 if (now < (mLastFullPssTime + 15416 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15417 return; 15418 } 15419 } 15420 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15421 mLastFullPssTime = now; 15422 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15423 mPendingPssProcesses.clear(); 15424 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15425 ProcessRecord app = mLruProcesses.get(i); 15426 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15427 app.pssProcState = app.setProcState; 15428 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15429 isSleeping(), now); 15430 mPendingPssProcesses.add(app); 15431 } 15432 } 15433 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15434 } 15435 15436 /** 15437 * Ask a given process to GC right now. 15438 */ 15439 final void performAppGcLocked(ProcessRecord app) { 15440 try { 15441 app.lastRequestedGc = SystemClock.uptimeMillis(); 15442 if (app.thread != null) { 15443 if (app.reportLowMemory) { 15444 app.reportLowMemory = false; 15445 app.thread.scheduleLowMemory(); 15446 } else { 15447 app.thread.processInBackground(); 15448 } 15449 } 15450 } catch (Exception e) { 15451 // whatever. 15452 } 15453 } 15454 15455 /** 15456 * Returns true if things are idle enough to perform GCs. 15457 */ 15458 private final boolean canGcNowLocked() { 15459 boolean processingBroadcasts = false; 15460 for (BroadcastQueue q : mBroadcastQueues) { 15461 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15462 processingBroadcasts = true; 15463 } 15464 } 15465 return !processingBroadcasts 15466 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15467 } 15468 15469 /** 15470 * Perform GCs on all processes that are waiting for it, but only 15471 * if things are idle. 15472 */ 15473 final void performAppGcsLocked() { 15474 final int N = mProcessesToGc.size(); 15475 if (N <= 0) { 15476 return; 15477 } 15478 if (canGcNowLocked()) { 15479 while (mProcessesToGc.size() > 0) { 15480 ProcessRecord proc = mProcessesToGc.remove(0); 15481 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15482 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15483 <= SystemClock.uptimeMillis()) { 15484 // To avoid spamming the system, we will GC processes one 15485 // at a time, waiting a few seconds between each. 15486 performAppGcLocked(proc); 15487 scheduleAppGcsLocked(); 15488 return; 15489 } else { 15490 // It hasn't been long enough since we last GCed this 15491 // process... put it in the list to wait for its time. 15492 addProcessToGcListLocked(proc); 15493 break; 15494 } 15495 } 15496 } 15497 15498 scheduleAppGcsLocked(); 15499 } 15500 } 15501 15502 /** 15503 * If all looks good, perform GCs on all processes waiting for them. 15504 */ 15505 final void performAppGcsIfAppropriateLocked() { 15506 if (canGcNowLocked()) { 15507 performAppGcsLocked(); 15508 return; 15509 } 15510 // Still not idle, wait some more. 15511 scheduleAppGcsLocked(); 15512 } 15513 15514 /** 15515 * Schedule the execution of all pending app GCs. 15516 */ 15517 final void scheduleAppGcsLocked() { 15518 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15519 15520 if (mProcessesToGc.size() > 0) { 15521 // Schedule a GC for the time to the next process. 15522 ProcessRecord proc = mProcessesToGc.get(0); 15523 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15524 15525 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15526 long now = SystemClock.uptimeMillis(); 15527 if (when < (now+GC_TIMEOUT)) { 15528 when = now + GC_TIMEOUT; 15529 } 15530 mHandler.sendMessageAtTime(msg, when); 15531 } 15532 } 15533 15534 /** 15535 * Add a process to the array of processes waiting to be GCed. Keeps the 15536 * list in sorted order by the last GC time. The process can't already be 15537 * on the list. 15538 */ 15539 final void addProcessToGcListLocked(ProcessRecord proc) { 15540 boolean added = false; 15541 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15542 if (mProcessesToGc.get(i).lastRequestedGc < 15543 proc.lastRequestedGc) { 15544 added = true; 15545 mProcessesToGc.add(i+1, proc); 15546 break; 15547 } 15548 } 15549 if (!added) { 15550 mProcessesToGc.add(0, proc); 15551 } 15552 } 15553 15554 /** 15555 * Set up to ask a process to GC itself. This will either do it 15556 * immediately, or put it on the list of processes to gc the next 15557 * time things are idle. 15558 */ 15559 final void scheduleAppGcLocked(ProcessRecord app) { 15560 long now = SystemClock.uptimeMillis(); 15561 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15562 return; 15563 } 15564 if (!mProcessesToGc.contains(app)) { 15565 addProcessToGcListLocked(app); 15566 scheduleAppGcsLocked(); 15567 } 15568 } 15569 15570 final void checkExcessivePowerUsageLocked(boolean doKills) { 15571 updateCpuStatsNow(); 15572 15573 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15574 boolean doWakeKills = doKills; 15575 boolean doCpuKills = doKills; 15576 if (mLastPowerCheckRealtime == 0) { 15577 doWakeKills = false; 15578 } 15579 if (mLastPowerCheckUptime == 0) { 15580 doCpuKills = false; 15581 } 15582 if (stats.isScreenOn()) { 15583 doWakeKills = false; 15584 } 15585 final long curRealtime = SystemClock.elapsedRealtime(); 15586 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15587 final long curUptime = SystemClock.uptimeMillis(); 15588 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15589 mLastPowerCheckRealtime = curRealtime; 15590 mLastPowerCheckUptime = curUptime; 15591 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15592 doWakeKills = false; 15593 } 15594 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15595 doCpuKills = false; 15596 } 15597 int i = mLruProcesses.size(); 15598 while (i > 0) { 15599 i--; 15600 ProcessRecord app = mLruProcesses.get(i); 15601 if (!app.keeping) { 15602 long wtime; 15603 synchronized (stats) { 15604 wtime = stats.getProcessWakeTime(app.info.uid, 15605 app.pid, curRealtime); 15606 } 15607 long wtimeUsed = wtime - app.lastWakeTime; 15608 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15609 if (DEBUG_POWER) { 15610 StringBuilder sb = new StringBuilder(128); 15611 sb.append("Wake for "); 15612 app.toShortString(sb); 15613 sb.append(": over "); 15614 TimeUtils.formatDuration(realtimeSince, sb); 15615 sb.append(" used "); 15616 TimeUtils.formatDuration(wtimeUsed, sb); 15617 sb.append(" ("); 15618 sb.append((wtimeUsed*100)/realtimeSince); 15619 sb.append("%)"); 15620 Slog.i(TAG, sb.toString()); 15621 sb.setLength(0); 15622 sb.append("CPU for "); 15623 app.toShortString(sb); 15624 sb.append(": over "); 15625 TimeUtils.formatDuration(uptimeSince, sb); 15626 sb.append(" used "); 15627 TimeUtils.formatDuration(cputimeUsed, sb); 15628 sb.append(" ("); 15629 sb.append((cputimeUsed*100)/uptimeSince); 15630 sb.append("%)"); 15631 Slog.i(TAG, sb.toString()); 15632 } 15633 // If a process has held a wake lock for more 15634 // than 50% of the time during this period, 15635 // that sounds bad. Kill! 15636 if (doWakeKills && realtimeSince > 0 15637 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15638 synchronized (stats) { 15639 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15640 realtimeSince, wtimeUsed); 15641 } 15642 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15643 + " during " + realtimeSince); 15644 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15645 } else if (doCpuKills && uptimeSince > 0 15646 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15647 synchronized (stats) { 15648 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15649 uptimeSince, cputimeUsed); 15650 } 15651 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15652 + " during " + uptimeSince); 15653 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15654 } else { 15655 app.lastWakeTime = wtime; 15656 app.lastCpuTime = app.curCpuTime; 15657 } 15658 } 15659 } 15660 } 15661 15662 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15663 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15664 boolean success = true; 15665 15666 if (app.curRawAdj != app.setRawAdj) { 15667 if (wasKeeping && !app.keeping) { 15668 // This app is no longer something we want to keep. Note 15669 // its current wake lock time to later know to kill it if 15670 // it is not behaving well. 15671 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15672 synchronized (stats) { 15673 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15674 app.pid, SystemClock.elapsedRealtime()); 15675 } 15676 app.lastCpuTime = app.curCpuTime; 15677 } 15678 15679 app.setRawAdj = app.curRawAdj; 15680 } 15681 15682 if (app.curAdj != app.setAdj) { 15683 ProcessList.setOomAdj(app.pid, app.curAdj); 15684 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15685 TAG, "Set " + app.pid + " " + app.processName + 15686 " adj " + app.curAdj + ": " + app.adjType); 15687 app.setAdj = app.curAdj; 15688 } 15689 15690 if (app.setSchedGroup != app.curSchedGroup) { 15691 app.setSchedGroup = app.curSchedGroup; 15692 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15693 "Setting process group of " + app.processName 15694 + " to " + app.curSchedGroup); 15695 if (app.waitingToKill != null && 15696 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15697 killUnneededProcessLocked(app, app.waitingToKill); 15698 success = false; 15699 } else { 15700 if (true) { 15701 long oldId = Binder.clearCallingIdentity(); 15702 try { 15703 Process.setProcessGroup(app.pid, app.curSchedGroup); 15704 } catch (Exception e) { 15705 Slog.w(TAG, "Failed setting process group of " + app.pid 15706 + " to " + app.curSchedGroup); 15707 e.printStackTrace(); 15708 } finally { 15709 Binder.restoreCallingIdentity(oldId); 15710 } 15711 } else { 15712 if (app.thread != null) { 15713 try { 15714 app.thread.setSchedulingGroup(app.curSchedGroup); 15715 } catch (RemoteException e) { 15716 } 15717 } 15718 } 15719 Process.setSwappiness(app.pid, 15720 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15721 } 15722 } 15723 if (app.repProcState != app.curProcState) { 15724 app.repProcState = app.curProcState; 15725 if (!reportingProcessState && app.thread != null) { 15726 try { 15727 if (false) { 15728 //RuntimeException h = new RuntimeException("here"); 15729 Slog.i(TAG, "Sending new process state " + app.repProcState 15730 + " to " + app /*, h*/); 15731 } 15732 app.thread.setProcessState(app.repProcState); 15733 } catch (RemoteException e) { 15734 } 15735 } 15736 } 15737 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15738 app.setProcState)) { 15739 app.lastStateTime = now; 15740 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15741 isSleeping(), now); 15742 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15743 + ProcessList.makeProcStateString(app.setProcState) + " to " 15744 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15745 + (app.nextPssTime-now) + ": " + app); 15746 } else { 15747 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15748 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15749 requestPssLocked(app, app.setProcState); 15750 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15751 isSleeping(), now); 15752 } else if (false && DEBUG_PSS) { 15753 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15754 } 15755 } 15756 if (app.setProcState != app.curProcState) { 15757 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15758 "Proc state change of " + app.processName 15759 + " to " + app.curProcState); 15760 app.setProcState = app.curProcState; 15761 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15762 app.notCachedSinceIdle = false; 15763 } 15764 if (!doingAll) { 15765 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15766 } else { 15767 app.procStateChanged = true; 15768 } 15769 } 15770 return success; 15771 } 15772 15773 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15774 if (proc.thread != null && proc.baseProcessTracker != null) { 15775 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15776 } 15777 } 15778 15779 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15780 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15781 if (app.thread == null) { 15782 return false; 15783 } 15784 15785 final boolean wasKeeping = app.keeping; 15786 15787 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15788 15789 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15790 reportingProcessState, now); 15791 } 15792 15793 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15794 boolean oomAdj) { 15795 if (isForeground != proc.foregroundServices) { 15796 proc.foregroundServices = isForeground; 15797 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15798 proc.info.uid); 15799 if (isForeground) { 15800 if (curProcs == null) { 15801 curProcs = new ArrayList<ProcessRecord>(); 15802 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15803 } 15804 if (!curProcs.contains(proc)) { 15805 curProcs.add(proc); 15806 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15807 proc.info.packageName, proc.info.uid); 15808 } 15809 } else { 15810 if (curProcs != null) { 15811 if (curProcs.remove(proc)) { 15812 mBatteryStatsService.noteEvent( 15813 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15814 proc.info.packageName, proc.info.uid); 15815 if (curProcs.size() <= 0) { 15816 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15817 } 15818 } 15819 } 15820 } 15821 if (oomAdj) { 15822 updateOomAdjLocked(); 15823 } 15824 } 15825 } 15826 15827 private final ActivityRecord resumedAppLocked() { 15828 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15829 String pkg; 15830 int uid; 15831 if (act != null && !act.sleeping) { 15832 pkg = act.packageName; 15833 uid = act.info.applicationInfo.uid; 15834 } else { 15835 pkg = null; 15836 uid = -1; 15837 } 15838 // Has the UID or resumed package name changed? 15839 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15840 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15841 if (mCurResumedPackage != null) { 15842 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15843 mCurResumedPackage, mCurResumedUid); 15844 } 15845 mCurResumedPackage = pkg; 15846 mCurResumedUid = uid; 15847 if (mCurResumedPackage != null) { 15848 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15849 mCurResumedPackage, mCurResumedUid); 15850 } 15851 } 15852 return act; 15853 } 15854 15855 final boolean updateOomAdjLocked(ProcessRecord app) { 15856 return updateOomAdjLocked(app, false); 15857 } 15858 15859 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15860 final ActivityRecord TOP_ACT = resumedAppLocked(); 15861 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15862 final boolean wasCached = app.cached; 15863 15864 mAdjSeq++; 15865 15866 // This is the desired cached adjusment we want to tell it to use. 15867 // If our app is currently cached, we know it, and that is it. Otherwise, 15868 // we don't know it yet, and it needs to now be cached we will then 15869 // need to do a complete oom adj. 15870 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15871 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15872 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15873 SystemClock.uptimeMillis()); 15874 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15875 // Changed to/from cached state, so apps after it in the LRU 15876 // list may also be changed. 15877 updateOomAdjLocked(); 15878 } 15879 return success; 15880 } 15881 15882 final void updateOomAdjLocked() { 15883 final ActivityRecord TOP_ACT = resumedAppLocked(); 15884 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15885 final long now = SystemClock.uptimeMillis(); 15886 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15887 final int N = mLruProcesses.size(); 15888 15889 if (false) { 15890 RuntimeException e = new RuntimeException(); 15891 e.fillInStackTrace(); 15892 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15893 } 15894 15895 mAdjSeq++; 15896 mNewNumServiceProcs = 0; 15897 mNewNumAServiceProcs = 0; 15898 15899 final int emptyProcessLimit; 15900 final int cachedProcessLimit; 15901 if (mProcessLimit <= 0) { 15902 emptyProcessLimit = cachedProcessLimit = 0; 15903 } else if (mProcessLimit == 1) { 15904 emptyProcessLimit = 1; 15905 cachedProcessLimit = 0; 15906 } else { 15907 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15908 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15909 } 15910 15911 // Let's determine how many processes we have running vs. 15912 // how many slots we have for background processes; we may want 15913 // to put multiple processes in a slot of there are enough of 15914 // them. 15915 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15916 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15917 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15918 if (numEmptyProcs > cachedProcessLimit) { 15919 // If there are more empty processes than our limit on cached 15920 // processes, then use the cached process limit for the factor. 15921 // This ensures that the really old empty processes get pushed 15922 // down to the bottom, so if we are running low on memory we will 15923 // have a better chance at keeping around more cached processes 15924 // instead of a gazillion empty processes. 15925 numEmptyProcs = cachedProcessLimit; 15926 } 15927 int emptyFactor = numEmptyProcs/numSlots; 15928 if (emptyFactor < 1) emptyFactor = 1; 15929 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15930 if (cachedFactor < 1) cachedFactor = 1; 15931 int stepCached = 0; 15932 int stepEmpty = 0; 15933 int numCached = 0; 15934 int numEmpty = 0; 15935 int numTrimming = 0; 15936 15937 mNumNonCachedProcs = 0; 15938 mNumCachedHiddenProcs = 0; 15939 15940 // First update the OOM adjustment for each of the 15941 // application processes based on their current state. 15942 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15943 int nextCachedAdj = curCachedAdj+1; 15944 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15945 int nextEmptyAdj = curEmptyAdj+2; 15946 for (int i=N-1; i>=0; i--) { 15947 ProcessRecord app = mLruProcesses.get(i); 15948 if (!app.killedByAm && app.thread != null) { 15949 app.procStateChanged = false; 15950 final boolean wasKeeping = app.keeping; 15951 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15952 15953 // If we haven't yet assigned the final cached adj 15954 // to the process, do that now. 15955 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15956 switch (app.curProcState) { 15957 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15958 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15959 // This process is a cached process holding activities... 15960 // assign it the next cached value for that type, and then 15961 // step that cached level. 15962 app.curRawAdj = curCachedAdj; 15963 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15964 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15965 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15966 + ")"); 15967 if (curCachedAdj != nextCachedAdj) { 15968 stepCached++; 15969 if (stepCached >= cachedFactor) { 15970 stepCached = 0; 15971 curCachedAdj = nextCachedAdj; 15972 nextCachedAdj += 2; 15973 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15974 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15975 } 15976 } 15977 } 15978 break; 15979 default: 15980 // For everything else, assign next empty cached process 15981 // level and bump that up. Note that this means that 15982 // long-running services that have dropped down to the 15983 // cached level will be treated as empty (since their process 15984 // state is still as a service), which is what we want. 15985 app.curRawAdj = curEmptyAdj; 15986 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15987 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15988 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15989 + ")"); 15990 if (curEmptyAdj != nextEmptyAdj) { 15991 stepEmpty++; 15992 if (stepEmpty >= emptyFactor) { 15993 stepEmpty = 0; 15994 curEmptyAdj = nextEmptyAdj; 15995 nextEmptyAdj += 2; 15996 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15997 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15998 } 15999 } 16000 } 16001 break; 16002 } 16003 } 16004 16005 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 16006 16007 // Count the number of process types. 16008 switch (app.curProcState) { 16009 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16010 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16011 mNumCachedHiddenProcs++; 16012 numCached++; 16013 if (numCached > cachedProcessLimit) { 16014 killUnneededProcessLocked(app, "cached #" + numCached); 16015 } 16016 break; 16017 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 16018 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 16019 && app.lastActivityTime < oldTime) { 16020 killUnneededProcessLocked(app, "empty for " 16021 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 16022 / 1000) + "s"); 16023 } else { 16024 numEmpty++; 16025 if (numEmpty > emptyProcessLimit) { 16026 killUnneededProcessLocked(app, "empty #" + numEmpty); 16027 } 16028 } 16029 break; 16030 default: 16031 mNumNonCachedProcs++; 16032 break; 16033 } 16034 16035 if (app.isolated && app.services.size() <= 0) { 16036 // If this is an isolated process, and there are no 16037 // services running in it, then the process is no longer 16038 // needed. We agressively kill these because we can by 16039 // definition not re-use the same process again, and it is 16040 // good to avoid having whatever code was running in them 16041 // left sitting around after no longer needed. 16042 killUnneededProcessLocked(app, "isolated not needed"); 16043 } 16044 16045 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16046 && !app.killedByAm) { 16047 numTrimming++; 16048 } 16049 } 16050 } 16051 16052 mNumServiceProcs = mNewNumServiceProcs; 16053 16054 // Now determine the memory trimming level of background processes. 16055 // Unfortunately we need to start at the back of the list to do this 16056 // properly. We only do this if the number of background apps we 16057 // are managing to keep around is less than half the maximum we desire; 16058 // if we are keeping a good number around, we'll let them use whatever 16059 // memory they want. 16060 final int numCachedAndEmpty = numCached + numEmpty; 16061 int memFactor; 16062 if (numCached <= ProcessList.TRIM_CACHED_APPS 16063 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16064 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16065 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16066 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16067 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16068 } else { 16069 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16070 } 16071 } else { 16072 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16073 } 16074 // We always allow the memory level to go up (better). We only allow it to go 16075 // down if we are in a state where that is allowed, *and* the total number of processes 16076 // has gone down since last time. 16077 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16078 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16079 + " last=" + mLastNumProcesses); 16080 if (memFactor > mLastMemoryLevel) { 16081 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16082 memFactor = mLastMemoryLevel; 16083 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16084 } 16085 } 16086 mLastMemoryLevel = memFactor; 16087 mLastNumProcesses = mLruProcesses.size(); 16088 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16089 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16090 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16091 if (mLowRamStartTime == 0) { 16092 mLowRamStartTime = now; 16093 } 16094 int step = 0; 16095 int fgTrimLevel; 16096 switch (memFactor) { 16097 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16098 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16099 break; 16100 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16101 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16102 break; 16103 default: 16104 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16105 break; 16106 } 16107 int factor = numTrimming/3; 16108 int minFactor = 2; 16109 if (mHomeProcess != null) minFactor++; 16110 if (mPreviousProcess != null) minFactor++; 16111 if (factor < minFactor) factor = minFactor; 16112 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16113 for (int i=N-1; i>=0; i--) { 16114 ProcessRecord app = mLruProcesses.get(i); 16115 if (allChanged || app.procStateChanged) { 16116 setProcessTrackerState(app, trackerMemFactor, now); 16117 app.procStateChanged = false; 16118 } 16119 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16120 && !app.killedByAm) { 16121 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16122 try { 16123 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16124 "Trimming memory of " + app.processName 16125 + " to " + curLevel); 16126 app.thread.scheduleTrimMemory(curLevel); 16127 } catch (RemoteException e) { 16128 } 16129 if (false) { 16130 // For now we won't do this; our memory trimming seems 16131 // to be good enough at this point that destroying 16132 // activities causes more harm than good. 16133 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16134 && app != mHomeProcess && app != mPreviousProcess) { 16135 // Need to do this on its own message because the stack may not 16136 // be in a consistent state at this point. 16137 // For these apps we will also finish their activities 16138 // to help them free memory. 16139 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16140 } 16141 } 16142 } 16143 app.trimMemoryLevel = curLevel; 16144 step++; 16145 if (step >= factor) { 16146 step = 0; 16147 switch (curLevel) { 16148 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16149 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16150 break; 16151 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16152 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16153 break; 16154 } 16155 } 16156 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16157 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16158 && app.thread != null) { 16159 try { 16160 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16161 "Trimming memory of heavy-weight " + app.processName 16162 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16163 app.thread.scheduleTrimMemory( 16164 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16165 } catch (RemoteException e) { 16166 } 16167 } 16168 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16169 } else { 16170 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16171 || app.systemNoUi) && app.pendingUiClean) { 16172 // If this application is now in the background and it 16173 // had done UI, then give it the special trim level to 16174 // have it free UI resources. 16175 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16176 if (app.trimMemoryLevel < level && app.thread != null) { 16177 try { 16178 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16179 "Trimming memory of bg-ui " + app.processName 16180 + " to " + level); 16181 app.thread.scheduleTrimMemory(level); 16182 } catch (RemoteException e) { 16183 } 16184 } 16185 app.pendingUiClean = false; 16186 } 16187 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16188 try { 16189 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16190 "Trimming memory of fg " + app.processName 16191 + " to " + fgTrimLevel); 16192 app.thread.scheduleTrimMemory(fgTrimLevel); 16193 } catch (RemoteException e) { 16194 } 16195 } 16196 app.trimMemoryLevel = fgTrimLevel; 16197 } 16198 } 16199 } else { 16200 if (mLowRamStartTime != 0) { 16201 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16202 mLowRamStartTime = 0; 16203 } 16204 for (int i=N-1; i>=0; i--) { 16205 ProcessRecord app = mLruProcesses.get(i); 16206 if (allChanged || app.procStateChanged) { 16207 setProcessTrackerState(app, trackerMemFactor, now); 16208 app.procStateChanged = false; 16209 } 16210 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16211 || app.systemNoUi) && app.pendingUiClean) { 16212 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16213 && app.thread != null) { 16214 try { 16215 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16216 "Trimming memory of ui hidden " + app.processName 16217 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16218 app.thread.scheduleTrimMemory( 16219 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16220 } catch (RemoteException e) { 16221 } 16222 } 16223 app.pendingUiClean = false; 16224 } 16225 app.trimMemoryLevel = 0; 16226 } 16227 } 16228 16229 if (mAlwaysFinishActivities) { 16230 // Need to do this on its own message because the stack may not 16231 // be in a consistent state at this point. 16232 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16233 } 16234 16235 if (allChanged) { 16236 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16237 } 16238 16239 if (mProcessStats.shouldWriteNowLocked(now)) { 16240 mHandler.post(new Runnable() { 16241 @Override public void run() { 16242 synchronized (ActivityManagerService.this) { 16243 mProcessStats.writeStateAsyncLocked(); 16244 } 16245 } 16246 }); 16247 } 16248 16249 if (DEBUG_OOM_ADJ) { 16250 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16251 } 16252 } 16253 16254 final void trimApplications() { 16255 synchronized (this) { 16256 int i; 16257 16258 // First remove any unused application processes whose package 16259 // has been removed. 16260 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16261 final ProcessRecord app = mRemovedProcesses.get(i); 16262 if (app.activities.size() == 0 16263 && app.curReceiver == null && app.services.size() == 0) { 16264 Slog.i( 16265 TAG, "Exiting empty application process " 16266 + app.processName + " (" 16267 + (app.thread != null ? app.thread.asBinder() : null) 16268 + ")\n"); 16269 if (app.pid > 0 && app.pid != MY_PID) { 16270 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16271 app.processName, app.setAdj, "empty"); 16272 app.killedByAm = true; 16273 Process.killProcessQuiet(app.pid); 16274 } else { 16275 try { 16276 app.thread.scheduleExit(); 16277 } catch (Exception e) { 16278 // Ignore exceptions. 16279 } 16280 } 16281 cleanUpApplicationRecordLocked(app, false, true, -1); 16282 mRemovedProcesses.remove(i); 16283 16284 if (app.persistent) { 16285 if (app.persistent) { 16286 addAppLocked(app.info, false); 16287 } 16288 } 16289 } 16290 } 16291 16292 // Now update the oom adj for all processes. 16293 updateOomAdjLocked(); 16294 } 16295 } 16296 16297 /** This method sends the specified signal to each of the persistent apps */ 16298 public void signalPersistentProcesses(int sig) throws RemoteException { 16299 if (sig != Process.SIGNAL_USR1) { 16300 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16301 } 16302 16303 synchronized (this) { 16304 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16305 != PackageManager.PERMISSION_GRANTED) { 16306 throw new SecurityException("Requires permission " 16307 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16308 } 16309 16310 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16311 ProcessRecord r = mLruProcesses.get(i); 16312 if (r.thread != null && r.persistent) { 16313 Process.sendSignal(r.pid, sig); 16314 } 16315 } 16316 } 16317 } 16318 16319 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16320 if (proc == null || proc == mProfileProc) { 16321 proc = mProfileProc; 16322 path = mProfileFile; 16323 profileType = mProfileType; 16324 clearProfilerLocked(); 16325 } 16326 if (proc == null) { 16327 return; 16328 } 16329 try { 16330 proc.thread.profilerControl(false, path, null, profileType); 16331 } catch (RemoteException e) { 16332 throw new IllegalStateException("Process disappeared"); 16333 } 16334 } 16335 16336 private void clearProfilerLocked() { 16337 if (mProfileFd != null) { 16338 try { 16339 mProfileFd.close(); 16340 } catch (IOException e) { 16341 } 16342 } 16343 mProfileApp = null; 16344 mProfileProc = null; 16345 mProfileFile = null; 16346 mProfileType = 0; 16347 mAutoStopProfiler = false; 16348 } 16349 16350 public boolean profileControl(String process, int userId, boolean start, 16351 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16352 16353 try { 16354 synchronized (this) { 16355 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16356 // its own permission. 16357 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16358 != PackageManager.PERMISSION_GRANTED) { 16359 throw new SecurityException("Requires permission " 16360 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16361 } 16362 16363 if (start && fd == null) { 16364 throw new IllegalArgumentException("null fd"); 16365 } 16366 16367 ProcessRecord proc = null; 16368 if (process != null) { 16369 proc = findProcessLocked(process, userId, "profileControl"); 16370 } 16371 16372 if (start && (proc == null || proc.thread == null)) { 16373 throw new IllegalArgumentException("Unknown process: " + process); 16374 } 16375 16376 if (start) { 16377 stopProfilerLocked(null, null, 0); 16378 setProfileApp(proc.info, proc.processName, path, fd, false); 16379 mProfileProc = proc; 16380 mProfileType = profileType; 16381 try { 16382 fd = fd.dup(); 16383 } catch (IOException e) { 16384 fd = null; 16385 } 16386 proc.thread.profilerControl(start, path, fd, profileType); 16387 fd = null; 16388 mProfileFd = null; 16389 } else { 16390 stopProfilerLocked(proc, path, profileType); 16391 if (fd != null) { 16392 try { 16393 fd.close(); 16394 } catch (IOException e) { 16395 } 16396 } 16397 } 16398 16399 return true; 16400 } 16401 } catch (RemoteException e) { 16402 throw new IllegalStateException("Process disappeared"); 16403 } finally { 16404 if (fd != null) { 16405 try { 16406 fd.close(); 16407 } catch (IOException e) { 16408 } 16409 } 16410 } 16411 } 16412 16413 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16414 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16415 userId, true, true, callName, null); 16416 ProcessRecord proc = null; 16417 try { 16418 int pid = Integer.parseInt(process); 16419 synchronized (mPidsSelfLocked) { 16420 proc = mPidsSelfLocked.get(pid); 16421 } 16422 } catch (NumberFormatException e) { 16423 } 16424 16425 if (proc == null) { 16426 ArrayMap<String, SparseArray<ProcessRecord>> all 16427 = mProcessNames.getMap(); 16428 SparseArray<ProcessRecord> procs = all.get(process); 16429 if (procs != null && procs.size() > 0) { 16430 proc = procs.valueAt(0); 16431 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16432 for (int i=1; i<procs.size(); i++) { 16433 ProcessRecord thisProc = procs.valueAt(i); 16434 if (thisProc.userId == userId) { 16435 proc = thisProc; 16436 break; 16437 } 16438 } 16439 } 16440 } 16441 } 16442 16443 return proc; 16444 } 16445 16446 public boolean dumpHeap(String process, int userId, boolean managed, 16447 String path, ParcelFileDescriptor fd) throws RemoteException { 16448 16449 try { 16450 synchronized (this) { 16451 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16452 // its own permission (same as profileControl). 16453 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16454 != PackageManager.PERMISSION_GRANTED) { 16455 throw new SecurityException("Requires permission " 16456 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16457 } 16458 16459 if (fd == null) { 16460 throw new IllegalArgumentException("null fd"); 16461 } 16462 16463 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16464 if (proc == null || proc.thread == null) { 16465 throw new IllegalArgumentException("Unknown process: " + process); 16466 } 16467 16468 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16469 if (!isDebuggable) { 16470 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16471 throw new SecurityException("Process not debuggable: " + proc); 16472 } 16473 } 16474 16475 proc.thread.dumpHeap(managed, path, fd); 16476 fd = null; 16477 return true; 16478 } 16479 } catch (RemoteException e) { 16480 throw new IllegalStateException("Process disappeared"); 16481 } finally { 16482 if (fd != null) { 16483 try { 16484 fd.close(); 16485 } catch (IOException e) { 16486 } 16487 } 16488 } 16489 } 16490 16491 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16492 public void monitor() { 16493 synchronized (this) { } 16494 } 16495 16496 void onCoreSettingsChange(Bundle settings) { 16497 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16498 ProcessRecord processRecord = mLruProcesses.get(i); 16499 try { 16500 if (processRecord.thread != null) { 16501 processRecord.thread.setCoreSettings(settings); 16502 } 16503 } catch (RemoteException re) { 16504 /* ignore */ 16505 } 16506 } 16507 } 16508 16509 // Multi-user methods 16510 16511 /** 16512 * Start user, if its not already running, but don't bring it to foreground. 16513 */ 16514 @Override 16515 public boolean startUserInBackground(final int userId) { 16516 return startUser(userId, /* foreground */ false); 16517 } 16518 16519 /** 16520 * Refreshes the list of users related to the current user when either a 16521 * user switch happens or when a new related user is started in the 16522 * background. 16523 */ 16524 private void updateCurrentProfileIdsLocked() { 16525 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16526 mCurrentUserId, false /* enabledOnly */); 16527 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16528 for (int i = 0; i < currentProfileIds.length; i++) { 16529 currentProfileIds[i] = profiles.get(i).id; 16530 } 16531 mCurrentProfileIds = currentProfileIds; 16532 } 16533 16534 private Set getProfileIdsLocked(int userId) { 16535 Set userIds = new HashSet<Integer>(); 16536 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16537 userId, false /* enabledOnly */); 16538 for (UserInfo user : profiles) { 16539 userIds.add(Integer.valueOf(user.id)); 16540 } 16541 return userIds; 16542 } 16543 16544 @Override 16545 public boolean switchUser(final int userId) { 16546 return startUser(userId, /* foregound */ true); 16547 } 16548 16549 private boolean startUser(final int userId, boolean foreground) { 16550 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16551 != PackageManager.PERMISSION_GRANTED) { 16552 String msg = "Permission Denial: switchUser() from pid=" 16553 + Binder.getCallingPid() 16554 + ", uid=" + Binder.getCallingUid() 16555 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16556 Slog.w(TAG, msg); 16557 throw new SecurityException(msg); 16558 } 16559 16560 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16561 16562 final long ident = Binder.clearCallingIdentity(); 16563 try { 16564 synchronized (this) { 16565 final int oldUserId = mCurrentUserId; 16566 if (oldUserId == userId) { 16567 return true; 16568 } 16569 16570 mStackSupervisor.setLockTaskModeLocked(null); 16571 16572 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16573 if (userInfo == null) { 16574 Slog.w(TAG, "No user info for user #" + userId); 16575 return false; 16576 } 16577 16578 if (foreground) { 16579 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16580 R.anim.screen_user_enter); 16581 } 16582 16583 boolean needStart = false; 16584 16585 // If the user we are switching to is not currently started, then 16586 // we need to start it now. 16587 if (mStartedUsers.get(userId) == null) { 16588 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16589 updateStartedUserArrayLocked(); 16590 needStart = true; 16591 } 16592 16593 final Integer userIdInt = Integer.valueOf(userId); 16594 mUserLru.remove(userIdInt); 16595 mUserLru.add(userIdInt); 16596 16597 if (foreground) { 16598 mCurrentUserId = userId; 16599 updateCurrentProfileIdsLocked(); 16600 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16601 // Once the internal notion of the active user has switched, we lock the device 16602 // with the option to show the user switcher on the keyguard. 16603 mWindowManager.lockNow(null); 16604 } else { 16605 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16606 updateCurrentProfileIdsLocked(); 16607 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16608 mUserLru.remove(currentUserIdInt); 16609 mUserLru.add(currentUserIdInt); 16610 } 16611 16612 final UserStartedState uss = mStartedUsers.get(userId); 16613 16614 // Make sure user is in the started state. If it is currently 16615 // stopping, we need to knock that off. 16616 if (uss.mState == UserStartedState.STATE_STOPPING) { 16617 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16618 // so we can just fairly silently bring the user back from 16619 // the almost-dead. 16620 uss.mState = UserStartedState.STATE_RUNNING; 16621 updateStartedUserArrayLocked(); 16622 needStart = true; 16623 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16624 // This means ACTION_SHUTDOWN has been sent, so we will 16625 // need to treat this as a new boot of the user. 16626 uss.mState = UserStartedState.STATE_BOOTING; 16627 updateStartedUserArrayLocked(); 16628 needStart = true; 16629 } 16630 16631 if (uss.mState == UserStartedState.STATE_BOOTING) { 16632 // Booting up a new user, need to tell system services about it. 16633 // Note that this is on the same handler as scheduling of broadcasts, 16634 // which is important because it needs to go first. 16635 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16636 } 16637 16638 if (foreground) { 16639 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16640 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16641 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16642 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16643 oldUserId, userId, uss)); 16644 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16645 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16646 } 16647 16648 if (needStart) { 16649 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16650 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16651 | Intent.FLAG_RECEIVER_FOREGROUND); 16652 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16653 broadcastIntentLocked(null, null, intent, 16654 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16655 false, false, MY_PID, Process.SYSTEM_UID, userId); 16656 } 16657 16658 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16659 if (userId != 0) { 16660 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16661 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16662 broadcastIntentLocked(null, null, intent, null, 16663 new IIntentReceiver.Stub() { 16664 public void performReceive(Intent intent, int resultCode, 16665 String data, Bundle extras, boolean ordered, 16666 boolean sticky, int sendingUser) { 16667 userInitialized(uss, userId); 16668 } 16669 }, 0, null, null, null, AppOpsManager.OP_NONE, 16670 true, false, MY_PID, Process.SYSTEM_UID, 16671 userId); 16672 uss.initializing = true; 16673 } else { 16674 getUserManagerLocked().makeInitialized(userInfo.id); 16675 } 16676 } 16677 16678 if (foreground) { 16679 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16680 if (homeInFront) { 16681 startHomeActivityLocked(userId); 16682 } else { 16683 mStackSupervisor.resumeTopActivitiesLocked(); 16684 } 16685 EventLogTags.writeAmSwitchUser(userId); 16686 getUserManagerLocked().userForeground(userId); 16687 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16688 } 16689 16690 if (needStart) { 16691 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16692 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16693 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16694 broadcastIntentLocked(null, null, intent, 16695 null, new IIntentReceiver.Stub() { 16696 @Override 16697 public void performReceive(Intent intent, int resultCode, String data, 16698 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16699 throws RemoteException { 16700 } 16701 }, 0, null, null, 16702 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16703 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16704 } 16705 } 16706 } finally { 16707 Binder.restoreCallingIdentity(ident); 16708 } 16709 16710 return true; 16711 } 16712 16713 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16714 long ident = Binder.clearCallingIdentity(); 16715 try { 16716 Intent intent; 16717 if (oldUserId >= 0) { 16718 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16719 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16720 | Intent.FLAG_RECEIVER_FOREGROUND); 16721 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16722 broadcastIntentLocked(null, null, intent, 16723 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16724 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16725 } 16726 if (newUserId >= 0) { 16727 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16728 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16729 | Intent.FLAG_RECEIVER_FOREGROUND); 16730 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16731 broadcastIntentLocked(null, null, intent, 16732 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16733 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16734 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16735 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16736 | Intent.FLAG_RECEIVER_FOREGROUND); 16737 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16738 broadcastIntentLocked(null, null, intent, 16739 null, null, 0, null, null, 16740 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16741 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16742 } 16743 } finally { 16744 Binder.restoreCallingIdentity(ident); 16745 } 16746 } 16747 16748 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16749 final int newUserId) { 16750 final int N = mUserSwitchObservers.beginBroadcast(); 16751 if (N > 0) { 16752 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16753 int mCount = 0; 16754 @Override 16755 public void sendResult(Bundle data) throws RemoteException { 16756 synchronized (ActivityManagerService.this) { 16757 if (mCurUserSwitchCallback == this) { 16758 mCount++; 16759 if (mCount == N) { 16760 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16761 } 16762 } 16763 } 16764 } 16765 }; 16766 synchronized (this) { 16767 uss.switching = true; 16768 mCurUserSwitchCallback = callback; 16769 } 16770 for (int i=0; i<N; i++) { 16771 try { 16772 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16773 newUserId, callback); 16774 } catch (RemoteException e) { 16775 } 16776 } 16777 } else { 16778 synchronized (this) { 16779 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16780 } 16781 } 16782 mUserSwitchObservers.finishBroadcast(); 16783 } 16784 16785 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16786 synchronized (this) { 16787 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16788 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16789 } 16790 } 16791 16792 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16793 mCurUserSwitchCallback = null; 16794 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16795 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16796 oldUserId, newUserId, uss)); 16797 } 16798 16799 void userInitialized(UserStartedState uss, int newUserId) { 16800 completeSwitchAndInitalize(uss, newUserId, true, false); 16801 } 16802 16803 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16804 completeSwitchAndInitalize(uss, newUserId, false, true); 16805 } 16806 16807 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16808 boolean clearInitializing, boolean clearSwitching) { 16809 boolean unfrozen = false; 16810 synchronized (this) { 16811 if (clearInitializing) { 16812 uss.initializing = false; 16813 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16814 } 16815 if (clearSwitching) { 16816 uss.switching = false; 16817 } 16818 if (!uss.switching && !uss.initializing) { 16819 mWindowManager.stopFreezingScreen(); 16820 unfrozen = true; 16821 } 16822 } 16823 if (unfrozen) { 16824 final int N = mUserSwitchObservers.beginBroadcast(); 16825 for (int i=0; i<N; i++) { 16826 try { 16827 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16828 } catch (RemoteException e) { 16829 } 16830 } 16831 mUserSwitchObservers.finishBroadcast(); 16832 } 16833 } 16834 16835 void scheduleStartProfilesLocked() { 16836 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16837 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16838 DateUtils.SECOND_IN_MILLIS); 16839 } 16840 } 16841 16842 void startProfilesLocked() { 16843 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16844 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16845 mCurrentUserId, false /* enabledOnly */); 16846 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16847 for (UserInfo user : profiles) { 16848 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16849 && user.id != mCurrentUserId) { 16850 toStart.add(user); 16851 } 16852 } 16853 final int n = toStart.size(); 16854 int i = 0; 16855 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16856 startUserInBackground(toStart.get(i).id); 16857 } 16858 if (i < n) { 16859 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16860 } 16861 } 16862 16863 void finishUserSwitch(UserStartedState uss) { 16864 synchronized (this) { 16865 if (uss.mState == UserStartedState.STATE_BOOTING 16866 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16867 uss.mState = UserStartedState.STATE_RUNNING; 16868 final int userId = uss.mHandle.getIdentifier(); 16869 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16870 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16871 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16872 broadcastIntentLocked(null, null, intent, 16873 null, null, 0, null, null, 16874 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16875 true, false, MY_PID, Process.SYSTEM_UID, userId); 16876 } 16877 16878 startProfilesLocked(); 16879 16880 int num = mUserLru.size(); 16881 int i = 0; 16882 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16883 Integer oldUserId = mUserLru.get(i); 16884 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16885 if (oldUss == null) { 16886 // Shouldn't happen, but be sane if it does. 16887 mUserLru.remove(i); 16888 num--; 16889 continue; 16890 } 16891 if (oldUss.mState == UserStartedState.STATE_STOPPING 16892 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16893 // This user is already stopping, doesn't count. 16894 num--; 16895 i++; 16896 continue; 16897 } 16898 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16899 // Owner and current can't be stopped, but count as running. 16900 i++; 16901 continue; 16902 } 16903 // This is a user to be stopped. 16904 stopUserLocked(oldUserId, null); 16905 num--; 16906 i++; 16907 } 16908 } 16909 } 16910 16911 @Override 16912 public int stopUser(final int userId, final IStopUserCallback callback) { 16913 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16914 != PackageManager.PERMISSION_GRANTED) { 16915 String msg = "Permission Denial: switchUser() from pid=" 16916 + Binder.getCallingPid() 16917 + ", uid=" + Binder.getCallingUid() 16918 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16919 Slog.w(TAG, msg); 16920 throw new SecurityException(msg); 16921 } 16922 if (userId <= 0) { 16923 throw new IllegalArgumentException("Can't stop primary user " + userId); 16924 } 16925 synchronized (this) { 16926 return stopUserLocked(userId, callback); 16927 } 16928 } 16929 16930 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16931 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16932 if (mCurrentUserId == userId) { 16933 return ActivityManager.USER_OP_IS_CURRENT; 16934 } 16935 16936 final UserStartedState uss = mStartedUsers.get(userId); 16937 if (uss == null) { 16938 // User is not started, nothing to do... but we do need to 16939 // callback if requested. 16940 if (callback != null) { 16941 mHandler.post(new Runnable() { 16942 @Override 16943 public void run() { 16944 try { 16945 callback.userStopped(userId); 16946 } catch (RemoteException e) { 16947 } 16948 } 16949 }); 16950 } 16951 return ActivityManager.USER_OP_SUCCESS; 16952 } 16953 16954 if (callback != null) { 16955 uss.mStopCallbacks.add(callback); 16956 } 16957 16958 if (uss.mState != UserStartedState.STATE_STOPPING 16959 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16960 uss.mState = UserStartedState.STATE_STOPPING; 16961 updateStartedUserArrayLocked(); 16962 16963 long ident = Binder.clearCallingIdentity(); 16964 try { 16965 // We are going to broadcast ACTION_USER_STOPPING and then 16966 // once that is done send a final ACTION_SHUTDOWN and then 16967 // stop the user. 16968 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16969 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16970 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16971 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16972 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16973 // This is the result receiver for the final shutdown broadcast. 16974 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16975 @Override 16976 public void performReceive(Intent intent, int resultCode, String data, 16977 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16978 finishUserStop(uss); 16979 } 16980 }; 16981 // This is the result receiver for the initial stopping broadcast. 16982 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16983 @Override 16984 public void performReceive(Intent intent, int resultCode, String data, 16985 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16986 // On to the next. 16987 synchronized (ActivityManagerService.this) { 16988 if (uss.mState != UserStartedState.STATE_STOPPING) { 16989 // Whoops, we are being started back up. Abort, abort! 16990 return; 16991 } 16992 uss.mState = UserStartedState.STATE_SHUTDOWN; 16993 } 16994 mSystemServiceManager.stopUser(userId); 16995 broadcastIntentLocked(null, null, shutdownIntent, 16996 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16997 true, false, MY_PID, Process.SYSTEM_UID, userId); 16998 } 16999 }; 17000 // Kick things off. 17001 broadcastIntentLocked(null, null, stoppingIntent, 17002 null, stoppingReceiver, 0, null, null, 17003 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17004 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17005 } finally { 17006 Binder.restoreCallingIdentity(ident); 17007 } 17008 } 17009 17010 return ActivityManager.USER_OP_SUCCESS; 17011 } 17012 17013 void finishUserStop(UserStartedState uss) { 17014 final int userId = uss.mHandle.getIdentifier(); 17015 boolean stopped; 17016 ArrayList<IStopUserCallback> callbacks; 17017 synchronized (this) { 17018 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 17019 if (mStartedUsers.get(userId) != uss) { 17020 stopped = false; 17021 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 17022 stopped = false; 17023 } else { 17024 stopped = true; 17025 // User can no longer run. 17026 mStartedUsers.remove(userId); 17027 mUserLru.remove(Integer.valueOf(userId)); 17028 updateStartedUserArrayLocked(); 17029 17030 // Clean up all state and processes associated with the user. 17031 // Kill all the processes for the user. 17032 forceStopUserLocked(userId, "finish user"); 17033 } 17034 } 17035 17036 for (int i=0; i<callbacks.size(); i++) { 17037 try { 17038 if (stopped) callbacks.get(i).userStopped(userId); 17039 else callbacks.get(i).userStopAborted(userId); 17040 } catch (RemoteException e) { 17041 } 17042 } 17043 17044 if (stopped) { 17045 mSystemServiceManager.cleanupUser(userId); 17046 synchronized (this) { 17047 mStackSupervisor.removeUserLocked(userId); 17048 } 17049 } 17050 } 17051 17052 @Override 17053 public UserInfo getCurrentUser() { 17054 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17055 != PackageManager.PERMISSION_GRANTED) && ( 17056 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17057 != PackageManager.PERMISSION_GRANTED)) { 17058 String msg = "Permission Denial: getCurrentUser() from pid=" 17059 + Binder.getCallingPid() 17060 + ", uid=" + Binder.getCallingUid() 17061 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17062 Slog.w(TAG, msg); 17063 throw new SecurityException(msg); 17064 } 17065 synchronized (this) { 17066 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17067 } 17068 } 17069 17070 int getCurrentUserIdLocked() { 17071 return mCurrentUserId; 17072 } 17073 17074 @Override 17075 public boolean isUserRunning(int userId, boolean orStopped) { 17076 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17077 != PackageManager.PERMISSION_GRANTED) { 17078 String msg = "Permission Denial: isUserRunning() from pid=" 17079 + Binder.getCallingPid() 17080 + ", uid=" + Binder.getCallingUid() 17081 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17082 Slog.w(TAG, msg); 17083 throw new SecurityException(msg); 17084 } 17085 synchronized (this) { 17086 return isUserRunningLocked(userId, orStopped); 17087 } 17088 } 17089 17090 boolean isUserRunningLocked(int userId, boolean orStopped) { 17091 UserStartedState state = mStartedUsers.get(userId); 17092 if (state == null) { 17093 return false; 17094 } 17095 if (orStopped) { 17096 return true; 17097 } 17098 return state.mState != UserStartedState.STATE_STOPPING 17099 && state.mState != UserStartedState.STATE_SHUTDOWN; 17100 } 17101 17102 @Override 17103 public int[] getRunningUserIds() { 17104 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17105 != PackageManager.PERMISSION_GRANTED) { 17106 String msg = "Permission Denial: isUserRunning() from pid=" 17107 + Binder.getCallingPid() 17108 + ", uid=" + Binder.getCallingUid() 17109 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17110 Slog.w(TAG, msg); 17111 throw new SecurityException(msg); 17112 } 17113 synchronized (this) { 17114 return mStartedUserArray; 17115 } 17116 } 17117 17118 private void updateStartedUserArrayLocked() { 17119 int num = 0; 17120 for (int i=0; i<mStartedUsers.size(); i++) { 17121 UserStartedState uss = mStartedUsers.valueAt(i); 17122 // This list does not include stopping users. 17123 if (uss.mState != UserStartedState.STATE_STOPPING 17124 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17125 num++; 17126 } 17127 } 17128 mStartedUserArray = new int[num]; 17129 num = 0; 17130 for (int i=0; i<mStartedUsers.size(); i++) { 17131 UserStartedState uss = mStartedUsers.valueAt(i); 17132 if (uss.mState != UserStartedState.STATE_STOPPING 17133 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17134 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17135 num++; 17136 } 17137 } 17138 } 17139 17140 @Override 17141 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17142 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17143 != PackageManager.PERMISSION_GRANTED) { 17144 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17145 + Binder.getCallingPid() 17146 + ", uid=" + Binder.getCallingUid() 17147 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 17148 Slog.w(TAG, msg); 17149 throw new SecurityException(msg); 17150 } 17151 17152 mUserSwitchObservers.register(observer); 17153 } 17154 17155 @Override 17156 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17157 mUserSwitchObservers.unregister(observer); 17158 } 17159 17160 private boolean userExists(int userId) { 17161 if (userId == 0) { 17162 return true; 17163 } 17164 UserManagerService ums = getUserManagerLocked(); 17165 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17166 } 17167 17168 int[] getUsersLocked() { 17169 UserManagerService ums = getUserManagerLocked(); 17170 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17171 } 17172 17173 UserManagerService getUserManagerLocked() { 17174 if (mUserManager == null) { 17175 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17176 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17177 } 17178 return mUserManager; 17179 } 17180 17181 private int applyUserId(int uid, int userId) { 17182 return UserHandle.getUid(userId, uid); 17183 } 17184 17185 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17186 if (info == null) return null; 17187 ApplicationInfo newInfo = new ApplicationInfo(info); 17188 newInfo.uid = applyUserId(info.uid, userId); 17189 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17190 + info.packageName; 17191 return newInfo; 17192 } 17193 17194 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17195 if (aInfo == null 17196 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17197 return aInfo; 17198 } 17199 17200 ActivityInfo info = new ActivityInfo(aInfo); 17201 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17202 return info; 17203 } 17204 17205 private final class LocalService extends ActivityManagerInternal { 17206 @Override 17207 public void goingToSleep() { 17208 ActivityManagerService.this.goingToSleep(); 17209 } 17210 17211 @Override 17212 public void wakingUp() { 17213 ActivityManagerService.this.wakingUp(); 17214 } 17215 } 17216} 17217